fce426868beb46f060f1075d56773a297e1d5bfb
[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, 2011
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 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
64
65 ;; UNSPEC usage:
66
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
69 UNSPEC_GOT
70 UNSPEC_GOTOFF
71 UNSPEC_GOTPCREL
72 UNSPEC_GOTTPOFF
73 UNSPEC_TPOFF
74 UNSPEC_NTPOFF
75 UNSPEC_DTPOFF
76 UNSPEC_GOTNTPOFF
77 UNSPEC_INDNTPOFF
78 UNSPEC_PLTOFF
79 UNSPEC_MACHOPIC_OFFSET
80 UNSPEC_PCREL
81
82 ;; Prologue support
83 UNSPEC_STACK_ALLOC
84 UNSPEC_SET_GOT
85 UNSPEC_REG_SAVE
86 UNSPEC_DEF_CFA
87 UNSPEC_SET_RIP
88 UNSPEC_SET_GOT_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
90 UNSPEC_STACK_CHECK
91
92 ;; TLS support
93 UNSPEC_TP
94 UNSPEC_TLS_GD
95 UNSPEC_TLS_LD_BASE
96 UNSPEC_TLSDESC
97 UNSPEC_TLS_IE_SUN
98
99 ;; Other random patterns
100 UNSPEC_SCAS
101 UNSPEC_FNSTSW
102 UNSPEC_SAHF
103 UNSPEC_PARITY
104 UNSPEC_FSTCW
105 UNSPEC_ADD_CARRY
106 UNSPEC_FLDCW
107 UNSPEC_REP
108 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_TRUNC_NOOP
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_CALL_NEEDS_VZEROUPPER
112 UNSPEC_PAUSE
113
114 ;; For SSE/MMX support:
115 UNSPEC_FIX_NOTRUNC
116 UNSPEC_MASKMOV
117 UNSPEC_MOVMSK
118 UNSPEC_MOVNT
119 UNSPEC_MOVU
120 UNSPEC_RCP
121 UNSPEC_RSQRT
122 UNSPEC_SFENCE
123 UNSPEC_PFRCP
124 UNSPEC_PFRCPIT1
125 UNSPEC_PFRCPIT2
126 UNSPEC_PFRSQRT
127 UNSPEC_PFRSQIT1
128 UNSPEC_MFENCE
129 UNSPEC_LFENCE
130 UNSPEC_PSADBW
131 UNSPEC_LDDQU
132 UNSPEC_MS_TO_SYSV_CALL
133
134 ;; Generic math support
135 UNSPEC_COPYSIGN
136 UNSPEC_IEEE_MIN ; not commutative
137 UNSPEC_IEEE_MAX ; not commutative
138
139 ;; x87 Floating point
140 UNSPEC_SIN
141 UNSPEC_COS
142 UNSPEC_FPATAN
143 UNSPEC_FYL2X
144 UNSPEC_FYL2XP1
145 UNSPEC_FRNDINT
146 UNSPEC_FIST
147 UNSPEC_F2XM1
148 UNSPEC_TAN
149 UNSPEC_FXAM
150
151 ;; x87 Rounding
152 UNSPEC_FRNDINT_FLOOR
153 UNSPEC_FRNDINT_CEIL
154 UNSPEC_FRNDINT_TRUNC
155 UNSPEC_FRNDINT_MASK_PM
156 UNSPEC_FIST_FLOOR
157 UNSPEC_FIST_CEIL
158
159 ;; x87 Double output FP
160 UNSPEC_SINCOS_COS
161 UNSPEC_SINCOS_SIN
162 UNSPEC_XTRACT_FRACT
163 UNSPEC_XTRACT_EXP
164 UNSPEC_FSCALE_FRACT
165 UNSPEC_FSCALE_EXP
166 UNSPEC_FPREM_F
167 UNSPEC_FPREM_U
168 UNSPEC_FPREM1_F
169 UNSPEC_FPREM1_U
170
171 UNSPEC_C2_FLAG
172 UNSPEC_FXAM_MEM
173
174 ;; SSP patterns
175 UNSPEC_SP_SET
176 UNSPEC_SP_TEST
177 UNSPEC_SP_TLS_SET
178 UNSPEC_SP_TLS_TEST
179
180 ;; SSSE3
181 UNSPEC_PSHUFB
182 UNSPEC_PSIGN
183 UNSPEC_PALIGNR
184
185 ;; For SSE4A support
186 UNSPEC_EXTRQI
187 UNSPEC_EXTRQ
188 UNSPEC_INSERTQI
189 UNSPEC_INSERTQ
190
191 ;; For SSE4.1 support
192 UNSPEC_BLENDV
193 UNSPEC_INSERTPS
194 UNSPEC_DP
195 UNSPEC_MOVNTDQA
196 UNSPEC_MPSADBW
197 UNSPEC_PHMINPOSUW
198 UNSPEC_PTEST
199 UNSPEC_ROUND
200
201 ;; For SSE4.2 support
202 UNSPEC_CRC32
203 UNSPEC_PCMPESTR
204 UNSPEC_PCMPISTR
205
206 ;; For FMA4 support
207 UNSPEC_FMADDSUB
208 UNSPEC_XOP_UNSIGNED_CMP
209 UNSPEC_XOP_TRUEFALSE
210 UNSPEC_XOP_PERMUTE
211 UNSPEC_FRCZ
212
213 ;; For AES support
214 UNSPEC_AESENC
215 UNSPEC_AESENCLAST
216 UNSPEC_AESDEC
217 UNSPEC_AESDECLAST
218 UNSPEC_AESIMC
219 UNSPEC_AESKEYGENASSIST
220
221 ;; For PCLMUL support
222 UNSPEC_PCLMUL
223
224 ;; For AVX support
225 UNSPEC_PCMP
226 UNSPEC_VPERMIL
227 UNSPEC_VPERMIL2
228 UNSPEC_VPERMIL2F128
229 UNSPEC_CAST
230 UNSPEC_VTESTP
231 UNSPEC_VCVTPH2PS
232 UNSPEC_VCVTPS2PH
233
234 ;; For BMI support
235 UNSPEC_BEXTR
236
237 ;; For RDRAND support
238 UNSPEC_RDRAND
239 ])
240
241 (define_c_enum "unspecv" [
242 UNSPECV_BLOCKAGE
243 UNSPECV_STACK_PROBE
244 UNSPECV_PROBE_STACK_RANGE
245 UNSPECV_EMMS
246 UNSPECV_LDMXCSR
247 UNSPECV_STMXCSR
248 UNSPECV_FEMMS
249 UNSPECV_CLFLUSH
250 UNSPECV_ALIGN
251 UNSPECV_MONITOR
252 UNSPECV_MWAIT
253 UNSPECV_CMPXCHG
254 UNSPECV_XCHG
255 UNSPECV_LOCK
256 UNSPECV_PROLOGUE_USE
257 UNSPECV_CLD
258 UNSPECV_NOPS
259 UNSPECV_VZEROALL
260 UNSPECV_VZEROUPPER
261 UNSPECV_RDTSC
262 UNSPECV_RDTSCP
263 UNSPECV_RDPMC
264 UNSPECV_LLWP_INTRINSIC
265 UNSPECV_SLWP_INTRINSIC
266 UNSPECV_LWPVAL_INTRINSIC
267 UNSPECV_LWPINS_INTRINSIC
268 UNSPECV_RDFSBASE
269 UNSPECV_RDGSBASE
270 UNSPECV_WRFSBASE
271 UNSPECV_WRGSBASE
272 UNSPECV_SPLIT_STACK_RETURN
273 ])
274
275 ;; Constants to represent rounding modes in the ROUND instruction
276 (define_constants
277 [(ROUND_FLOOR 0x1)
278 (ROUND_CEIL 0x2)
279 (ROUND_TRUNC 0x3)
280 (ROUND_MXCSR 0x4)
281 (ROUND_NO_EXC 0x8)
282 ])
283
284 ;; Constants to represent pcomtrue/pcomfalse variants
285 (define_constants
286 [(PCOM_FALSE 0)
287 (PCOM_TRUE 1)
288 (COM_FALSE_S 2)
289 (COM_FALSE_P 3)
290 (COM_TRUE_S 4)
291 (COM_TRUE_P 5)
292 ])
293
294 ;; Constants used in the XOP pperm instruction
295 (define_constants
296 [(PPERM_SRC 0x00) /* copy source */
297 (PPERM_INVERT 0x20) /* invert source */
298 (PPERM_REVERSE 0x40) /* bit reverse source */
299 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
300 (PPERM_ZERO 0x80) /* all 0's */
301 (PPERM_ONES 0xa0) /* all 1's */
302 (PPERM_SIGN 0xc0) /* propagate sign bit */
303 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
304 (PPERM_SRC1 0x00) /* use first source byte */
305 (PPERM_SRC2 0x10) /* use second source byte */
306 ])
307
308 ;; Registers by name.
309 (define_constants
310 [(AX_REG 0)
311 (DX_REG 1)
312 (CX_REG 2)
313 (BX_REG 3)
314 (SI_REG 4)
315 (DI_REG 5)
316 (BP_REG 6)
317 (SP_REG 7)
318 (ST0_REG 8)
319 (ST1_REG 9)
320 (ST2_REG 10)
321 (ST3_REG 11)
322 (ST4_REG 12)
323 (ST5_REG 13)
324 (ST6_REG 14)
325 (ST7_REG 15)
326 (FLAGS_REG 17)
327 (FPSR_REG 18)
328 (FPCR_REG 19)
329 (XMM0_REG 21)
330 (XMM1_REG 22)
331 (XMM2_REG 23)
332 (XMM3_REG 24)
333 (XMM4_REG 25)
334 (XMM5_REG 26)
335 (XMM6_REG 27)
336 (XMM7_REG 28)
337 (MM0_REG 29)
338 (MM1_REG 30)
339 (MM2_REG 31)
340 (MM3_REG 32)
341 (MM4_REG 33)
342 (MM5_REG 34)
343 (MM6_REG 35)
344 (MM7_REG 36)
345 (R8_REG 37)
346 (R9_REG 38)
347 (R10_REG 39)
348 (R11_REG 40)
349 (R12_REG 41)
350 (R13_REG 42)
351 (XMM8_REG 45)
352 (XMM9_REG 46)
353 (XMM10_REG 47)
354 (XMM11_REG 48)
355 (XMM12_REG 49)
356 (XMM13_REG 50)
357 (XMM14_REG 51)
358 (XMM15_REG 52)
359 ])
360
361 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
362 ;; from i386.c.
363
364 ;; In C guard expressions, put expressions which may be compile-time
365 ;; constants first. This allows for better optimization. For
366 ;; example, write "TARGET_64BIT && reload_completed", not
367 ;; "reload_completed && TARGET_64BIT".
368
369 \f
370 ;; Processor type.
371 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
372 atom,generic64,amdfam10,bdver1,bdver2,btver1"
373 (const (symbol_ref "ix86_schedule")))
374
375 ;; A basic instruction type. Refinements due to arguments to be
376 ;; provided in other attributes.
377 (define_attr "type"
378 "other,multi,
379 alu,alu1,negnot,imov,imovx,lea,
380 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
381 icmp,test,ibr,setcc,icmov,
382 push,pop,call,callv,leave,
383 str,bitmanip,
384 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
385 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
386 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
387 ssemuladd,sse4arg,lwp,
388 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
389 (const_string "other"))
390
391 ;; Main data type used by the insn
392 (define_attr "mode"
393 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
394 (const_string "unknown"))
395
396 ;; The CPU unit operations uses.
397 (define_attr "unit" "integer,i387,sse,mmx,unknown"
398 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
399 (const_string "i387")
400 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
401 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
402 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
403 (const_string "sse")
404 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
405 (const_string "mmx")
406 (eq_attr "type" "other")
407 (const_string "unknown")]
408 (const_string "integer")))
409
410 ;; The (bounding maximum) length of an instruction immediate.
411 (define_attr "length_immediate" ""
412 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
413 bitmanip")
414 (const_int 0)
415 (eq_attr "unit" "i387,sse,mmx")
416 (const_int 0)
417 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
418 imul,icmp,push,pop")
419 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
420 (eq_attr "type" "imov,test")
421 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
422 (eq_attr "type" "call")
423 (if_then_else (match_operand 0 "constant_call_address_operand" "")
424 (const_int 4)
425 (const_int 0))
426 (eq_attr "type" "callv")
427 (if_then_else (match_operand 1 "constant_call_address_operand" "")
428 (const_int 4)
429 (const_int 0))
430 ;; We don't know the size before shorten_branches. Expect
431 ;; the instruction to fit for better scheduling.
432 (eq_attr "type" "ibr")
433 (const_int 1)
434 ]
435 (symbol_ref "/* Update immediate_length and other attributes! */
436 gcc_unreachable (),1")))
437
438 ;; The (bounding maximum) length of an instruction address.
439 (define_attr "length_address" ""
440 (cond [(eq_attr "type" "str,other,multi,fxch")
441 (const_int 0)
442 (and (eq_attr "type" "call")
443 (match_operand 0 "constant_call_address_operand" ""))
444 (const_int 0)
445 (and (eq_attr "type" "callv")
446 (match_operand 1 "constant_call_address_operand" ""))
447 (const_int 0)
448 ]
449 (symbol_ref "ix86_attr_length_address_default (insn)")))
450
451 ;; Set when length prefix is used.
452 (define_attr "prefix_data16" ""
453 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
454 (const_int 0)
455 (eq_attr "mode" "HI")
456 (const_int 1)
457 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
458 (const_int 1)
459 ]
460 (const_int 0)))
461
462 ;; Set when string REP prefix is used.
463 (define_attr "prefix_rep" ""
464 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
465 (const_int 0)
466 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
467 (const_int 1)
468 ]
469 (const_int 0)))
470
471 ;; Set when 0f opcode prefix is used.
472 (define_attr "prefix_0f" ""
473 (if_then_else
474 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
475 (eq_attr "unit" "sse,mmx"))
476 (const_int 1)
477 (const_int 0)))
478
479 ;; Set when REX opcode prefix is used.
480 (define_attr "prefix_rex" ""
481 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
482 (const_int 0)
483 (and (eq_attr "mode" "DI")
484 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
485 (eq_attr "unit" "!mmx")))
486 (const_int 1)
487 (and (eq_attr "mode" "QI")
488 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
489 (const_int 0)))
490 (const_int 1)
491 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
492 (const_int 0))
493 (const_int 1)
494 (and (eq_attr "type" "imovx")
495 (match_operand:QI 1 "ext_QIreg_operand" ""))
496 (const_int 1)
497 ]
498 (const_int 0)))
499
500 ;; There are also additional prefixes in 3DNOW, SSSE3.
501 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
502 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
503 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
504 (define_attr "prefix_extra" ""
505 (cond [(eq_attr "type" "ssemuladd,sse4arg")
506 (const_int 2)
507 (eq_attr "type" "sseiadd1,ssecvt1")
508 (const_int 1)
509 ]
510 (const_int 0)))
511
512 ;; Prefix used: original, VEX or maybe VEX.
513 (define_attr "prefix" "orig,vex,maybe_vex"
514 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
515 (const_string "vex")
516 (const_string "orig")))
517
518 ;; VEX W bit is used.
519 (define_attr "prefix_vex_w" "" (const_int 0))
520
521 ;; The length of VEX prefix
522 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
523 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
524 ;; still prefix_0f 1, with prefix_extra 1.
525 (define_attr "length_vex" ""
526 (if_then_else (and (eq_attr "prefix_0f" "1")
527 (eq_attr "prefix_extra" "0"))
528 (if_then_else (eq_attr "prefix_vex_w" "1")
529 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
530 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
531 (if_then_else (eq_attr "prefix_vex_w" "1")
532 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
533 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
534
535 ;; Set when modrm byte is used.
536 (define_attr "modrm" ""
537 (cond [(eq_attr "type" "str,leave")
538 (const_int 0)
539 (eq_attr "unit" "i387")
540 (const_int 0)
541 (and (eq_attr "type" "incdec")
542 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
543 (ior (match_operand:SI 1 "register_operand" "")
544 (match_operand:HI 1 "register_operand" ""))))
545 (const_int 0)
546 (and (eq_attr "type" "push")
547 (not (match_operand 1 "memory_operand" "")))
548 (const_int 0)
549 (and (eq_attr "type" "pop")
550 (not (match_operand 0 "memory_operand" "")))
551 (const_int 0)
552 (and (eq_attr "type" "imov")
553 (and (not (eq_attr "mode" "DI"))
554 (ior (and (match_operand 0 "register_operand" "")
555 (match_operand 1 "immediate_operand" ""))
556 (ior (and (match_operand 0 "ax_reg_operand" "")
557 (match_operand 1 "memory_displacement_only_operand" ""))
558 (and (match_operand 0 "memory_displacement_only_operand" "")
559 (match_operand 1 "ax_reg_operand" ""))))))
560 (const_int 0)
561 (and (eq_attr "type" "call")
562 (match_operand 0 "constant_call_address_operand" ""))
563 (const_int 0)
564 (and (eq_attr "type" "callv")
565 (match_operand 1 "constant_call_address_operand" ""))
566 (const_int 0)
567 (and (eq_attr "type" "alu,alu1,icmp,test")
568 (match_operand 0 "ax_reg_operand" ""))
569 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
570 ]
571 (const_int 1)))
572
573 ;; The (bounding maximum) length of an instruction in bytes.
574 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
575 ;; Later we may want to split them and compute proper length as for
576 ;; other insns.
577 (define_attr "length" ""
578 (cond [(eq_attr "type" "other,multi,fistp,frndint")
579 (const_int 16)
580 (eq_attr "type" "fcmp")
581 (const_int 4)
582 (eq_attr "unit" "i387")
583 (plus (const_int 2)
584 (plus (attr "prefix_data16")
585 (attr "length_address")))
586 (ior (eq_attr "prefix" "vex")
587 (and (eq_attr "prefix" "maybe_vex")
588 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
589 (plus (attr "length_vex")
590 (plus (attr "length_immediate")
591 (plus (attr "modrm")
592 (attr "length_address"))))]
593 (plus (plus (attr "modrm")
594 (plus (attr "prefix_0f")
595 (plus (attr "prefix_rex")
596 (plus (attr "prefix_extra")
597 (const_int 1)))))
598 (plus (attr "prefix_rep")
599 (plus (attr "prefix_data16")
600 (plus (attr "length_immediate")
601 (attr "length_address")))))))
602
603 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
604 ;; `store' if there is a simple memory reference therein, or `unknown'
605 ;; if the instruction is complex.
606
607 (define_attr "memory" "none,load,store,both,unknown"
608 (cond [(eq_attr "type" "other,multi,str,lwp")
609 (const_string "unknown")
610 (eq_attr "type" "lea,fcmov,fpspc")
611 (const_string "none")
612 (eq_attr "type" "fistp,leave")
613 (const_string "both")
614 (eq_attr "type" "frndint")
615 (const_string "load")
616 (eq_attr "type" "push")
617 (if_then_else (match_operand 1 "memory_operand" "")
618 (const_string "both")
619 (const_string "store"))
620 (eq_attr "type" "pop")
621 (if_then_else (match_operand 0 "memory_operand" "")
622 (const_string "both")
623 (const_string "load"))
624 (eq_attr "type" "setcc")
625 (if_then_else (match_operand 0 "memory_operand" "")
626 (const_string "store")
627 (const_string "none"))
628 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
629 (if_then_else (ior (match_operand 0 "memory_operand" "")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "load")
632 (const_string "none"))
633 (eq_attr "type" "ibr")
634 (if_then_else (match_operand 0 "memory_operand" "")
635 (const_string "load")
636 (const_string "none"))
637 (eq_attr "type" "call")
638 (if_then_else (match_operand 0 "constant_call_address_operand" "")
639 (const_string "none")
640 (const_string "load"))
641 (eq_attr "type" "callv")
642 (if_then_else (match_operand 1 "constant_call_address_operand" "")
643 (const_string "none")
644 (const_string "load"))
645 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
646 (match_operand 1 "memory_operand" ""))
647 (const_string "both")
648 (and (match_operand 0 "memory_operand" "")
649 (match_operand 1 "memory_operand" ""))
650 (const_string "both")
651 (match_operand 0 "memory_operand" "")
652 (const_string "store")
653 (match_operand 1 "memory_operand" "")
654 (const_string "load")
655 (and (eq_attr "type"
656 "!alu1,negnot,ishift1,
657 imov,imovx,icmp,test,bitmanip,
658 fmov,fcmp,fsgn,
659 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
660 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
661 (match_operand 2 "memory_operand" ""))
662 (const_string "load")
663 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
664 (match_operand 3 "memory_operand" ""))
665 (const_string "load")
666 ]
667 (const_string "none")))
668
669 ;; Indicates if an instruction has both an immediate and a displacement.
670
671 (define_attr "imm_disp" "false,true,unknown"
672 (cond [(eq_attr "type" "other,multi")
673 (const_string "unknown")
674 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
675 (and (match_operand 0 "memory_displacement_operand" "")
676 (match_operand 1 "immediate_operand" "")))
677 (const_string "true")
678 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
679 (and (match_operand 0 "memory_displacement_operand" "")
680 (match_operand 2 "immediate_operand" "")))
681 (const_string "true")
682 ]
683 (const_string "false")))
684
685 ;; Indicates if an FP operation has an integer source.
686
687 (define_attr "fp_int_src" "false,true"
688 (const_string "false"))
689
690 ;; Defines rounding mode of an FP operation.
691
692 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
693 (const_string "any"))
694
695 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
696 (define_attr "use_carry" "0,1" (const_string "0"))
697
698 ;; Define attribute to indicate unaligned ssemov insns
699 (define_attr "movu" "0,1" (const_string "0"))
700
701 ;; Used to control the "enabled" attribute on a per-instruction basis.
702 (define_attr "isa" "base,noavx,avx"
703 (const_string "base"))
704
705 (define_attr "enabled" ""
706 (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
707 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
708 ]
709 (const_int 1)))
710
711 ;; Describe a user's asm statement.
712 (define_asm_attributes
713 [(set_attr "length" "128")
714 (set_attr "type" "multi")])
715
716 (define_code_iterator plusminus [plus minus])
717
718 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
719
720 ;; Base name for define_insn
721 (define_code_attr plusminus_insn
722 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
723 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
724
725 ;; Base name for insn mnemonic.
726 (define_code_attr plusminus_mnemonic
727 [(plus "add") (ss_plus "adds") (us_plus "addus")
728 (minus "sub") (ss_minus "subs") (us_minus "subus")])
729 (define_code_attr plusminus_carry_mnemonic
730 [(plus "adc") (minus "sbb")])
731
732 ;; Mark commutative operators as such in constraints.
733 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
734 (minus "") (ss_minus "") (us_minus "")])
735
736 ;; Mapping of signed max and min
737 (define_code_iterator smaxmin [smax smin])
738
739 ;; Mapping of unsigned max and min
740 (define_code_iterator umaxmin [umax umin])
741
742 ;; Base name for integer and FP insn mnemonic
743 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
744 (umax "maxu") (umin "minu")])
745 (define_code_attr maxmin_float [(smax "max") (smin "min")])
746
747 ;; Mapping of logic operators
748 (define_code_iterator any_logic [and ior xor])
749 (define_code_iterator any_or [ior xor])
750
751 ;; Base name for insn mnemonic.
752 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
753
754 ;; Mapping of shift-right operators
755 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
756
757 ;; Base name for define_insn
758 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
759
760 ;; Base name for insn mnemonic.
761 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
762
763 ;; Mapping of rotate operators
764 (define_code_iterator any_rotate [rotate rotatert])
765
766 ;; Base name for define_insn
767 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
768
769 ;; Base name for insn mnemonic.
770 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
771
772 ;; Mapping of abs neg operators
773 (define_code_iterator absneg [abs neg])
774
775 ;; Base name for x87 insn mnemonic.
776 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
777
778 ;; Used in signed and unsigned widening multiplications.
779 (define_code_iterator any_extend [sign_extend zero_extend])
780
781 ;; Various insn prefixes for signed and unsigned operations.
782 (define_code_attr u [(sign_extend "") (zero_extend "u")
783 (div "") (udiv "u")])
784 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
785
786 ;; Used in signed and unsigned divisions.
787 (define_code_iterator any_div [div udiv])
788
789 ;; Instruction prefix for signed and unsigned operations.
790 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
791 (div "i") (udiv "")])
792
793 ;; All integer modes.
794 (define_mode_iterator SWI1248x [QI HI SI DI])
795
796 ;; All integer modes without QImode.
797 (define_mode_iterator SWI248x [HI SI DI])
798
799 ;; All integer modes without QImode and HImode.
800 (define_mode_iterator SWI48x [SI DI])
801
802 ;; All integer modes without SImode and DImode.
803 (define_mode_iterator SWI12 [QI HI])
804
805 ;; All integer modes without DImode.
806 (define_mode_iterator SWI124 [QI HI SI])
807
808 ;; All integer modes without QImode and DImode.
809 (define_mode_iterator SWI24 [HI SI])
810
811 ;; Single word integer modes.
812 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
813
814 ;; Single word integer modes without QImode.
815 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
816
817 ;; Single word integer modes without QImode and HImode.
818 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
819
820 ;; All math-dependant single and double word integer modes.
821 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
822 (HI "TARGET_HIMODE_MATH")
823 SI DI (TI "TARGET_64BIT")])
824
825 ;; Math-dependant single word integer modes.
826 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
827 (HI "TARGET_HIMODE_MATH")
828 SI (DI "TARGET_64BIT")])
829
830 ;; Math-dependant integer modes without DImode.
831 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
832 (HI "TARGET_HIMODE_MATH")
833 SI])
834
835 ;; Math-dependant single word integer modes without QImode.
836 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
837 SI (DI "TARGET_64BIT")])
838
839 ;; Double word integer modes.
840 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
841 (TI "TARGET_64BIT")])
842
843 ;; Double word integer modes as mode attribute.
844 (define_mode_attr DWI [(SI "DI") (DI "TI")])
845 (define_mode_attr dwi [(SI "di") (DI "ti")])
846
847 ;; Half mode for double word integer modes.
848 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
849 (DI "TARGET_64BIT")])
850
851 ;; Instruction suffix for integer modes.
852 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
853
854 ;; Pointer size prefix for integer modes (Intel asm dialect)
855 (define_mode_attr iptrsize [(QI "BYTE")
856 (HI "WORD")
857 (SI "DWORD")
858 (DI "QWORD")])
859
860 ;; Register class for integer modes.
861 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
862
863 ;; Immediate operand constraint for integer modes.
864 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
865
866 ;; General operand constraint for word modes.
867 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
868
869 ;; Immediate operand constraint for double integer modes.
870 (define_mode_attr di [(SI "nF") (DI "e")])
871
872 ;; Immediate operand constraint for shifts.
873 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
874
875 ;; General operand predicate for integer modes.
876 (define_mode_attr general_operand
877 [(QI "general_operand")
878 (HI "general_operand")
879 (SI "x86_64_general_operand")
880 (DI "x86_64_general_operand")
881 (TI "x86_64_general_operand")])
882
883 ;; General sign/zero extend operand predicate for integer modes.
884 (define_mode_attr general_szext_operand
885 [(QI "general_operand")
886 (HI "general_operand")
887 (SI "x86_64_szext_general_operand")
888 (DI "x86_64_szext_general_operand")])
889
890 ;; Immediate operand predicate for integer modes.
891 (define_mode_attr immediate_operand
892 [(QI "immediate_operand")
893 (HI "immediate_operand")
894 (SI "x86_64_immediate_operand")
895 (DI "x86_64_immediate_operand")])
896
897 ;; Nonmemory operand predicate for integer modes.
898 (define_mode_attr nonmemory_operand
899 [(QI "nonmemory_operand")
900 (HI "nonmemory_operand")
901 (SI "x86_64_nonmemory_operand")
902 (DI "x86_64_nonmemory_operand")])
903
904 ;; Operand predicate for shifts.
905 (define_mode_attr shift_operand
906 [(QI "nonimmediate_operand")
907 (HI "nonimmediate_operand")
908 (SI "nonimmediate_operand")
909 (DI "shiftdi_operand")
910 (TI "register_operand")])
911
912 ;; Operand predicate for shift argument.
913 (define_mode_attr shift_immediate_operand
914 [(QI "const_1_to_31_operand")
915 (HI "const_1_to_31_operand")
916 (SI "const_1_to_31_operand")
917 (DI "const_1_to_63_operand")])
918
919 ;; Input operand predicate for arithmetic left shifts.
920 (define_mode_attr ashl_input_operand
921 [(QI "nonimmediate_operand")
922 (HI "nonimmediate_operand")
923 (SI "nonimmediate_operand")
924 (DI "ashldi_input_operand")
925 (TI "reg_or_pm1_operand")])
926
927 ;; SSE and x87 SFmode and DFmode floating point modes
928 (define_mode_iterator MODEF [SF DF])
929
930 ;; All x87 floating point modes
931 (define_mode_iterator X87MODEF [SF DF XF])
932
933 ;; SSE instruction suffix for various modes
934 (define_mode_attr ssemodesuffix
935 [(SF "ss") (DF "sd")
936 (V8SF "ps") (V4DF "pd")
937 (V4SF "ps") (V2DF "pd")
938 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
939 (V8SI "si")])
940
941 ;; SSE vector suffix for floating point modes
942 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
943
944 ;; SSE vector mode corresponding to a scalar mode
945 (define_mode_attr ssevecmode
946 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
947
948 ;; Instruction suffix for REX 64bit operators.
949 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
950
951 ;; This mode iterator allows :P to be used for patterns that operate on
952 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
953 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
954 \f
955 ;; Scheduling descriptions
956
957 (include "pentium.md")
958 (include "ppro.md")
959 (include "k6.md")
960 (include "athlon.md")
961 (include "bdver1.md")
962 (include "geode.md")
963 (include "atom.md")
964 (include "core2.md")
965
966 \f
967 ;; Operand and operator predicates and constraints
968
969 (include "predicates.md")
970 (include "constraints.md")
971
972 \f
973 ;; Compare and branch/compare and store instructions.
974
975 (define_expand "cbranch<mode>4"
976 [(set (reg:CC FLAGS_REG)
977 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
978 (match_operand:SDWIM 2 "<general_operand>" "")))
979 (set (pc) (if_then_else
980 (match_operator 0 "ordered_comparison_operator"
981 [(reg:CC FLAGS_REG) (const_int 0)])
982 (label_ref (match_operand 3 "" ""))
983 (pc)))]
984 ""
985 {
986 if (MEM_P (operands[1]) && MEM_P (operands[2]))
987 operands[1] = force_reg (<MODE>mode, operands[1]);
988 ix86_expand_branch (GET_CODE (operands[0]),
989 operands[1], operands[2], operands[3]);
990 DONE;
991 })
992
993 (define_expand "cstore<mode>4"
994 [(set (reg:CC FLAGS_REG)
995 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
996 (match_operand:SWIM 3 "<general_operand>" "")))
997 (set (match_operand:QI 0 "register_operand" "")
998 (match_operator 1 "ordered_comparison_operator"
999 [(reg:CC FLAGS_REG) (const_int 0)]))]
1000 ""
1001 {
1002 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1003 operands[2] = force_reg (<MODE>mode, operands[2]);
1004 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1005 operands[2], operands[3]);
1006 DONE;
1007 })
1008
1009 (define_expand "cmp<mode>_1"
1010 [(set (reg:CC FLAGS_REG)
1011 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1012 (match_operand:SWI48 1 "<general_operand>" "")))])
1013
1014 (define_insn "*cmp<mode>_ccno_1"
1015 [(set (reg FLAGS_REG)
1016 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1017 (match_operand:SWI 1 "const0_operand" "")))]
1018 "ix86_match_ccmode (insn, CCNOmode)"
1019 "@
1020 test{<imodesuffix>}\t%0, %0
1021 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1022 [(set_attr "type" "test,icmp")
1023 (set_attr "length_immediate" "0,1")
1024 (set_attr "mode" "<MODE>")])
1025
1026 (define_insn "*cmp<mode>_1"
1027 [(set (reg FLAGS_REG)
1028 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1029 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1030 "ix86_match_ccmode (insn, CCmode)"
1031 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1032 [(set_attr "type" "icmp")
1033 (set_attr "mode" "<MODE>")])
1034
1035 (define_insn "*cmp<mode>_minus_1"
1036 [(set (reg FLAGS_REG)
1037 (compare
1038 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1039 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1040 (const_int 0)))]
1041 "ix86_match_ccmode (insn, CCGOCmode)"
1042 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1043 [(set_attr "type" "icmp")
1044 (set_attr "mode" "<MODE>")])
1045
1046 (define_insn "*cmpqi_ext_1"
1047 [(set (reg FLAGS_REG)
1048 (compare
1049 (match_operand:QI 0 "general_operand" "Qm")
1050 (subreg:QI
1051 (zero_extract:SI
1052 (match_operand 1 "ext_register_operand" "Q")
1053 (const_int 8)
1054 (const_int 8)) 0)))]
1055 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1056 "cmp{b}\t{%h1, %0|%0, %h1}"
1057 [(set_attr "type" "icmp")
1058 (set_attr "mode" "QI")])
1059
1060 (define_insn "*cmpqi_ext_1_rex64"
1061 [(set (reg FLAGS_REG)
1062 (compare
1063 (match_operand:QI 0 "register_operand" "Q")
1064 (subreg:QI
1065 (zero_extract:SI
1066 (match_operand 1 "ext_register_operand" "Q")
1067 (const_int 8)
1068 (const_int 8)) 0)))]
1069 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1070 "cmp{b}\t{%h1, %0|%0, %h1}"
1071 [(set_attr "type" "icmp")
1072 (set_attr "mode" "QI")])
1073
1074 (define_insn "*cmpqi_ext_2"
1075 [(set (reg FLAGS_REG)
1076 (compare
1077 (subreg:QI
1078 (zero_extract:SI
1079 (match_operand 0 "ext_register_operand" "Q")
1080 (const_int 8)
1081 (const_int 8)) 0)
1082 (match_operand:QI 1 "const0_operand" "")))]
1083 "ix86_match_ccmode (insn, CCNOmode)"
1084 "test{b}\t%h0, %h0"
1085 [(set_attr "type" "test")
1086 (set_attr "length_immediate" "0")
1087 (set_attr "mode" "QI")])
1088
1089 (define_expand "cmpqi_ext_3"
1090 [(set (reg:CC FLAGS_REG)
1091 (compare:CC
1092 (subreg:QI
1093 (zero_extract:SI
1094 (match_operand 0 "ext_register_operand" "")
1095 (const_int 8)
1096 (const_int 8)) 0)
1097 (match_operand:QI 1 "immediate_operand" "")))])
1098
1099 (define_insn "*cmpqi_ext_3_insn"
1100 [(set (reg FLAGS_REG)
1101 (compare
1102 (subreg:QI
1103 (zero_extract:SI
1104 (match_operand 0 "ext_register_operand" "Q")
1105 (const_int 8)
1106 (const_int 8)) 0)
1107 (match_operand:QI 1 "general_operand" "Qmn")))]
1108 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1109 "cmp{b}\t{%1, %h0|%h0, %1}"
1110 [(set_attr "type" "icmp")
1111 (set_attr "modrm" "1")
1112 (set_attr "mode" "QI")])
1113
1114 (define_insn "*cmpqi_ext_3_insn_rex64"
1115 [(set (reg FLAGS_REG)
1116 (compare
1117 (subreg:QI
1118 (zero_extract:SI
1119 (match_operand 0 "ext_register_operand" "Q")
1120 (const_int 8)
1121 (const_int 8)) 0)
1122 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1123 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1124 "cmp{b}\t{%1, %h0|%h0, %1}"
1125 [(set_attr "type" "icmp")
1126 (set_attr "modrm" "1")
1127 (set_attr "mode" "QI")])
1128
1129 (define_insn "*cmpqi_ext_4"
1130 [(set (reg FLAGS_REG)
1131 (compare
1132 (subreg:QI
1133 (zero_extract:SI
1134 (match_operand 0 "ext_register_operand" "Q")
1135 (const_int 8)
1136 (const_int 8)) 0)
1137 (subreg:QI
1138 (zero_extract:SI
1139 (match_operand 1 "ext_register_operand" "Q")
1140 (const_int 8)
1141 (const_int 8)) 0)))]
1142 "ix86_match_ccmode (insn, CCmode)"
1143 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1144 [(set_attr "type" "icmp")
1145 (set_attr "mode" "QI")])
1146
1147 ;; These implement float point compares.
1148 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1149 ;; which would allow mix and match FP modes on the compares. Which is what
1150 ;; the old patterns did, but with many more of them.
1151
1152 (define_expand "cbranchxf4"
1153 [(set (reg:CC FLAGS_REG)
1154 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1155 (match_operand:XF 2 "nonmemory_operand" "")))
1156 (set (pc) (if_then_else
1157 (match_operator 0 "ix86_fp_comparison_operator"
1158 [(reg:CC FLAGS_REG)
1159 (const_int 0)])
1160 (label_ref (match_operand 3 "" ""))
1161 (pc)))]
1162 "TARGET_80387"
1163 {
1164 ix86_expand_branch (GET_CODE (operands[0]),
1165 operands[1], operands[2], operands[3]);
1166 DONE;
1167 })
1168
1169 (define_expand "cstorexf4"
1170 [(set (reg:CC FLAGS_REG)
1171 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1172 (match_operand:XF 3 "nonmemory_operand" "")))
1173 (set (match_operand:QI 0 "register_operand" "")
1174 (match_operator 1 "ix86_fp_comparison_operator"
1175 [(reg:CC FLAGS_REG)
1176 (const_int 0)]))]
1177 "TARGET_80387"
1178 {
1179 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1180 operands[2], operands[3]);
1181 DONE;
1182 })
1183
1184 (define_expand "cbranch<mode>4"
1185 [(set (reg:CC FLAGS_REG)
1186 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1187 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1188 (set (pc) (if_then_else
1189 (match_operator 0 "ix86_fp_comparison_operator"
1190 [(reg:CC FLAGS_REG)
1191 (const_int 0)])
1192 (label_ref (match_operand 3 "" ""))
1193 (pc)))]
1194 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1195 {
1196 ix86_expand_branch (GET_CODE (operands[0]),
1197 operands[1], operands[2], operands[3]);
1198 DONE;
1199 })
1200
1201 (define_expand "cstore<mode>4"
1202 [(set (reg:CC FLAGS_REG)
1203 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1204 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1205 (set (match_operand:QI 0 "register_operand" "")
1206 (match_operator 1 "ix86_fp_comparison_operator"
1207 [(reg:CC FLAGS_REG)
1208 (const_int 0)]))]
1209 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1210 {
1211 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1212 operands[2], operands[3]);
1213 DONE;
1214 })
1215
1216 (define_expand "cbranchcc4"
1217 [(set (pc) (if_then_else
1218 (match_operator 0 "comparison_operator"
1219 [(match_operand 1 "flags_reg_operand" "")
1220 (match_operand 2 "const0_operand" "")])
1221 (label_ref (match_operand 3 "" ""))
1222 (pc)))]
1223 ""
1224 {
1225 ix86_expand_branch (GET_CODE (operands[0]),
1226 operands[1], operands[2], operands[3]);
1227 DONE;
1228 })
1229
1230 (define_expand "cstorecc4"
1231 [(set (match_operand:QI 0 "register_operand" "")
1232 (match_operator 1 "comparison_operator"
1233 [(match_operand 2 "flags_reg_operand" "")
1234 (match_operand 3 "const0_operand" "")]))]
1235 ""
1236 {
1237 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1238 operands[2], operands[3]);
1239 DONE;
1240 })
1241
1242
1243 ;; FP compares, step 1:
1244 ;; Set the FP condition codes.
1245 ;;
1246 ;; CCFPmode compare with exceptions
1247 ;; CCFPUmode compare with no exceptions
1248
1249 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1250 ;; used to manage the reg stack popping would not be preserved.
1251
1252 (define_insn "*cmpfp_0"
1253 [(set (match_operand:HI 0 "register_operand" "=a")
1254 (unspec:HI
1255 [(compare:CCFP
1256 (match_operand 1 "register_operand" "f")
1257 (match_operand 2 "const0_operand" ""))]
1258 UNSPEC_FNSTSW))]
1259 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1260 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1261 "* return output_fp_compare (insn, operands, false, false);"
1262 [(set_attr "type" "multi")
1263 (set_attr "unit" "i387")
1264 (set (attr "mode")
1265 (cond [(match_operand:SF 1 "" "")
1266 (const_string "SF")
1267 (match_operand:DF 1 "" "")
1268 (const_string "DF")
1269 ]
1270 (const_string "XF")))])
1271
1272 (define_insn_and_split "*cmpfp_0_cc"
1273 [(set (reg:CCFP FLAGS_REG)
1274 (compare:CCFP
1275 (match_operand 1 "register_operand" "f")
1276 (match_operand 2 "const0_operand" "")))
1277 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1278 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1279 && TARGET_SAHF && !TARGET_CMOVE
1280 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1281 "#"
1282 "&& reload_completed"
1283 [(set (match_dup 0)
1284 (unspec:HI
1285 [(compare:CCFP (match_dup 1)(match_dup 2))]
1286 UNSPEC_FNSTSW))
1287 (set (reg:CC FLAGS_REG)
1288 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1289 ""
1290 [(set_attr "type" "multi")
1291 (set_attr "unit" "i387")
1292 (set (attr "mode")
1293 (cond [(match_operand:SF 1 "" "")
1294 (const_string "SF")
1295 (match_operand:DF 1 "" "")
1296 (const_string "DF")
1297 ]
1298 (const_string "XF")))])
1299
1300 (define_insn "*cmpfp_xf"
1301 [(set (match_operand:HI 0 "register_operand" "=a")
1302 (unspec:HI
1303 [(compare:CCFP
1304 (match_operand:XF 1 "register_operand" "f")
1305 (match_operand:XF 2 "register_operand" "f"))]
1306 UNSPEC_FNSTSW))]
1307 "TARGET_80387"
1308 "* return output_fp_compare (insn, operands, false, false);"
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "XF")])
1312
1313 (define_insn_and_split "*cmpfp_xf_cc"
1314 [(set (reg:CCFP FLAGS_REG)
1315 (compare:CCFP
1316 (match_operand:XF 1 "register_operand" "f")
1317 (match_operand:XF 2 "register_operand" "f")))
1318 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1319 "TARGET_80387
1320 && TARGET_SAHF && !TARGET_CMOVE"
1321 "#"
1322 "&& reload_completed"
1323 [(set (match_dup 0)
1324 (unspec:HI
1325 [(compare:CCFP (match_dup 1)(match_dup 2))]
1326 UNSPEC_FNSTSW))
1327 (set (reg:CC FLAGS_REG)
1328 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1329 ""
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1332 (set_attr "mode" "XF")])
1333
1334 (define_insn "*cmpfp_<mode>"
1335 [(set (match_operand:HI 0 "register_operand" "=a")
1336 (unspec:HI
1337 [(compare:CCFP
1338 (match_operand:MODEF 1 "register_operand" "f")
1339 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1340 UNSPEC_FNSTSW))]
1341 "TARGET_80387"
1342 "* return output_fp_compare (insn, operands, false, false);"
1343 [(set_attr "type" "multi")
1344 (set_attr "unit" "i387")
1345 (set_attr "mode" "<MODE>")])
1346
1347 (define_insn_and_split "*cmpfp_<mode>_cc"
1348 [(set (reg:CCFP FLAGS_REG)
1349 (compare:CCFP
1350 (match_operand:MODEF 1 "register_operand" "f")
1351 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1352 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1353 "TARGET_80387
1354 && TARGET_SAHF && !TARGET_CMOVE"
1355 "#"
1356 "&& reload_completed"
1357 [(set (match_dup 0)
1358 (unspec:HI
1359 [(compare:CCFP (match_dup 1)(match_dup 2))]
1360 UNSPEC_FNSTSW))
1361 (set (reg:CC FLAGS_REG)
1362 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1363 ""
1364 [(set_attr "type" "multi")
1365 (set_attr "unit" "i387")
1366 (set_attr "mode" "<MODE>")])
1367
1368 (define_insn "*cmpfp_u"
1369 [(set (match_operand:HI 0 "register_operand" "=a")
1370 (unspec:HI
1371 [(compare:CCFPU
1372 (match_operand 1 "register_operand" "f")
1373 (match_operand 2 "register_operand" "f"))]
1374 UNSPEC_FNSTSW))]
1375 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1376 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1377 "* return output_fp_compare (insn, operands, false, true);"
1378 [(set_attr "type" "multi")
1379 (set_attr "unit" "i387")
1380 (set (attr "mode")
1381 (cond [(match_operand:SF 1 "" "")
1382 (const_string "SF")
1383 (match_operand:DF 1 "" "")
1384 (const_string "DF")
1385 ]
1386 (const_string "XF")))])
1387
1388 (define_insn_and_split "*cmpfp_u_cc"
1389 [(set (reg:CCFPU FLAGS_REG)
1390 (compare:CCFPU
1391 (match_operand 1 "register_operand" "f")
1392 (match_operand 2 "register_operand" "f")))
1393 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395 && TARGET_SAHF && !TARGET_CMOVE
1396 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1397 "#"
1398 "&& reload_completed"
1399 [(set (match_dup 0)
1400 (unspec:HI
1401 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1402 UNSPEC_FNSTSW))
1403 (set (reg:CC FLAGS_REG)
1404 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1405 ""
1406 [(set_attr "type" "multi")
1407 (set_attr "unit" "i387")
1408 (set (attr "mode")
1409 (cond [(match_operand:SF 1 "" "")
1410 (const_string "SF")
1411 (match_operand:DF 1 "" "")
1412 (const_string "DF")
1413 ]
1414 (const_string "XF")))])
1415
1416 (define_insn "*cmpfp_<mode>"
1417 [(set (match_operand:HI 0 "register_operand" "=a")
1418 (unspec:HI
1419 [(compare:CCFP
1420 (match_operand 1 "register_operand" "f")
1421 (match_operator 3 "float_operator"
1422 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1423 UNSPEC_FNSTSW))]
1424 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1425 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1426 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1427 "* return output_fp_compare (insn, operands, false, false);"
1428 [(set_attr "type" "multi")
1429 (set_attr "unit" "i387")
1430 (set_attr "fp_int_src" "true")
1431 (set_attr "mode" "<MODE>")])
1432
1433 (define_insn_and_split "*cmpfp_<mode>_cc"
1434 [(set (reg:CCFP FLAGS_REG)
1435 (compare:CCFP
1436 (match_operand 1 "register_operand" "f")
1437 (match_operator 3 "float_operator"
1438 [(match_operand:SWI24 2 "memory_operand" "m")])))
1439 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1440 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1441 && TARGET_SAHF && !TARGET_CMOVE
1442 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1443 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1444 "#"
1445 "&& reload_completed"
1446 [(set (match_dup 0)
1447 (unspec:HI
1448 [(compare:CCFP
1449 (match_dup 1)
1450 (match_op_dup 3 [(match_dup 2)]))]
1451 UNSPEC_FNSTSW))
1452 (set (reg:CC FLAGS_REG)
1453 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1454 ""
1455 [(set_attr "type" "multi")
1456 (set_attr "unit" "i387")
1457 (set_attr "fp_int_src" "true")
1458 (set_attr "mode" "<MODE>")])
1459
1460 ;; FP compares, step 2
1461 ;; Move the fpsw to ax.
1462
1463 (define_insn "x86_fnstsw_1"
1464 [(set (match_operand:HI 0 "register_operand" "=a")
1465 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1466 "TARGET_80387"
1467 "fnstsw\t%0"
1468 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1469 (set_attr "mode" "SI")
1470 (set_attr "unit" "i387")])
1471
1472 ;; FP compares, step 3
1473 ;; Get ax into flags, general case.
1474
1475 (define_insn "x86_sahf_1"
1476 [(set (reg:CC FLAGS_REG)
1477 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1478 UNSPEC_SAHF))]
1479 "TARGET_SAHF"
1480 {
1481 #ifndef HAVE_AS_IX86_SAHF
1482 if (TARGET_64BIT)
1483 return ASM_BYTE "0x9e";
1484 else
1485 #endif
1486 return "sahf";
1487 }
1488 [(set_attr "length" "1")
1489 (set_attr "athlon_decode" "vector")
1490 (set_attr "amdfam10_decode" "direct")
1491 (set_attr "bdver1_decode" "direct")
1492 (set_attr "mode" "SI")])
1493
1494 ;; Pentium Pro can do steps 1 through 3 in one go.
1495 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1496 (define_insn "*cmpfp_i_mixed"
1497 [(set (reg:CCFP FLAGS_REG)
1498 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1499 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1500 "TARGET_MIX_SSE_I387
1501 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, true, false);"
1504 [(set_attr "type" "fcmp,ssecomi")
1505 (set_attr "prefix" "orig,maybe_vex")
1506 (set (attr "mode")
1507 (if_then_else (match_operand:SF 1 "" "")
1508 (const_string "SF")
1509 (const_string "DF")))
1510 (set (attr "prefix_rep")
1511 (if_then_else (eq_attr "type" "ssecomi")
1512 (const_string "0")
1513 (const_string "*")))
1514 (set (attr "prefix_data16")
1515 (cond [(eq_attr "type" "fcmp")
1516 (const_string "*")
1517 (eq_attr "mode" "DF")
1518 (const_string "1")
1519 ]
1520 (const_string "0")))
1521 (set_attr "athlon_decode" "vector")
1522 (set_attr "amdfam10_decode" "direct")
1523 (set_attr "bdver1_decode" "double")])
1524
1525 (define_insn "*cmpfp_i_sse"
1526 [(set (reg:CCFP FLAGS_REG)
1527 (compare:CCFP (match_operand 0 "register_operand" "x")
1528 (match_operand 1 "nonimmediate_operand" "xm")))]
1529 "TARGET_SSE_MATH
1530 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1531 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1532 "* return output_fp_compare (insn, operands, true, false);"
1533 [(set_attr "type" "ssecomi")
1534 (set_attr "prefix" "maybe_vex")
1535 (set (attr "mode")
1536 (if_then_else (match_operand:SF 1 "" "")
1537 (const_string "SF")
1538 (const_string "DF")))
1539 (set_attr "prefix_rep" "0")
1540 (set (attr "prefix_data16")
1541 (if_then_else (eq_attr "mode" "DF")
1542 (const_string "1")
1543 (const_string "0")))
1544 (set_attr "athlon_decode" "vector")
1545 (set_attr "amdfam10_decode" "direct")
1546 (set_attr "bdver1_decode" "double")])
1547
1548 (define_insn "*cmpfp_i_i387"
1549 [(set (reg:CCFP FLAGS_REG)
1550 (compare:CCFP (match_operand 0 "register_operand" "f")
1551 (match_operand 1 "register_operand" "f")))]
1552 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1553 && TARGET_CMOVE
1554 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1555 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556 "* return output_fp_compare (insn, operands, true, false);"
1557 [(set_attr "type" "fcmp")
1558 (set (attr "mode")
1559 (cond [(match_operand:SF 1 "" "")
1560 (const_string "SF")
1561 (match_operand:DF 1 "" "")
1562 (const_string "DF")
1563 ]
1564 (const_string "XF")))
1565 (set_attr "athlon_decode" "vector")
1566 (set_attr "amdfam10_decode" "direct")
1567 (set_attr "bdver1_decode" "double")])
1568
1569 (define_insn "*cmpfp_iu_mixed"
1570 [(set (reg:CCFPU FLAGS_REG)
1571 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1572 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1573 "TARGET_MIX_SSE_I387
1574 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1575 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576 "* return output_fp_compare (insn, operands, true, true);"
1577 [(set_attr "type" "fcmp,ssecomi")
1578 (set_attr "prefix" "orig,maybe_vex")
1579 (set (attr "mode")
1580 (if_then_else (match_operand:SF 1 "" "")
1581 (const_string "SF")
1582 (const_string "DF")))
1583 (set (attr "prefix_rep")
1584 (if_then_else (eq_attr "type" "ssecomi")
1585 (const_string "0")
1586 (const_string "*")))
1587 (set (attr "prefix_data16")
1588 (cond [(eq_attr "type" "fcmp")
1589 (const_string "*")
1590 (eq_attr "mode" "DF")
1591 (const_string "1")
1592 ]
1593 (const_string "0")))
1594 (set_attr "athlon_decode" "vector")
1595 (set_attr "amdfam10_decode" "direct")
1596 (set_attr "bdver1_decode" "double")])
1597
1598 (define_insn "*cmpfp_iu_sse"
1599 [(set (reg:CCFPU FLAGS_REG)
1600 (compare:CCFPU (match_operand 0 "register_operand" "x")
1601 (match_operand 1 "nonimmediate_operand" "xm")))]
1602 "TARGET_SSE_MATH
1603 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1604 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1605 "* return output_fp_compare (insn, operands, true, true);"
1606 [(set_attr "type" "ssecomi")
1607 (set_attr "prefix" "maybe_vex")
1608 (set (attr "mode")
1609 (if_then_else (match_operand:SF 1 "" "")
1610 (const_string "SF")
1611 (const_string "DF")))
1612 (set_attr "prefix_rep" "0")
1613 (set (attr "prefix_data16")
1614 (if_then_else (eq_attr "mode" "DF")
1615 (const_string "1")
1616 (const_string "0")))
1617 (set_attr "athlon_decode" "vector")
1618 (set_attr "amdfam10_decode" "direct")
1619 (set_attr "bdver1_decode" "double")])
1620
1621 (define_insn "*cmpfp_iu_387"
1622 [(set (reg:CCFPU FLAGS_REG)
1623 (compare:CCFPU (match_operand 0 "register_operand" "f")
1624 (match_operand 1 "register_operand" "f")))]
1625 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1626 && TARGET_CMOVE
1627 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1628 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1629 "* return output_fp_compare (insn, operands, true, true);"
1630 [(set_attr "type" "fcmp")
1631 (set (attr "mode")
1632 (cond [(match_operand:SF 1 "" "")
1633 (const_string "SF")
1634 (match_operand:DF 1 "" "")
1635 (const_string "DF")
1636 ]
1637 (const_string "XF")))
1638 (set_attr "athlon_decode" "vector")
1639 (set_attr "amdfam10_decode" "direct")
1640 (set_attr "bdver1_decode" "direct")])
1641 \f
1642 ;; Push/pop instructions.
1643
1644 (define_insn "*push<mode>2"
1645 [(set (match_operand:DWI 0 "push_operand" "=<")
1646 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1647 ""
1648 "#")
1649
1650 (define_split
1651 [(set (match_operand:TI 0 "push_operand" "")
1652 (match_operand:TI 1 "general_operand" ""))]
1653 "TARGET_64BIT && reload_completed
1654 && !SSE_REG_P (operands[1])"
1655 [(const_int 0)]
1656 "ix86_split_long_move (operands); DONE;")
1657
1658 (define_insn "*pushdi2_rex64"
1659 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1660 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1661 "TARGET_64BIT"
1662 "@
1663 push{q}\t%1
1664 #"
1665 [(set_attr "type" "push,multi")
1666 (set_attr "mode" "DI")])
1667
1668 ;; Convert impossible pushes of immediate to existing instructions.
1669 ;; First try to get scratch register and go through it. In case this
1670 ;; fails, push sign extended lower part first and then overwrite
1671 ;; upper part by 32bit move.
1672 (define_peephole2
1673 [(match_scratch:DI 2 "r")
1674 (set (match_operand:DI 0 "push_operand" "")
1675 (match_operand:DI 1 "immediate_operand" ""))]
1676 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1677 && !x86_64_immediate_operand (operands[1], DImode)"
1678 [(set (match_dup 2) (match_dup 1))
1679 (set (match_dup 0) (match_dup 2))])
1680
1681 ;; We need to define this as both peepholer and splitter for case
1682 ;; peephole2 pass is not run.
1683 ;; "&& 1" is needed to keep it from matching the previous pattern.
1684 (define_peephole2
1685 [(set (match_operand:DI 0 "push_operand" "")
1686 (match_operand:DI 1 "immediate_operand" ""))]
1687 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1688 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1689 [(set (match_dup 0) (match_dup 1))
1690 (set (match_dup 2) (match_dup 3))]
1691 {
1692 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1693
1694 operands[1] = gen_lowpart (DImode, operands[2]);
1695 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1696 GEN_INT (4)));
1697 })
1698
1699 (define_split
1700 [(set (match_operand:DI 0 "push_operand" "")
1701 (match_operand:DI 1 "immediate_operand" ""))]
1702 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1703 ? epilogue_completed : reload_completed)
1704 && !symbolic_operand (operands[1], DImode)
1705 && !x86_64_immediate_operand (operands[1], DImode)"
1706 [(set (match_dup 0) (match_dup 1))
1707 (set (match_dup 2) (match_dup 3))]
1708 {
1709 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1710
1711 operands[1] = gen_lowpart (DImode, operands[2]);
1712 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1713 GEN_INT (4)));
1714 })
1715
1716 (define_split
1717 [(set (match_operand:DI 0 "push_operand" "")
1718 (match_operand:DI 1 "general_operand" ""))]
1719 "!TARGET_64BIT && reload_completed
1720 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1721 [(const_int 0)]
1722 "ix86_split_long_move (operands); DONE;")
1723
1724 (define_insn "*pushsi2"
1725 [(set (match_operand:SI 0 "push_operand" "=<")
1726 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1727 "!TARGET_64BIT"
1728 "push{l}\t%1"
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "SI")])
1731
1732 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1733 ;; "push a byte/word". But actually we use pushl, which has the effect
1734 ;; of rounding the amount pushed up to a word.
1735
1736 ;; For TARGET_64BIT we always round up to 8 bytes.
1737 (define_insn "*push<mode>2_rex64"
1738 [(set (match_operand:SWI124 0 "push_operand" "=X")
1739 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1740 "TARGET_64BIT"
1741 "push{q}\t%q1"
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "DI")])
1744
1745 (define_insn "*push<mode>2"
1746 [(set (match_operand:SWI12 0 "push_operand" "=X")
1747 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1748 "!TARGET_64BIT"
1749 "push{l}\t%k1"
1750 [(set_attr "type" "push")
1751 (set_attr "mode" "SI")])
1752
1753 (define_insn "*push<mode>2_prologue"
1754 [(set (match_operand:P 0 "push_operand" "=<")
1755 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1756 (clobber (mem:BLK (scratch)))]
1757 ""
1758 "push{<imodesuffix>}\t%1"
1759 [(set_attr "type" "push")
1760 (set_attr "mode" "<MODE>")])
1761
1762 (define_insn "*pop<mode>1"
1763 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1764 (match_operand:P 1 "pop_operand" ">"))]
1765 ""
1766 "pop{<imodesuffix>}\t%0"
1767 [(set_attr "type" "pop")
1768 (set_attr "mode" "<MODE>")])
1769
1770 (define_insn "*pop<mode>1_epilogue"
1771 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1772 (match_operand:P 1 "pop_operand" ">"))
1773 (clobber (mem:BLK (scratch)))]
1774 ""
1775 "pop{<imodesuffix>}\t%0"
1776 [(set_attr "type" "pop")
1777 (set_attr "mode" "<MODE>")])
1778 \f
1779 ;; Move instructions.
1780
1781 (define_expand "movoi"
1782 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1783 (match_operand:OI 1 "general_operand" ""))]
1784 "TARGET_AVX"
1785 "ix86_expand_move (OImode, operands); DONE;")
1786
1787 (define_expand "movti"
1788 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1789 (match_operand:TI 1 "nonimmediate_operand" ""))]
1790 "TARGET_64BIT || TARGET_SSE"
1791 {
1792 if (TARGET_64BIT)
1793 ix86_expand_move (TImode, operands);
1794 else if (push_operand (operands[0], TImode))
1795 ix86_expand_push (TImode, operands[1]);
1796 else
1797 ix86_expand_vector_move (TImode, operands);
1798 DONE;
1799 })
1800
1801 ;; This expands to what emit_move_complex would generate if we didn't
1802 ;; have a movti pattern. Having this avoids problems with reload on
1803 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1804 ;; to have around all the time.
1805 (define_expand "movcdi"
1806 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1807 (match_operand:CDI 1 "general_operand" ""))]
1808 ""
1809 {
1810 if (push_operand (operands[0], CDImode))
1811 emit_move_complex_push (CDImode, operands[0], operands[1]);
1812 else
1813 emit_move_complex_parts (operands[0], operands[1]);
1814 DONE;
1815 })
1816
1817 (define_expand "mov<mode>"
1818 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1819 (match_operand:SWI1248x 1 "general_operand" ""))]
1820 ""
1821 "ix86_expand_move (<MODE>mode, operands); DONE;")
1822
1823 (define_insn "*mov<mode>_xor"
1824 [(set (match_operand:SWI48 0 "register_operand" "=r")
1825 (match_operand:SWI48 1 "const0_operand" ""))
1826 (clobber (reg:CC FLAGS_REG))]
1827 "reload_completed"
1828 "xor{l}\t%k0, %k0"
1829 [(set_attr "type" "alu1")
1830 (set_attr "mode" "SI")
1831 (set_attr "length_immediate" "0")])
1832
1833 (define_insn "*mov<mode>_or"
1834 [(set (match_operand:SWI48 0 "register_operand" "=r")
1835 (match_operand:SWI48 1 "const_int_operand" ""))
1836 (clobber (reg:CC FLAGS_REG))]
1837 "reload_completed
1838 && operands[1] == constm1_rtx"
1839 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1840 [(set_attr "type" "alu1")
1841 (set_attr "mode" "<MODE>")
1842 (set_attr "length_immediate" "1")])
1843
1844 (define_insn "*movoi_internal_avx"
1845 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1846 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1847 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1848 {
1849 switch (which_alternative)
1850 {
1851 case 0:
1852 return standard_sse_constant_opcode (insn, operands[1]);
1853 case 1:
1854 case 2:
1855 if (misaligned_operand (operands[0], OImode)
1856 || misaligned_operand (operands[1], OImode))
1857 return "vmovdqu\t{%1, %0|%0, %1}";
1858 else
1859 return "vmovdqa\t{%1, %0|%0, %1}";
1860 default:
1861 gcc_unreachable ();
1862 }
1863 }
1864 [(set_attr "type" "sselog1,ssemov,ssemov")
1865 (set_attr "prefix" "vex")
1866 (set_attr "mode" "OI")])
1867
1868 (define_insn "*movti_internal_rex64"
1869 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1870 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1871 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1872 {
1873 switch (which_alternative)
1874 {
1875 case 0:
1876 case 1:
1877 return "#";
1878 case 2:
1879 return standard_sse_constant_opcode (insn, operands[1]);
1880 case 3:
1881 case 4:
1882 /* TDmode values are passed as TImode on the stack. Moving them
1883 to stack may result in unaligned memory access. */
1884 if (misaligned_operand (operands[0], TImode)
1885 || misaligned_operand (operands[1], TImode))
1886 {
1887 if (get_attr_mode (insn) == MODE_V4SF)
1888 return "%vmovups\t{%1, %0|%0, %1}";
1889 else
1890 return "%vmovdqu\t{%1, %0|%0, %1}";
1891 }
1892 else
1893 {
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vmovaps\t{%1, %0|%0, %1}";
1896 else
1897 return "%vmovdqa\t{%1, %0|%0, %1}";
1898 }
1899 default:
1900 gcc_unreachable ();
1901 }
1902 }
1903 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1904 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1905 (set (attr "mode")
1906 (cond [(eq_attr "alternative" "2,3")
1907 (if_then_else
1908 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1909 (const_int 0))
1910 (const_string "V4SF")
1911 (const_string "TI"))
1912 (eq_attr "alternative" "4")
1913 (if_then_else
1914 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1915 (const_int 0))
1916 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1917 (const_int 0)))
1918 (const_string "V4SF")
1919 (const_string "TI"))]
1920 (const_string "DI")))])
1921
1922 (define_split
1923 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1924 (match_operand:TI 1 "general_operand" ""))]
1925 "reload_completed
1926 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1927 [(const_int 0)]
1928 "ix86_split_long_move (operands); DONE;")
1929
1930 (define_insn "*movti_internal_sse"
1931 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1932 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1933 "TARGET_SSE && !TARGET_64BIT
1934 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1935 {
1936 switch (which_alternative)
1937 {
1938 case 0:
1939 return standard_sse_constant_opcode (insn, operands[1]);
1940 case 1:
1941 case 2:
1942 /* TDmode values are passed as TImode on the stack. Moving them
1943 to stack may result in unaligned memory access. */
1944 if (misaligned_operand (operands[0], TImode)
1945 || misaligned_operand (operands[1], TImode))
1946 {
1947 if (get_attr_mode (insn) == MODE_V4SF)
1948 return "%vmovups\t{%1, %0|%0, %1}";
1949 else
1950 return "%vmovdqu\t{%1, %0|%0, %1}";
1951 }
1952 else
1953 {
1954 if (get_attr_mode (insn) == MODE_V4SF)
1955 return "%vmovaps\t{%1, %0|%0, %1}";
1956 else
1957 return "%vmovdqa\t{%1, %0|%0, %1}";
1958 }
1959 default:
1960 gcc_unreachable ();
1961 }
1962 }
1963 [(set_attr "type" "sselog1,ssemov,ssemov")
1964 (set_attr "prefix" "maybe_vex")
1965 (set (attr "mode")
1966 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1967 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1968 (const_int 0)))
1969 (const_string "V4SF")
1970 (and (eq_attr "alternative" "2")
1971 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1972 (const_int 0)))
1973 (const_string "V4SF")]
1974 (const_string "TI")))])
1975
1976 (define_insn "*movdi_internal_rex64"
1977 [(set (match_operand:DI 0 "nonimmediate_operand"
1978 "=r,r ,r,m ,!m,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1979 (match_operand:DI 1 "general_operand"
1980 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1981 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1982 {
1983 switch (get_attr_type (insn))
1984 {
1985 case TYPE_SSECVT:
1986 if (SSE_REG_P (operands[0]))
1987 return "movq2dq\t{%1, %0|%0, %1}";
1988 else
1989 return "movdq2q\t{%1, %0|%0, %1}";
1990
1991 case TYPE_SSEMOV:
1992 if (get_attr_mode (insn) == MODE_TI)
1993 return "%vmovdqa\t{%1, %0|%0, %1}";
1994 /* Handle broken assemblers that require movd instead of movq. */
1995 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1996 return "%vmovd\t{%1, %0|%0, %1}";
1997 else
1998 return "%vmovq\t{%1, %0|%0, %1}";
1999
2000 case TYPE_MMXMOV:
2001 /* Handle broken assemblers that require movd instead of movq. */
2002 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2003 return "movd\t{%1, %0|%0, %1}";
2004 else
2005 return "movq\t{%1, %0|%0, %1}";
2006
2007 case TYPE_SSELOG1:
2008 return standard_sse_constant_opcode (insn, operands[1]);
2009
2010 case TYPE_MMX:
2011 return "pxor\t%0, %0";
2012
2013 case TYPE_MULTI:
2014 return "#";
2015
2016 case TYPE_LEA:
2017 return "lea{q}\t{%a1, %0|%0, %a1}";
2018
2019 default:
2020 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2021 if (get_attr_mode (insn) == MODE_SI)
2022 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2023 else if (which_alternative == 2)
2024 return "movabs{q}\t{%1, %0|%0, %1}";
2025 else
2026 return "mov{q}\t{%1, %0|%0, %1}";
2027 }
2028 }
2029 [(set (attr "type")
2030 (cond [(eq_attr "alternative" "4")
2031 (const_string "multi")
2032 (eq_attr "alternative" "5")
2033 (const_string "mmx")
2034 (eq_attr "alternative" "6,7,8,9")
2035 (const_string "mmxmov")
2036 (eq_attr "alternative" "10")
2037 (const_string "sselog1")
2038 (eq_attr "alternative" "11,12,13,14,15")
2039 (const_string "ssemov")
2040 (eq_attr "alternative" "16,17")
2041 (const_string "ssecvt")
2042 (match_operand 1 "pic_32bit_operand" "")
2043 (const_string "lea")
2044 ]
2045 (const_string "imov")))
2046 (set (attr "modrm")
2047 (if_then_else
2048 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2049 (const_string "0")
2050 (const_string "*")))
2051 (set (attr "length_immediate")
2052 (if_then_else
2053 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2054 (const_string "8")
2055 (const_string "*")))
2056 (set (attr "prefix_rex")
2057 (if_then_else (eq_attr "alternative" "8,9")
2058 (const_string "1")
2059 (const_string "*")))
2060 (set (attr "prefix_data16")
2061 (if_then_else (eq_attr "alternative" "11")
2062 (const_string "1")
2063 (const_string "*")))
2064 (set (attr "prefix")
2065 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2066 (const_string "maybe_vex")
2067 (const_string "orig")))
2068 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2069
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it. In case this
2072 ;; fails, move by 32bit parts.
2073 (define_peephole2
2074 [(match_scratch:DI 2 "r")
2075 (set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 1))
2080 (set (match_dup 0) (match_dup 2))])
2081
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 ;; "&& 1" is needed to keep it from matching the previous pattern.
2085 (define_peephole2
2086 [(set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090 [(set (match_dup 2) (match_dup 3))
2091 (set (match_dup 4) (match_dup 5))]
2092 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2093
2094 (define_split
2095 [(set (match_operand:DI 0 "memory_operand" "")
2096 (match_operand:DI 1 "immediate_operand" ""))]
2097 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2098 ? epilogue_completed : reload_completed)
2099 && !symbolic_operand (operands[1], DImode)
2100 && !x86_64_immediate_operand (operands[1], DImode)"
2101 [(set (match_dup 2) (match_dup 3))
2102 (set (match_dup 4) (match_dup 5))]
2103 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2104
2105 (define_insn "*movdi_internal"
2106 [(set (match_operand:DI 0 "nonimmediate_operand"
2107 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2108 (match_operand:DI 1 "general_operand"
2109 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m ,*Ym ,*Y2"))]
2110 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2111 {
2112 switch (get_attr_type (insn))
2113 {
2114 case TYPE_SSECVT:
2115 if (SSE_REG_P (operands[0]))
2116 return "movq2dq\t{%1, %0|%0, %1}";
2117 else
2118 return "movdq2q\t{%1, %0|%0, %1}";
2119
2120 case TYPE_SSEMOV:
2121 switch (get_attr_mode (insn))
2122 {
2123 case MODE_TI:
2124 return "%vmovdqa\t{%1, %0|%0, %1}";
2125 case MODE_DI:
2126 return "%vmovq\t{%1, %0|%0, %1}";
2127 case MODE_V4SF:
2128 return "movaps\t{%1, %0|%0, %1}";
2129 case MODE_V2SF:
2130 return "movlps\t{%1, %0|%0, %1}";
2131 default:
2132 gcc_unreachable ();
2133 }
2134
2135 case TYPE_MMXMOV:
2136 return "movq\t{%1, %0|%0, %1}";
2137
2138 case TYPE_SSELOG1:
2139 return standard_sse_constant_opcode (insn, operands[1]);
2140
2141 case TYPE_MMX:
2142 return "pxor\t%0, %0";
2143
2144 case TYPE_MULTI:
2145 return "#";
2146
2147 default:
2148 gcc_unreachable ();
2149 }
2150 }
2151 [(set (attr "isa")
2152 (if_then_else (eq_attr "alternative" "9,10,11,12")
2153 (const_string "noavx")
2154 (const_string "*")))
2155 (set (attr "type")
2156 (cond [(eq_attr "alternative" "0,1")
2157 (const_string "multi")
2158 (eq_attr "alternative" "2")
2159 (const_string "mmx")
2160 (eq_attr "alternative" "3,4")
2161 (const_string "mmxmov")
2162 (eq_attr "alternative" "5,9")
2163 (const_string "sselog1")
2164 (eq_attr "alternative" "13,14")
2165 (const_string "ssecvt")
2166 ]
2167 (const_string "ssemov")))
2168 (set (attr "prefix")
2169 (if_then_else (eq_attr "alternative" "5,6,7,8")
2170 (const_string "maybe_vex")
2171 (const_string "orig")))
2172 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2173
2174 (define_split
2175 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2176 (match_operand:DI 1 "general_operand" ""))]
2177 "!TARGET_64BIT && reload_completed
2178 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2179 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2180 [(const_int 0)]
2181 "ix86_split_long_move (operands); DONE;")
2182
2183 (define_insn "*movsi_internal"
2184 [(set (match_operand:SI 0 "nonimmediate_operand"
2185 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2186 (match_operand:SI 1 "general_operand"
2187 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2188 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2189 {
2190 switch (get_attr_type (insn))
2191 {
2192 case TYPE_SSELOG1:
2193 return standard_sse_constant_opcode (insn, operands[1]);
2194
2195 case TYPE_SSEMOV:
2196 switch (get_attr_mode (insn))
2197 {
2198 case MODE_TI:
2199 return "%vmovdqa\t{%1, %0|%0, %1}";
2200 case MODE_V4SF:
2201 return "%vmovaps\t{%1, %0|%0, %1}";
2202 case MODE_SI:
2203 return "%vmovd\t{%1, %0|%0, %1}";
2204 case MODE_SF:
2205 return "%vmovss\t{%1, %0|%0, %1}";
2206 default:
2207 gcc_unreachable ();
2208 }
2209
2210 case TYPE_MMX:
2211 return "pxor\t%0, %0";
2212
2213 case TYPE_MMXMOV:
2214 if (get_attr_mode (insn) == MODE_DI)
2215 return "movq\t{%1, %0|%0, %1}";
2216 return "movd\t{%1, %0|%0, %1}";
2217
2218 case TYPE_LEA:
2219 return "lea{l}\t{%a1, %0|%0, %a1}";
2220
2221 default:
2222 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2223 return "mov{l}\t{%1, %0|%0, %1}";
2224 }
2225 }
2226 [(set (attr "type")
2227 (cond [(eq_attr "alternative" "2")
2228 (const_string "mmx")
2229 (eq_attr "alternative" "3,4,5")
2230 (const_string "mmxmov")
2231 (eq_attr "alternative" "6")
2232 (const_string "sselog1")
2233 (eq_attr "alternative" "7,8,9,10,11")
2234 (const_string "ssemov")
2235 (match_operand 1 "pic_32bit_operand" "")
2236 (const_string "lea")
2237 ]
2238 (const_string "imov")))
2239 (set (attr "prefix")
2240 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2241 (const_string "orig")
2242 (const_string "maybe_vex")))
2243 (set (attr "prefix_data16")
2244 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2245 (const_string "1")
2246 (const_string "*")))
2247 (set (attr "mode")
2248 (cond [(eq_attr "alternative" "2,3")
2249 (const_string "DI")
2250 (eq_attr "alternative" "6,7")
2251 (if_then_else
2252 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2253 (const_string "V4SF")
2254 (const_string "TI"))
2255 (and (eq_attr "alternative" "8,9,10,11")
2256 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2257 (const_string "SF")
2258 ]
2259 (const_string "SI")))])
2260
2261 (define_insn "*movhi_internal"
2262 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2263 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2264 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2265 {
2266 switch (get_attr_type (insn))
2267 {
2268 case TYPE_IMOVX:
2269 /* movzwl is faster than movw on p2 due to partial word stalls,
2270 though not as fast as an aligned movl. */
2271 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2272 default:
2273 if (get_attr_mode (insn) == MODE_SI)
2274 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2275 else
2276 return "mov{w}\t{%1, %0|%0, %1}";
2277 }
2278 }
2279 [(set (attr "type")
2280 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2281 (const_int 0))
2282 (const_string "imov")
2283 (and (eq_attr "alternative" "0")
2284 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2285 (const_int 0))
2286 (eq (symbol_ref "TARGET_HIMODE_MATH")
2287 (const_int 0))))
2288 (const_string "imov")
2289 (and (eq_attr "alternative" "1,2")
2290 (match_operand:HI 1 "aligned_operand" ""))
2291 (const_string "imov")
2292 (and (ne (symbol_ref "TARGET_MOVX")
2293 (const_int 0))
2294 (eq_attr "alternative" "0,2"))
2295 (const_string "imovx")
2296 ]
2297 (const_string "imov")))
2298 (set (attr "mode")
2299 (cond [(eq_attr "type" "imovx")
2300 (const_string "SI")
2301 (and (eq_attr "alternative" "1,2")
2302 (match_operand:HI 1 "aligned_operand" ""))
2303 (const_string "SI")
2304 (and (eq_attr "alternative" "0")
2305 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2306 (const_int 0))
2307 (eq (symbol_ref "TARGET_HIMODE_MATH")
2308 (const_int 0))))
2309 (const_string "SI")
2310 ]
2311 (const_string "HI")))])
2312
2313 ;; Situation is quite tricky about when to choose full sized (SImode) move
2314 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2315 ;; partial register dependency machines (such as AMD Athlon), where QImode
2316 ;; moves issue extra dependency and for partial register stalls machines
2317 ;; that don't use QImode patterns (and QImode move cause stall on the next
2318 ;; instruction).
2319 ;;
2320 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2321 ;; register stall machines with, where we use QImode instructions, since
2322 ;; partial register stall can be caused there. Then we use movzx.
2323 (define_insn "*movqi_internal"
2324 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2325 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2326 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2327 {
2328 switch (get_attr_type (insn))
2329 {
2330 case TYPE_IMOVX:
2331 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2332 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2333 default:
2334 if (get_attr_mode (insn) == MODE_SI)
2335 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2336 else
2337 return "mov{b}\t{%1, %0|%0, %1}";
2338 }
2339 }
2340 [(set (attr "type")
2341 (cond [(and (eq_attr "alternative" "5")
2342 (not (match_operand:QI 1 "aligned_operand" "")))
2343 (const_string "imovx")
2344 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2345 (const_int 0))
2346 (const_string "imov")
2347 (and (eq_attr "alternative" "3")
2348 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2349 (const_int 0))
2350 (eq (symbol_ref "TARGET_QIMODE_MATH")
2351 (const_int 0))))
2352 (const_string "imov")
2353 (eq_attr "alternative" "3,5")
2354 (const_string "imovx")
2355 (and (ne (symbol_ref "TARGET_MOVX")
2356 (const_int 0))
2357 (eq_attr "alternative" "2"))
2358 (const_string "imovx")
2359 ]
2360 (const_string "imov")))
2361 (set (attr "mode")
2362 (cond [(eq_attr "alternative" "3,4,5")
2363 (const_string "SI")
2364 (eq_attr "alternative" "6")
2365 (const_string "QI")
2366 (eq_attr "type" "imovx")
2367 (const_string "SI")
2368 (and (eq_attr "type" "imov")
2369 (and (eq_attr "alternative" "0,1")
2370 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2371 (const_int 0))
2372 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2373 (const_int 0))
2374 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2375 (const_int 0))))))
2376 (const_string "SI")
2377 ;; Avoid partial register stalls when not using QImode arithmetic
2378 (and (eq_attr "type" "imov")
2379 (and (eq_attr "alternative" "0,1")
2380 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2381 (const_int 0))
2382 (eq (symbol_ref "TARGET_QIMODE_MATH")
2383 (const_int 0)))))
2384 (const_string "SI")
2385 ]
2386 (const_string "QI")))])
2387
2388 ;; Stores and loads of ax to arbitrary constant address.
2389 ;; We fake an second form of instruction to force reload to load address
2390 ;; into register when rax is not available
2391 (define_insn "*movabs<mode>_1"
2392 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2393 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2394 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2395 "@
2396 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2397 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2398 [(set_attr "type" "imov")
2399 (set_attr "modrm" "0,*")
2400 (set_attr "length_address" "8,0")
2401 (set_attr "length_immediate" "0,*")
2402 (set_attr "memory" "store")
2403 (set_attr "mode" "<MODE>")])
2404
2405 (define_insn "*movabs<mode>_2"
2406 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2407 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2408 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2409 "@
2410 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2411 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2412 [(set_attr "type" "imov")
2413 (set_attr "modrm" "0,*")
2414 (set_attr "length_address" "8,0")
2415 (set_attr "length_immediate" "0")
2416 (set_attr "memory" "load")
2417 (set_attr "mode" "<MODE>")])
2418
2419 (define_insn "*swap<mode>"
2420 [(set (match_operand:SWI48 0 "register_operand" "+r")
2421 (match_operand:SWI48 1 "register_operand" "+r"))
2422 (set (match_dup 1)
2423 (match_dup 0))]
2424 ""
2425 "xchg{<imodesuffix>}\t%1, %0"
2426 [(set_attr "type" "imov")
2427 (set_attr "mode" "<MODE>")
2428 (set_attr "pent_pair" "np")
2429 (set_attr "athlon_decode" "vector")
2430 (set_attr "amdfam10_decode" "double")
2431 (set_attr "bdver1_decode" "double")])
2432
2433 (define_insn "*swap<mode>_1"
2434 [(set (match_operand:SWI12 0 "register_operand" "+r")
2435 (match_operand:SWI12 1 "register_operand" "+r"))
2436 (set (match_dup 1)
2437 (match_dup 0))]
2438 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2439 "xchg{l}\t%k1, %k0"
2440 [(set_attr "type" "imov")
2441 (set_attr "mode" "SI")
2442 (set_attr "pent_pair" "np")
2443 (set_attr "athlon_decode" "vector")
2444 (set_attr "amdfam10_decode" "double")
2445 (set_attr "bdver1_decode" "double")])
2446
2447 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2448 ;; is disabled for AMDFAM10
2449 (define_insn "*swap<mode>_2"
2450 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2451 (match_operand:SWI12 1 "register_operand" "+<r>"))
2452 (set (match_dup 1)
2453 (match_dup 0))]
2454 "TARGET_PARTIAL_REG_STALL"
2455 "xchg{<imodesuffix>}\t%1, %0"
2456 [(set_attr "type" "imov")
2457 (set_attr "mode" "<MODE>")
2458 (set_attr "pent_pair" "np")
2459 (set_attr "athlon_decode" "vector")])
2460
2461 (define_expand "movstrict<mode>"
2462 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2463 (match_operand:SWI12 1 "general_operand" ""))]
2464 ""
2465 {
2466 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2467 FAIL;
2468 if (GET_CODE (operands[0]) == SUBREG
2469 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2470 FAIL;
2471 /* Don't generate memory->memory moves, go through a register */
2472 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2473 operands[1] = force_reg (<MODE>mode, operands[1]);
2474 })
2475
2476 (define_insn "*movstrict<mode>_1"
2477 [(set (strict_low_part
2478 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2479 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2480 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2481 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2482 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2483 [(set_attr "type" "imov")
2484 (set_attr "mode" "<MODE>")])
2485
2486 (define_insn "*movstrict<mode>_xor"
2487 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2488 (match_operand:SWI12 1 "const0_operand" ""))
2489 (clobber (reg:CC FLAGS_REG))]
2490 "reload_completed"
2491 "xor{<imodesuffix>}\t%0, %0"
2492 [(set_attr "type" "alu1")
2493 (set_attr "mode" "<MODE>")
2494 (set_attr "length_immediate" "0")])
2495
2496 (define_insn "*mov<mode>_extv_1"
2497 [(set (match_operand:SWI24 0 "register_operand" "=R")
2498 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2499 (const_int 8)
2500 (const_int 8)))]
2501 ""
2502 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2503 [(set_attr "type" "imovx")
2504 (set_attr "mode" "SI")])
2505
2506 (define_insn "*movqi_extv_1_rex64"
2507 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2508 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2509 (const_int 8)
2510 (const_int 8)))]
2511 "TARGET_64BIT"
2512 {
2513 switch (get_attr_type (insn))
2514 {
2515 case TYPE_IMOVX:
2516 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2517 default:
2518 return "mov{b}\t{%h1, %0|%0, %h1}";
2519 }
2520 }
2521 [(set (attr "type")
2522 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2523 (ne (symbol_ref "TARGET_MOVX")
2524 (const_int 0)))
2525 (const_string "imovx")
2526 (const_string "imov")))
2527 (set (attr "mode")
2528 (if_then_else (eq_attr "type" "imovx")
2529 (const_string "SI")
2530 (const_string "QI")))])
2531
2532 (define_insn "*movqi_extv_1"
2533 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2534 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2535 (const_int 8)
2536 (const_int 8)))]
2537 "!TARGET_64BIT"
2538 {
2539 switch (get_attr_type (insn))
2540 {
2541 case TYPE_IMOVX:
2542 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2543 default:
2544 return "mov{b}\t{%h1, %0|%0, %h1}";
2545 }
2546 }
2547 [(set (attr "type")
2548 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2549 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2550 (ne (symbol_ref "TARGET_MOVX")
2551 (const_int 0))))
2552 (const_string "imovx")
2553 (const_string "imov")))
2554 (set (attr "mode")
2555 (if_then_else (eq_attr "type" "imovx")
2556 (const_string "SI")
2557 (const_string "QI")))])
2558
2559 (define_insn "*mov<mode>_extzv_1"
2560 [(set (match_operand:SWI48 0 "register_operand" "=R")
2561 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2562 (const_int 8)
2563 (const_int 8)))]
2564 ""
2565 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2566 [(set_attr "type" "imovx")
2567 (set_attr "mode" "SI")])
2568
2569 (define_insn "*movqi_extzv_2_rex64"
2570 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2571 (subreg:QI
2572 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2573 (const_int 8)
2574 (const_int 8)) 0))]
2575 "TARGET_64BIT"
2576 {
2577 switch (get_attr_type (insn))
2578 {
2579 case TYPE_IMOVX:
2580 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2581 default:
2582 return "mov{b}\t{%h1, %0|%0, %h1}";
2583 }
2584 }
2585 [(set (attr "type")
2586 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2587 (ne (symbol_ref "TARGET_MOVX")
2588 (const_int 0)))
2589 (const_string "imovx")
2590 (const_string "imov")))
2591 (set (attr "mode")
2592 (if_then_else (eq_attr "type" "imovx")
2593 (const_string "SI")
2594 (const_string "QI")))])
2595
2596 (define_insn "*movqi_extzv_2"
2597 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2598 (subreg:QI
2599 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2600 (const_int 8)
2601 (const_int 8)) 0))]
2602 "!TARGET_64BIT"
2603 {
2604 switch (get_attr_type (insn))
2605 {
2606 case TYPE_IMOVX:
2607 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2608 default:
2609 return "mov{b}\t{%h1, %0|%0, %h1}";
2610 }
2611 }
2612 [(set (attr "type")
2613 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2614 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2615 (ne (symbol_ref "TARGET_MOVX")
2616 (const_int 0))))
2617 (const_string "imovx")
2618 (const_string "imov")))
2619 (set (attr "mode")
2620 (if_then_else (eq_attr "type" "imovx")
2621 (const_string "SI")
2622 (const_string "QI")))])
2623
2624 (define_expand "mov<mode>_insv_1"
2625 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2626 (const_int 8)
2627 (const_int 8))
2628 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2629
2630 (define_insn "*mov<mode>_insv_1_rex64"
2631 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2632 (const_int 8)
2633 (const_int 8))
2634 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2635 "TARGET_64BIT"
2636 "mov{b}\t{%b1, %h0|%h0, %b1}"
2637 [(set_attr "type" "imov")
2638 (set_attr "mode" "QI")])
2639
2640 (define_insn "*movsi_insv_1"
2641 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2642 (const_int 8)
2643 (const_int 8))
2644 (match_operand:SI 1 "general_operand" "Qmn"))]
2645 "!TARGET_64BIT"
2646 "mov{b}\t{%b1, %h0|%h0, %b1}"
2647 [(set_attr "type" "imov")
2648 (set_attr "mode" "QI")])
2649
2650 (define_insn "*movqi_insv_2"
2651 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2652 (const_int 8)
2653 (const_int 8))
2654 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2655 (const_int 8)))]
2656 ""
2657 "mov{b}\t{%h1, %h0|%h0, %h1}"
2658 [(set_attr "type" "imov")
2659 (set_attr "mode" "QI")])
2660 \f
2661 ;; Floating point push instructions.
2662
2663 (define_insn "*pushtf"
2664 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2665 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2666 "TARGET_SSE2"
2667 {
2668 /* This insn should be already split before reg-stack. */
2669 gcc_unreachable ();
2670 }
2671 [(set_attr "type" "multi")
2672 (set_attr "unit" "sse,*,*")
2673 (set_attr "mode" "TF,SI,SI")])
2674
2675 ;; %%% Kill this when call knows how to work this out.
2676 (define_split
2677 [(set (match_operand:TF 0 "push_operand" "")
2678 (match_operand:TF 1 "sse_reg_operand" ""))]
2679 "TARGET_SSE2 && reload_completed"
2680 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2681 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2682
2683 (define_insn "*pushxf"
2684 [(set (match_operand:XF 0 "push_operand" "=<,<")
2685 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2686 "optimize_function_for_speed_p (cfun)"
2687 {
2688 /* This insn should be already split before reg-stack. */
2689 gcc_unreachable ();
2690 }
2691 [(set_attr "type" "multi")
2692 (set_attr "unit" "i387,*")
2693 (set_attr "mode" "XF,SI")])
2694
2695 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2696 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2697 ;; Pushing using integer instructions is longer except for constants
2698 ;; and direct memory references (assuming that any given constant is pushed
2699 ;; only once, but this ought to be handled elsewhere).
2700
2701 (define_insn "*pushxf_nointeger"
2702 [(set (match_operand:XF 0 "push_operand" "=X,X")
2703 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2704 "optimize_function_for_size_p (cfun)"
2705 {
2706 /* This insn should be already split before reg-stack. */
2707 gcc_unreachable ();
2708 }
2709 [(set_attr "type" "multi")
2710 (set_attr "unit" "i387,*")
2711 (set_attr "mode" "XF,SI")])
2712
2713 ;; %%% Kill this when call knows how to work this out.
2714 (define_split
2715 [(set (match_operand:XF 0 "push_operand" "")
2716 (match_operand:XF 1 "fp_register_operand" ""))]
2717 "reload_completed"
2718 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2719 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2720 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2721
2722 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2723 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2724 ;; On the average, pushdf using integers can be still shorter.
2725
2726 (define_insn "*pushdf"
2727 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2728 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2729 ""
2730 {
2731 /* This insn should be already split before reg-stack. */
2732 gcc_unreachable ();
2733 }
2734 [(set_attr "type" "multi")
2735 (set_attr "unit" "i387,*,*")
2736 (set_attr "mode" "DF,SI,DF")])
2737
2738 ;; %%% Kill this when call knows how to work this out.
2739 (define_split
2740 [(set (match_operand:DF 0 "push_operand" "")
2741 (match_operand:DF 1 "any_fp_register_operand" ""))]
2742 "reload_completed"
2743 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2744 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2745
2746 (define_insn "*pushsf_rex64"
2747 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2748 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2749 "TARGET_64BIT"
2750 {
2751 /* Anything else should be already split before reg-stack. */
2752 gcc_assert (which_alternative == 1);
2753 return "push{q}\t%q1";
2754 }
2755 [(set_attr "type" "multi,push,multi")
2756 (set_attr "unit" "i387,*,*")
2757 (set_attr "mode" "SF,DI,SF")])
2758
2759 (define_insn "*pushsf"
2760 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2761 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2762 "!TARGET_64BIT"
2763 {
2764 /* Anything else should be already split before reg-stack. */
2765 gcc_assert (which_alternative == 1);
2766 return "push{l}\t%1";
2767 }
2768 [(set_attr "type" "multi,push,multi")
2769 (set_attr "unit" "i387,*,*")
2770 (set_attr "mode" "SF,SI,SF")])
2771
2772 ;; %%% Kill this when call knows how to work this out.
2773 (define_split
2774 [(set (match_operand:SF 0 "push_operand" "")
2775 (match_operand:SF 1 "any_fp_register_operand" ""))]
2776 "reload_completed"
2777 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2780
2781 (define_split
2782 [(set (match_operand:SF 0 "push_operand" "")
2783 (match_operand:SF 1 "memory_operand" ""))]
2784 "reload_completed
2785 && (operands[2] = find_constant_src (insn))"
2786 [(set (match_dup 0) (match_dup 2))])
2787
2788 (define_split
2789 [(set (match_operand 0 "push_operand" "")
2790 (match_operand 1 "general_operand" ""))]
2791 "reload_completed
2792 && (GET_MODE (operands[0]) == TFmode
2793 || GET_MODE (operands[0]) == XFmode
2794 || GET_MODE (operands[0]) == DFmode)
2795 && !ANY_FP_REG_P (operands[1])"
2796 [(const_int 0)]
2797 "ix86_split_long_move (operands); DONE;")
2798 \f
2799 ;; Floating point move instructions.
2800
2801 (define_expand "movtf"
2802 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2803 (match_operand:TF 1 "nonimmediate_operand" ""))]
2804 "TARGET_SSE2"
2805 {
2806 ix86_expand_move (TFmode, operands);
2807 DONE;
2808 })
2809
2810 (define_expand "mov<mode>"
2811 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2812 (match_operand:X87MODEF 1 "general_operand" ""))]
2813 ""
2814 "ix86_expand_move (<MODE>mode, operands); DONE;")
2815
2816 (define_insn "*movtf_internal"
2817 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2818 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2819 "TARGET_SSE2
2820 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2821 && (!can_create_pseudo_p ()
2822 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2823 || GET_CODE (operands[1]) != CONST_DOUBLE
2824 || (optimize_function_for_size_p (cfun)
2825 && standard_sse_constant_p (operands[1])
2826 && !memory_operand (operands[0], TFmode))
2827 || (!TARGET_MEMORY_MISMATCH_STALL
2828 && memory_operand (operands[0], TFmode)))"
2829 {
2830 switch (which_alternative)
2831 {
2832 case 0:
2833 case 1:
2834 /* Handle misaligned load/store since we
2835 don't have movmisaligntf pattern. */
2836 if (misaligned_operand (operands[0], TFmode)
2837 || misaligned_operand (operands[1], TFmode))
2838 {
2839 if (get_attr_mode (insn) == MODE_V4SF)
2840 return "%vmovups\t{%1, %0|%0, %1}";
2841 else
2842 return "%vmovdqu\t{%1, %0|%0, %1}";
2843 }
2844 else
2845 {
2846 if (get_attr_mode (insn) == MODE_V4SF)
2847 return "%vmovaps\t{%1, %0|%0, %1}";
2848 else
2849 return "%vmovdqa\t{%1, %0|%0, %1}";
2850 }
2851
2852 case 2:
2853 return standard_sse_constant_opcode (insn, operands[1]);
2854
2855 case 3:
2856 case 4:
2857 return "#";
2858
2859 default:
2860 gcc_unreachable ();
2861 }
2862 }
2863 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2864 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2865 (set (attr "mode")
2866 (cond [(eq_attr "alternative" "0,2")
2867 (if_then_else
2868 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2869 (const_int 0))
2870 (const_string "V4SF")
2871 (const_string "TI"))
2872 (eq_attr "alternative" "1")
2873 (if_then_else
2874 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2875 (const_int 0))
2876 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2877 (const_int 0)))
2878 (const_string "V4SF")
2879 (const_string "TI"))]
2880 (const_string "DI")))])
2881
2882 ;; Possible store forwarding (partial memory) stall in alternative 4.
2883 (define_insn "*movxf_internal"
2884 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2885 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2886 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2887 && (!can_create_pseudo_p ()
2888 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889 || GET_CODE (operands[1]) != CONST_DOUBLE
2890 || (optimize_function_for_size_p (cfun)
2891 && standard_80387_constant_p (operands[1]) > 0
2892 && !memory_operand (operands[0], XFmode))
2893 || (!TARGET_MEMORY_MISMATCH_STALL
2894 && memory_operand (operands[0], XFmode)))"
2895 {
2896 switch (which_alternative)
2897 {
2898 case 0:
2899 case 1:
2900 return output_387_reg_move (insn, operands);
2901
2902 case 2:
2903 return standard_80387_constant_opcode (operands[1]);
2904
2905 case 3:
2906 case 4:
2907 return "#";
2908
2909 default:
2910 gcc_unreachable ();
2911 }
2912 }
2913 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2914 (set_attr "mode" "XF,XF,XF,SI,SI")])
2915
2916 (define_insn "*movdf_internal_rex64"
2917 [(set (match_operand:DF 0 "nonimmediate_operand"
2918 "=f,m,f,?r,?m,?r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2919 (match_operand:DF 1 "general_operand"
2920 "fm,f,G,rm,r ,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2921 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2922 && (!can_create_pseudo_p ()
2923 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2924 || GET_CODE (operands[1]) != CONST_DOUBLE
2925 || (optimize_function_for_size_p (cfun)
2926 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2927 && standard_80387_constant_p (operands[1]) > 0)
2928 || (TARGET_SSE2 && TARGET_SSE_MATH
2929 && standard_sse_constant_p (operands[1]))))
2930 || memory_operand (operands[0], DFmode))"
2931 {
2932 switch (which_alternative)
2933 {
2934 case 0:
2935 case 1:
2936 return output_387_reg_move (insn, operands);
2937
2938 case 2:
2939 return standard_80387_constant_opcode (operands[1]);
2940
2941 case 3:
2942 case 4:
2943 return "mov{q}\t{%1, %0|%0, %1}";
2944
2945 case 5:
2946 return "movabs{q}\t{%1, %0|%0, %1}";
2947
2948 case 6:
2949 return "#";
2950
2951 case 7:
2952 return standard_sse_constant_opcode (insn, operands[1]);
2953
2954 case 8:
2955 case 9:
2956 case 10:
2957 switch (get_attr_mode (insn))
2958 {
2959 case MODE_V2DF:
2960 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2961 return "%vmovapd\t{%1, %0|%0, %1}";
2962 case MODE_V4SF:
2963 return "%vmovaps\t{%1, %0|%0, %1}";
2964
2965 case MODE_DI:
2966 return "%vmovq\t{%1, %0|%0, %1}";
2967 case MODE_DF:
2968 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2969 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2970 return "%vmovsd\t{%1, %0|%0, %1}";
2971 case MODE_V1DF:
2972 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2973 case MODE_V2SF:
2974 return "%vmovlps\t{%1, %d0|%d0, %1}";
2975 default:
2976 gcc_unreachable ();
2977 }
2978
2979 case 11:
2980 case 12:
2981 /* Handle broken assemblers that require movd instead of movq. */
2982 return "%vmovd\t{%1, %0|%0, %1}";
2983
2984 default:
2985 gcc_unreachable();
2986 }
2987 }
2988 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2989 (set (attr "modrm")
2990 (if_then_else
2991 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2992 (const_string "0")
2993 (const_string "*")))
2994 (set (attr "length_immediate")
2995 (if_then_else
2996 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2997 (const_string "8")
2998 (const_string "*")))
2999 (set (attr "prefix")
3000 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3001 (const_string "orig")
3002 (const_string "maybe_vex")))
3003 (set (attr "prefix_data16")
3004 (if_then_else (eq_attr "mode" "V1DF")
3005 (const_string "1")
3006 (const_string "*")))
3007 (set (attr "mode")
3008 (cond [(eq_attr "alternative" "0,1,2")
3009 (const_string "DF")
3010 (eq_attr "alternative" "3,4,5,6,11,12")
3011 (const_string "DI")
3012
3013 /* xorps is one byte shorter. */
3014 (eq_attr "alternative" "7")
3015 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3016 (const_int 0))
3017 (const_string "V4SF")
3018 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3019 (const_int 0))
3020 (const_string "TI")
3021 ]
3022 (const_string "V2DF"))
3023
3024 /* For architectures resolving dependencies on
3025 whole SSE registers use APD move to break dependency
3026 chains, otherwise use short move to avoid extra work.
3027
3028 movaps encodes one byte shorter. */
3029 (eq_attr "alternative" "8")
3030 (cond
3031 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3032 (const_int 0))
3033 (const_string "V4SF")
3034 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3035 (const_int 0))
3036 (const_string "V2DF")
3037 ]
3038 (const_string "DF"))
3039 /* For architectures resolving dependencies on register
3040 parts we may avoid extra work to zero out upper part
3041 of register. */
3042 (eq_attr "alternative" "9")
3043 (if_then_else
3044 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3045 (const_int 0))
3046 (const_string "V1DF")
3047 (const_string "DF"))
3048 ]
3049 (const_string "DF")))])
3050
3051 ;; Possible store forwarding (partial memory) stall in alternative 4.
3052 (define_insn "*movdf_internal"
3053 [(set (match_operand:DF 0 "nonimmediate_operand"
3054 "=f,m,f,?Yd*r ,!o ,Y2*x,Y2*x,Y2*x,m ")
3055 (match_operand:DF 1 "general_operand"
3056 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3057 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3058 && (!can_create_pseudo_p ()
3059 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3060 || GET_CODE (operands[1]) != CONST_DOUBLE
3061 || (optimize_function_for_size_p (cfun)
3062 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3063 && standard_80387_constant_p (operands[1]) > 0)
3064 || (TARGET_SSE2 && TARGET_SSE_MATH
3065 && standard_sse_constant_p (operands[1])))
3066 && !memory_operand (operands[0], DFmode))
3067 || (!TARGET_MEMORY_MISMATCH_STALL
3068 && memory_operand (operands[0], DFmode)))"
3069 {
3070 switch (which_alternative)
3071 {
3072 case 0:
3073 case 1:
3074 return output_387_reg_move (insn, operands);
3075
3076 case 2:
3077 return standard_80387_constant_opcode (operands[1]);
3078
3079 case 3:
3080 case 4:
3081 return "#";
3082
3083 case 5:
3084 return standard_sse_constant_opcode (insn, operands[1]);
3085
3086 case 6:
3087 case 7:
3088 case 8:
3089 switch (get_attr_mode (insn))
3090 {
3091 case MODE_V2DF:
3092 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093 return "%vmovapd\t{%1, %0|%0, %1}";
3094 case MODE_V4SF:
3095 return "%vmovaps\t{%1, %0|%0, %1}";
3096
3097 case MODE_DI:
3098 return "%vmovq\t{%1, %0|%0, %1}";
3099 case MODE_DF:
3100 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3101 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3102 return "%vmovsd\t{%1, %0|%0, %1}";
3103 case MODE_V1DF:
3104 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3105 case MODE_V2SF:
3106 return "%vmovlps\t{%1, %d0|%d0, %1}";
3107 default:
3108 gcc_unreachable ();
3109 }
3110
3111 default:
3112 gcc_unreachable ();
3113 }
3114 }
3115 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3116 (set (attr "prefix")
3117 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3118 (const_string "orig")
3119 (const_string "maybe_vex")))
3120 (set (attr "prefix_data16")
3121 (if_then_else (eq_attr "mode" "V1DF")
3122 (const_string "1")
3123 (const_string "*")))
3124 (set (attr "mode")
3125 (cond [(eq_attr "alternative" "0,1,2")
3126 (const_string "DF")
3127 (eq_attr "alternative" "3,4")
3128 (const_string "SI")
3129
3130 /* For SSE1, we have many fewer alternatives. */
3131 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3132 (if_then_else
3133 (eq_attr "alternative" "5,6")
3134 (const_string "V4SF")
3135 (const_string "V2SF"))
3136
3137 /* xorps is one byte shorter. */
3138 (eq_attr "alternative" "5")
3139 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3140 (const_int 0))
3141 (const_string "V4SF")
3142 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3143 (const_int 0))
3144 (const_string "TI")
3145 ]
3146 (const_string "V2DF"))
3147
3148 /* For architectures resolving dependencies on
3149 whole SSE registers use APD move to break dependency
3150 chains, otherwise use short move to avoid extra work.
3151
3152 movaps encodes one byte shorter. */
3153 (eq_attr "alternative" "6")
3154 (cond
3155 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3156 (const_int 0))
3157 (const_string "V4SF")
3158 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3159 (const_int 0))
3160 (const_string "V2DF")
3161 ]
3162 (const_string "DF"))
3163 /* For architectures resolving dependencies on register
3164 parts we may avoid extra work to zero out upper part
3165 of register. */
3166 (eq_attr "alternative" "7")
3167 (if_then_else
3168 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3169 (const_int 0))
3170 (const_string "V1DF")
3171 (const_string "DF"))
3172 ]
3173 (const_string "DF")))])
3174
3175 (define_insn "*movsf_internal"
3176 [(set (match_operand:SF 0 "nonimmediate_operand"
3177 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3178 (match_operand:SF 1 "general_operand"
3179 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3180 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3181 && (!can_create_pseudo_p ()
3182 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3183 || GET_CODE (operands[1]) != CONST_DOUBLE
3184 || (optimize_function_for_size_p (cfun)
3185 && ((!TARGET_SSE_MATH
3186 && standard_80387_constant_p (operands[1]) > 0)
3187 || (TARGET_SSE_MATH
3188 && standard_sse_constant_p (operands[1]))))
3189 || memory_operand (operands[0], SFmode))"
3190 {
3191 switch (which_alternative)
3192 {
3193 case 0:
3194 case 1:
3195 return output_387_reg_move (insn, operands);
3196
3197 case 2:
3198 return standard_80387_constant_opcode (operands[1]);
3199
3200 case 3:
3201 case 4:
3202 return "mov{l}\t{%1, %0|%0, %1}";
3203
3204 case 5:
3205 return standard_sse_constant_opcode (insn, operands[1]);
3206
3207 case 6:
3208 if (get_attr_mode (insn) == MODE_V4SF)
3209 return "%vmovaps\t{%1, %0|%0, %1}";
3210 if (TARGET_AVX)
3211 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3212
3213 case 7:
3214 case 8:
3215 return "%vmovss\t{%1, %0|%0, %1}";
3216
3217 case 9:
3218 case 10:
3219 case 14:
3220 case 15:
3221 return "movd\t{%1, %0|%0, %1}";
3222
3223 case 11:
3224 return "movq\t{%1, %0|%0, %1}";
3225
3226 case 12:
3227 case 13:
3228 return "%vmovd\t{%1, %0|%0, %1}";
3229
3230 default:
3231 gcc_unreachable ();
3232 }
3233 }
3234 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3235 (set (attr "prefix")
3236 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3237 (const_string "maybe_vex")
3238 (const_string "orig")))
3239 (set (attr "mode")
3240 (cond [(eq_attr "alternative" "3,4,9,10")
3241 (const_string "SI")
3242 (eq_attr "alternative" "5")
3243 (if_then_else
3244 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3245 (const_int 0))
3246 (ne (symbol_ref "TARGET_SSE2")
3247 (const_int 0)))
3248 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3249 (const_int 0)))
3250 (const_string "TI")
3251 (const_string "V4SF"))
3252 /* For architectures resolving dependencies on
3253 whole SSE registers use APS move to break dependency
3254 chains, otherwise use short move to avoid extra work.
3255
3256 Do the same for architectures resolving dependencies on
3257 the parts. While in DF mode it is better to always handle
3258 just register parts, the SF mode is different due to lack
3259 of instructions to load just part of the register. It is
3260 better to maintain the whole registers in single format
3261 to avoid problems on using packed logical operations. */
3262 (eq_attr "alternative" "6")
3263 (if_then_else
3264 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3265 (const_int 0))
3266 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3267 (const_int 0)))
3268 (const_string "V4SF")
3269 (const_string "SF"))
3270 (eq_attr "alternative" "11")
3271 (const_string "DI")]
3272 (const_string "SF")))])
3273
3274 (define_split
3275 [(set (match_operand 0 "any_fp_register_operand" "")
3276 (match_operand 1 "memory_operand" ""))]
3277 "reload_completed
3278 && (GET_MODE (operands[0]) == TFmode
3279 || GET_MODE (operands[0]) == XFmode
3280 || GET_MODE (operands[0]) == DFmode
3281 || GET_MODE (operands[0]) == SFmode)
3282 && (operands[2] = find_constant_src (insn))"
3283 [(set (match_dup 0) (match_dup 2))]
3284 {
3285 rtx c = operands[2];
3286 int r = REGNO (operands[0]);
3287
3288 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3289 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3290 FAIL;
3291 })
3292
3293 (define_split
3294 [(set (match_operand 0 "any_fp_register_operand" "")
3295 (float_extend (match_operand 1 "memory_operand" "")))]
3296 "reload_completed
3297 && (GET_MODE (operands[0]) == TFmode
3298 || GET_MODE (operands[0]) == XFmode
3299 || GET_MODE (operands[0]) == DFmode)
3300 && (operands[2] = find_constant_src (insn))"
3301 [(set (match_dup 0) (match_dup 2))]
3302 {
3303 rtx c = operands[2];
3304 int r = REGNO (operands[0]);
3305
3306 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3307 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3308 FAIL;
3309 })
3310
3311 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3312 (define_split
3313 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3314 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3315 "reload_completed
3316 && (standard_80387_constant_p (operands[1]) == 8
3317 || standard_80387_constant_p (operands[1]) == 9)"
3318 [(set (match_dup 0)(match_dup 1))
3319 (set (match_dup 0)
3320 (neg:X87MODEF (match_dup 0)))]
3321 {
3322 REAL_VALUE_TYPE r;
3323
3324 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3325 if (real_isnegzero (&r))
3326 operands[1] = CONST0_RTX (<MODE>mode);
3327 else
3328 operands[1] = CONST1_RTX (<MODE>mode);
3329 })
3330
3331 (define_split
3332 [(set (match_operand 0 "nonimmediate_operand" "")
3333 (match_operand 1 "general_operand" ""))]
3334 "reload_completed
3335 && (GET_MODE (operands[0]) == TFmode
3336 || GET_MODE (operands[0]) == XFmode
3337 || GET_MODE (operands[0]) == DFmode)
3338 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3339 [(const_int 0)]
3340 "ix86_split_long_move (operands); DONE;")
3341
3342 (define_insn "swapxf"
3343 [(set (match_operand:XF 0 "register_operand" "+f")
3344 (match_operand:XF 1 "register_operand" "+f"))
3345 (set (match_dup 1)
3346 (match_dup 0))]
3347 "TARGET_80387"
3348 {
3349 if (STACK_TOP_P (operands[0]))
3350 return "fxch\t%1";
3351 else
3352 return "fxch\t%0";
3353 }
3354 [(set_attr "type" "fxch")
3355 (set_attr "mode" "XF")])
3356
3357 (define_insn "*swap<mode>"
3358 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3359 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3360 (set (match_dup 1)
3361 (match_dup 0))]
3362 "TARGET_80387 || reload_completed"
3363 {
3364 if (STACK_TOP_P (operands[0]))
3365 return "fxch\t%1";
3366 else
3367 return "fxch\t%0";
3368 }
3369 [(set_attr "type" "fxch")
3370 (set_attr "mode" "<MODE>")])
3371 \f
3372 ;; Zero extension instructions
3373
3374 (define_expand "zero_extendsidi2"
3375 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3376 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3377 ""
3378 {
3379 if (!TARGET_64BIT)
3380 {
3381 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3382 DONE;
3383 }
3384 })
3385
3386 (define_insn "*zero_extendsidi2_rex64"
3387 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3388 (zero_extend:DI
3389 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3390 "TARGET_64BIT"
3391 "@
3392 mov\t{%k1, %k0|%k0, %k1}
3393 #
3394 movd\t{%1, %0|%0, %1}
3395 movd\t{%1, %0|%0, %1}
3396 %vmovd\t{%1, %0|%0, %1}
3397 %vmovd\t{%1, %0|%0, %1}"
3398 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3399 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3400 (set_attr "prefix_0f" "0,*,*,*,*,*")
3401 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3402
3403 (define_split
3404 [(set (match_operand:DI 0 "memory_operand" "")
3405 (zero_extend:DI (match_dup 0)))]
3406 "TARGET_64BIT"
3407 [(set (match_dup 4) (const_int 0))]
3408 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3409
3410 ;; %%% Kill me once multi-word ops are sane.
3411 (define_insn "zero_extendsidi2_1"
3412 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3413 (zero_extend:DI
3414 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3415 (clobber (reg:CC FLAGS_REG))]
3416 "!TARGET_64BIT"
3417 "@
3418 #
3419 #
3420 #
3421 movd\t{%1, %0|%0, %1}
3422 movd\t{%1, %0|%0, %1}
3423 %vmovd\t{%1, %0|%0, %1}
3424 %vmovd\t{%1, %0|%0, %1}"
3425 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3426 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3427 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3428
3429 (define_split
3430 [(set (match_operand:DI 0 "register_operand" "")
3431 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3432 (clobber (reg:CC FLAGS_REG))]
3433 "!TARGET_64BIT && reload_completed
3434 && true_regnum (operands[0]) == true_regnum (operands[1])"
3435 [(set (match_dup 4) (const_int 0))]
3436 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3437
3438 (define_split
3439 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3440 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3441 (clobber (reg:CC FLAGS_REG))]
3442 "!TARGET_64BIT && reload_completed
3443 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3444 [(set (match_dup 3) (match_dup 1))
3445 (set (match_dup 4) (const_int 0))]
3446 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3447
3448 (define_insn "zero_extend<mode>di2"
3449 [(set (match_operand:DI 0 "register_operand" "=r")
3450 (zero_extend:DI
3451 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3452 "TARGET_64BIT"
3453 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3454 [(set_attr "type" "imovx")
3455 (set_attr "mode" "SI")])
3456
3457 (define_expand "zero_extendhisi2"
3458 [(set (match_operand:SI 0 "register_operand" "")
3459 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3460 ""
3461 {
3462 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3463 {
3464 operands[1] = force_reg (HImode, operands[1]);
3465 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3466 DONE;
3467 }
3468 })
3469
3470 (define_insn_and_split "zero_extendhisi2_and"
3471 [(set (match_operand:SI 0 "register_operand" "=r")
3472 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3473 (clobber (reg:CC FLAGS_REG))]
3474 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3475 "#"
3476 "&& reload_completed"
3477 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3478 (clobber (reg:CC FLAGS_REG))])]
3479 ""
3480 [(set_attr "type" "alu1")
3481 (set_attr "mode" "SI")])
3482
3483 (define_insn "*zero_extendhisi2_movzwl"
3484 [(set (match_operand:SI 0 "register_operand" "=r")
3485 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3486 "!TARGET_ZERO_EXTEND_WITH_AND
3487 || optimize_function_for_size_p (cfun)"
3488 "movz{wl|x}\t{%1, %0|%0, %1}"
3489 [(set_attr "type" "imovx")
3490 (set_attr "mode" "SI")])
3491
3492 (define_expand "zero_extendqi<mode>2"
3493 [(parallel
3494 [(set (match_operand:SWI24 0 "register_operand" "")
3495 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3496 (clobber (reg:CC FLAGS_REG))])])
3497
3498 (define_insn "*zero_extendqi<mode>2_and"
3499 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3500 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3501 (clobber (reg:CC FLAGS_REG))]
3502 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3503 "#"
3504 [(set_attr "type" "alu1")
3505 (set_attr "mode" "<MODE>")])
3506
3507 ;; When source and destination does not overlap, clear destination
3508 ;; first and then do the movb
3509 (define_split
3510 [(set (match_operand:SWI24 0 "register_operand" "")
3511 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3512 (clobber (reg:CC FLAGS_REG))]
3513 "reload_completed
3514 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3515 && ANY_QI_REG_P (operands[0])
3516 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3517 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3518 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3519 {
3520 operands[2] = gen_lowpart (QImode, operands[0]);
3521 ix86_expand_clear (operands[0]);
3522 })
3523
3524 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3525 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3526 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3527 (clobber (reg:CC FLAGS_REG))]
3528 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3529 "#"
3530 [(set_attr "type" "imovx,alu1")
3531 (set_attr "mode" "<MODE>")])
3532
3533 ;; For the movzbl case strip only the clobber
3534 (define_split
3535 [(set (match_operand:SWI24 0 "register_operand" "")
3536 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3537 (clobber (reg:CC FLAGS_REG))]
3538 "reload_completed
3539 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3540 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3541 [(set (match_dup 0)
3542 (zero_extend:SWI24 (match_dup 1)))])
3543
3544 ; zero extend to SImode to avoid partial register stalls
3545 (define_insn "*zero_extendqi<mode>2_movzbl"
3546 [(set (match_operand:SWI24 0 "register_operand" "=r")
3547 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3548 "reload_completed
3549 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3550 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3551 [(set_attr "type" "imovx")
3552 (set_attr "mode" "SI")])
3553
3554 ;; Rest is handled by single and.
3555 (define_split
3556 [(set (match_operand:SWI24 0 "register_operand" "")
3557 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3558 (clobber (reg:CC FLAGS_REG))]
3559 "reload_completed
3560 && true_regnum (operands[0]) == true_regnum (operands[1])"
3561 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3562 (clobber (reg:CC FLAGS_REG))])])
3563 \f
3564 ;; Sign extension instructions
3565
3566 (define_expand "extendsidi2"
3567 [(set (match_operand:DI 0 "register_operand" "")
3568 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3569 ""
3570 {
3571 if (!TARGET_64BIT)
3572 {
3573 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3574 DONE;
3575 }
3576 })
3577
3578 (define_insn "*extendsidi2_rex64"
3579 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3580 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3581 "TARGET_64BIT"
3582 "@
3583 {cltq|cdqe}
3584 movs{lq|x}\t{%1, %0|%0, %1}"
3585 [(set_attr "type" "imovx")
3586 (set_attr "mode" "DI")
3587 (set_attr "prefix_0f" "0")
3588 (set_attr "modrm" "0,1")])
3589
3590 (define_insn "extendsidi2_1"
3591 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3592 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3593 (clobber (reg:CC FLAGS_REG))
3594 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3595 "!TARGET_64BIT"
3596 "#")
3597
3598 ;; Extend to memory case when source register does die.
3599 (define_split
3600 [(set (match_operand:DI 0 "memory_operand" "")
3601 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3602 (clobber (reg:CC FLAGS_REG))
3603 (clobber (match_operand:SI 2 "register_operand" ""))]
3604 "(reload_completed
3605 && dead_or_set_p (insn, operands[1])
3606 && !reg_mentioned_p (operands[1], operands[0]))"
3607 [(set (match_dup 3) (match_dup 1))
3608 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3609 (clobber (reg:CC FLAGS_REG))])
3610 (set (match_dup 4) (match_dup 1))]
3611 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3612
3613 ;; Extend to memory case when source register does not die.
3614 (define_split
3615 [(set (match_operand:DI 0 "memory_operand" "")
3616 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3617 (clobber (reg:CC FLAGS_REG))
3618 (clobber (match_operand:SI 2 "register_operand" ""))]
3619 "reload_completed"
3620 [(const_int 0)]
3621 {
3622 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3623
3624 emit_move_insn (operands[3], operands[1]);
3625
3626 /* Generate a cltd if possible and doing so it profitable. */
3627 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3628 && true_regnum (operands[1]) == AX_REG
3629 && true_regnum (operands[2]) == DX_REG)
3630 {
3631 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3632 }
3633 else
3634 {
3635 emit_move_insn (operands[2], operands[1]);
3636 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3637 }
3638 emit_move_insn (operands[4], operands[2]);
3639 DONE;
3640 })
3641
3642 ;; Extend to register case. Optimize case where source and destination
3643 ;; registers match and cases where we can use cltd.
3644 (define_split
3645 [(set (match_operand:DI 0 "register_operand" "")
3646 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3647 (clobber (reg:CC FLAGS_REG))
3648 (clobber (match_scratch:SI 2 ""))]
3649 "reload_completed"
3650 [(const_int 0)]
3651 {
3652 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3653
3654 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3655 emit_move_insn (operands[3], operands[1]);
3656
3657 /* Generate a cltd if possible and doing so it profitable. */
3658 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3659 && true_regnum (operands[3]) == AX_REG
3660 && true_regnum (operands[4]) == DX_REG)
3661 {
3662 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3663 DONE;
3664 }
3665
3666 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3667 emit_move_insn (operands[4], operands[1]);
3668
3669 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3670 DONE;
3671 })
3672
3673 (define_insn "extend<mode>di2"
3674 [(set (match_operand:DI 0 "register_operand" "=r")
3675 (sign_extend:DI
3676 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3677 "TARGET_64BIT"
3678 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3679 [(set_attr "type" "imovx")
3680 (set_attr "mode" "DI")])
3681
3682 (define_insn "extendhisi2"
3683 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3684 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3685 ""
3686 {
3687 switch (get_attr_prefix_0f (insn))
3688 {
3689 case 0:
3690 return "{cwtl|cwde}";
3691 default:
3692 return "movs{wl|x}\t{%1, %0|%0, %1}";
3693 }
3694 }
3695 [(set_attr "type" "imovx")
3696 (set_attr "mode" "SI")
3697 (set (attr "prefix_0f")
3698 ;; movsx is short decodable while cwtl is vector decoded.
3699 (if_then_else (and (eq_attr "cpu" "!k6")
3700 (eq_attr "alternative" "0"))
3701 (const_string "0")
3702 (const_string "1")))
3703 (set (attr "modrm")
3704 (if_then_else (eq_attr "prefix_0f" "0")
3705 (const_string "0")
3706 (const_string "1")))])
3707
3708 (define_insn "*extendhisi2_zext"
3709 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3710 (zero_extend:DI
3711 (sign_extend:SI
3712 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3713 "TARGET_64BIT"
3714 {
3715 switch (get_attr_prefix_0f (insn))
3716 {
3717 case 0:
3718 return "{cwtl|cwde}";
3719 default:
3720 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3721 }
3722 }
3723 [(set_attr "type" "imovx")
3724 (set_attr "mode" "SI")
3725 (set (attr "prefix_0f")
3726 ;; movsx is short decodable while cwtl is vector decoded.
3727 (if_then_else (and (eq_attr "cpu" "!k6")
3728 (eq_attr "alternative" "0"))
3729 (const_string "0")
3730 (const_string "1")))
3731 (set (attr "modrm")
3732 (if_then_else (eq_attr "prefix_0f" "0")
3733 (const_string "0")
3734 (const_string "1")))])
3735
3736 (define_insn "extendqisi2"
3737 [(set (match_operand:SI 0 "register_operand" "=r")
3738 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3739 ""
3740 "movs{bl|x}\t{%1, %0|%0, %1}"
3741 [(set_attr "type" "imovx")
3742 (set_attr "mode" "SI")])
3743
3744 (define_insn "*extendqisi2_zext"
3745 [(set (match_operand:DI 0 "register_operand" "=r")
3746 (zero_extend:DI
3747 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3748 "TARGET_64BIT"
3749 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3750 [(set_attr "type" "imovx")
3751 (set_attr "mode" "SI")])
3752
3753 (define_insn "extendqihi2"
3754 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3755 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3756 ""
3757 {
3758 switch (get_attr_prefix_0f (insn))
3759 {
3760 case 0:
3761 return "{cbtw|cbw}";
3762 default:
3763 return "movs{bw|x}\t{%1, %0|%0, %1}";
3764 }
3765 }
3766 [(set_attr "type" "imovx")
3767 (set_attr "mode" "HI")
3768 (set (attr "prefix_0f")
3769 ;; movsx is short decodable while cwtl is vector decoded.
3770 (if_then_else (and (eq_attr "cpu" "!k6")
3771 (eq_attr "alternative" "0"))
3772 (const_string "0")
3773 (const_string "1")))
3774 (set (attr "modrm")
3775 (if_then_else (eq_attr "prefix_0f" "0")
3776 (const_string "0")
3777 (const_string "1")))])
3778 \f
3779 ;; Conversions between float and double.
3780
3781 ;; These are all no-ops in the model used for the 80387.
3782 ;; So just emit moves.
3783
3784 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3785 (define_split
3786 [(set (match_operand:DF 0 "push_operand" "")
3787 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3788 "reload_completed"
3789 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3790 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3791
3792 (define_split
3793 [(set (match_operand:XF 0 "push_operand" "")
3794 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3795 "reload_completed"
3796 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3797 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3798 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3799
3800 (define_expand "extendsfdf2"
3801 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3802 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3803 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3804 {
3805 /* ??? Needed for compress_float_constant since all fp constants
3806 are TARGET_LEGITIMATE_CONSTANT_P. */
3807 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3808 {
3809 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3810 && standard_80387_constant_p (operands[1]) > 0)
3811 {
3812 operands[1] = simplify_const_unary_operation
3813 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3814 emit_move_insn_1 (operands[0], operands[1]);
3815 DONE;
3816 }
3817 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3818 }
3819 })
3820
3821 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3822 cvtss2sd:
3823 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3824 cvtps2pd xmm2,xmm1
3825 We do the conversion post reload to avoid producing of 128bit spills
3826 that might lead to ICE on 32bit target. The sequence unlikely combine
3827 anyway. */
3828 (define_split
3829 [(set (match_operand:DF 0 "register_operand" "")
3830 (float_extend:DF
3831 (match_operand:SF 1 "nonimmediate_operand" "")))]
3832 "TARGET_USE_VECTOR_FP_CONVERTS
3833 && optimize_insn_for_speed_p ()
3834 && reload_completed && SSE_REG_P (operands[0])"
3835 [(set (match_dup 2)
3836 (float_extend:V2DF
3837 (vec_select:V2SF
3838 (match_dup 3)
3839 (parallel [(const_int 0) (const_int 1)]))))]
3840 {
3841 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3842 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3843 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3844 Try to avoid move when unpacking can be done in source. */
3845 if (REG_P (operands[1]))
3846 {
3847 /* If it is unsafe to overwrite upper half of source, we need
3848 to move to destination and unpack there. */
3849 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3850 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3851 && true_regnum (operands[0]) != true_regnum (operands[1]))
3852 {
3853 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3854 emit_move_insn (tmp, operands[1]);
3855 }
3856 else
3857 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3858 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3859 operands[3]));
3860 }
3861 else
3862 emit_insn (gen_vec_setv4sf_0 (operands[3],
3863 CONST0_RTX (V4SFmode), operands[1]));
3864 })
3865
3866 (define_insn "*extendsfdf2_mixed"
3867 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3868 (float_extend:DF
3869 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3870 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3871 {
3872 switch (which_alternative)
3873 {
3874 case 0:
3875 case 1:
3876 return output_387_reg_move (insn, operands);
3877
3878 case 2:
3879 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3880
3881 default:
3882 gcc_unreachable ();
3883 }
3884 }
3885 [(set_attr "type" "fmov,fmov,ssecvt")
3886 (set_attr "prefix" "orig,orig,maybe_vex")
3887 (set_attr "mode" "SF,XF,DF")])
3888
3889 (define_insn "*extendsfdf2_sse"
3890 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3891 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3892 "TARGET_SSE2 && TARGET_SSE_MATH"
3893 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3894 [(set_attr "type" "ssecvt")
3895 (set_attr "prefix" "maybe_vex")
3896 (set_attr "mode" "DF")])
3897
3898 (define_insn "*extendsfdf2_i387"
3899 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3900 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3901 "TARGET_80387"
3902 "* return output_387_reg_move (insn, operands);"
3903 [(set_attr "type" "fmov")
3904 (set_attr "mode" "SF,XF")])
3905
3906 (define_expand "extend<mode>xf2"
3907 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3908 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3909 "TARGET_80387"
3910 {
3911 /* ??? Needed for compress_float_constant since all fp constants
3912 are TARGET_LEGITIMATE_CONSTANT_P. */
3913 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3914 {
3915 if (standard_80387_constant_p (operands[1]) > 0)
3916 {
3917 operands[1] = simplify_const_unary_operation
3918 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3919 emit_move_insn_1 (operands[0], operands[1]);
3920 DONE;
3921 }
3922 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3923 }
3924 })
3925
3926 (define_insn "*extend<mode>xf2_i387"
3927 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3928 (float_extend:XF
3929 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3930 "TARGET_80387"
3931 "* return output_387_reg_move (insn, operands);"
3932 [(set_attr "type" "fmov")
3933 (set_attr "mode" "<MODE>,XF")])
3934
3935 ;; %%% This seems bad bad news.
3936 ;; This cannot output into an f-reg because there is no way to be sure
3937 ;; of truncating in that case. Otherwise this is just like a simple move
3938 ;; insn. So we pretend we can output to a reg in order to get better
3939 ;; register preferencing, but we really use a stack slot.
3940
3941 ;; Conversion from DFmode to SFmode.
3942
3943 (define_expand "truncdfsf2"
3944 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3945 (float_truncate:SF
3946 (match_operand:DF 1 "nonimmediate_operand" "")))]
3947 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3948 {
3949 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3950 ;
3951 else if (flag_unsafe_math_optimizations)
3952 ;
3953 else
3954 {
3955 enum ix86_stack_slot slot = (virtuals_instantiated
3956 ? SLOT_TEMP
3957 : SLOT_VIRTUAL);
3958 rtx temp = assign_386_stack_local (SFmode, slot);
3959 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3960 DONE;
3961 }
3962 })
3963
3964 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3965 cvtsd2ss:
3966 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3967 cvtpd2ps xmm2,xmm1
3968 We do the conversion post reload to avoid producing of 128bit spills
3969 that might lead to ICE on 32bit target. The sequence unlikely combine
3970 anyway. */
3971 (define_split
3972 [(set (match_operand:SF 0 "register_operand" "")
3973 (float_truncate:SF
3974 (match_operand:DF 1 "nonimmediate_operand" "")))]
3975 "TARGET_USE_VECTOR_FP_CONVERTS
3976 && optimize_insn_for_speed_p ()
3977 && reload_completed && SSE_REG_P (operands[0])"
3978 [(set (match_dup 2)
3979 (vec_concat:V4SF
3980 (float_truncate:V2SF
3981 (match_dup 4))
3982 (match_dup 3)))]
3983 {
3984 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3985 operands[3] = CONST0_RTX (V2SFmode);
3986 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3987 /* Use movsd for loading from memory, unpcklpd for registers.
3988 Try to avoid move when unpacking can be done in source, or SSE3
3989 movddup is available. */
3990 if (REG_P (operands[1]))
3991 {
3992 if (!TARGET_SSE3
3993 && true_regnum (operands[0]) != true_regnum (operands[1])
3994 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3995 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3996 {
3997 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3998 emit_move_insn (tmp, operands[1]);
3999 operands[1] = tmp;
4000 }
4001 else if (!TARGET_SSE3)
4002 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4003 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4004 }
4005 else
4006 emit_insn (gen_sse2_loadlpd (operands[4],
4007 CONST0_RTX (V2DFmode), operands[1]));
4008 })
4009
4010 (define_expand "truncdfsf2_with_temp"
4011 [(parallel [(set (match_operand:SF 0 "" "")
4012 (float_truncate:SF (match_operand:DF 1 "" "")))
4013 (clobber (match_operand:SF 2 "" ""))])])
4014
4015 (define_insn "*truncdfsf_fast_mixed"
4016 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4017 (float_truncate:SF
4018 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4019 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4020 {
4021 switch (which_alternative)
4022 {
4023 case 0:
4024 return output_387_reg_move (insn, operands);
4025 case 1:
4026 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4027 default:
4028 gcc_unreachable ();
4029 }
4030 }
4031 [(set_attr "type" "fmov,ssecvt")
4032 (set_attr "prefix" "orig,maybe_vex")
4033 (set_attr "mode" "SF")])
4034
4035 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4036 ;; because nothing we do here is unsafe.
4037 (define_insn "*truncdfsf_fast_sse"
4038 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4039 (float_truncate:SF
4040 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4041 "TARGET_SSE2 && TARGET_SSE_MATH"
4042 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4043 [(set_attr "type" "ssecvt")
4044 (set_attr "prefix" "maybe_vex")
4045 (set_attr "mode" "SF")])
4046
4047 (define_insn "*truncdfsf_fast_i387"
4048 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4049 (float_truncate:SF
4050 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4051 "TARGET_80387 && flag_unsafe_math_optimizations"
4052 "* return output_387_reg_move (insn, operands);"
4053 [(set_attr "type" "fmov")
4054 (set_attr "mode" "SF")])
4055
4056 (define_insn "*truncdfsf_mixed"
4057 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4058 (float_truncate:SF
4059 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4060 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4061 "TARGET_MIX_SSE_I387"
4062 {
4063 switch (which_alternative)
4064 {
4065 case 0:
4066 return output_387_reg_move (insn, operands);
4067 case 1:
4068 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4069
4070 default:
4071 return "#";
4072 }
4073 }
4074 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075 (set_attr "unit" "*,*,i387,i387,i387")
4076 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077 (set_attr "mode" "SF")])
4078
4079 (define_insn "*truncdfsf_i387"
4080 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4081 (float_truncate:SF
4082 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4084 "TARGET_80387"
4085 {
4086 switch (which_alternative)
4087 {
4088 case 0:
4089 return output_387_reg_move (insn, operands);
4090
4091 default:
4092 return "#";
4093 }
4094 }
4095 [(set_attr "type" "fmov,multi,multi,multi")
4096 (set_attr "unit" "*,i387,i387,i387")
4097 (set_attr "mode" "SF")])
4098
4099 (define_insn "*truncdfsf2_i387_1"
4100 [(set (match_operand:SF 0 "memory_operand" "=m")
4101 (float_truncate:SF
4102 (match_operand:DF 1 "register_operand" "f")))]
4103 "TARGET_80387
4104 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105 && !TARGET_MIX_SSE_I387"
4106 "* return output_387_reg_move (insn, operands);"
4107 [(set_attr "type" "fmov")
4108 (set_attr "mode" "SF")])
4109
4110 (define_split
4111 [(set (match_operand:SF 0 "register_operand" "")
4112 (float_truncate:SF
4113 (match_operand:DF 1 "fp_register_operand" "")))
4114 (clobber (match_operand 2 "" ""))]
4115 "reload_completed"
4116 [(set (match_dup 2) (match_dup 1))
4117 (set (match_dup 0) (match_dup 2))]
4118 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4119
4120 ;; Conversion from XFmode to {SF,DF}mode
4121
4122 (define_expand "truncxf<mode>2"
4123 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4124 (float_truncate:MODEF
4125 (match_operand:XF 1 "register_operand" "")))
4126 (clobber (match_dup 2))])]
4127 "TARGET_80387"
4128 {
4129 if (flag_unsafe_math_optimizations)
4130 {
4131 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4132 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4133 if (reg != operands[0])
4134 emit_move_insn (operands[0], reg);
4135 DONE;
4136 }
4137 else
4138 {
4139 enum ix86_stack_slot slot = (virtuals_instantiated
4140 ? SLOT_TEMP
4141 : SLOT_VIRTUAL);
4142 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4143 }
4144 })
4145
4146 (define_insn "*truncxfsf2_mixed"
4147 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4148 (float_truncate:SF
4149 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4150 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4151 "TARGET_80387"
4152 {
4153 gcc_assert (!which_alternative);
4154 return output_387_reg_move (insn, operands);
4155 }
4156 [(set_attr "type" "fmov,multi,multi,multi")
4157 (set_attr "unit" "*,i387,i387,i387")
4158 (set_attr "mode" "SF")])
4159
4160 (define_insn "*truncxfdf2_mixed"
4161 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4162 (float_truncate:DF
4163 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4164 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4165 "TARGET_80387"
4166 {
4167 gcc_assert (!which_alternative);
4168 return output_387_reg_move (insn, operands);
4169 }
4170 [(set_attr "type" "fmov,multi,multi,multi")
4171 (set_attr "unit" "*,i387,i387,i387")
4172 (set_attr "mode" "DF")])
4173
4174 (define_insn "truncxf<mode>2_i387_noop"
4175 [(set (match_operand:MODEF 0 "register_operand" "=f")
4176 (float_truncate:MODEF
4177 (match_operand:XF 1 "register_operand" "f")))]
4178 "TARGET_80387 && flag_unsafe_math_optimizations"
4179 "* return output_387_reg_move (insn, operands);"
4180 [(set_attr "type" "fmov")
4181 (set_attr "mode" "<MODE>")])
4182
4183 (define_insn "*truncxf<mode>2_i387"
4184 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4185 (float_truncate:MODEF
4186 (match_operand:XF 1 "register_operand" "f")))]
4187 "TARGET_80387"
4188 "* return output_387_reg_move (insn, operands);"
4189 [(set_attr "type" "fmov")
4190 (set_attr "mode" "<MODE>")])
4191
4192 (define_split
4193 [(set (match_operand:MODEF 0 "register_operand" "")
4194 (float_truncate:MODEF
4195 (match_operand:XF 1 "register_operand" "")))
4196 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4197 "TARGET_80387 && reload_completed"
4198 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4199 (set (match_dup 0) (match_dup 2))])
4200
4201 (define_split
4202 [(set (match_operand:MODEF 0 "memory_operand" "")
4203 (float_truncate:MODEF
4204 (match_operand:XF 1 "register_operand" "")))
4205 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4206 "TARGET_80387"
4207 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4208 \f
4209 ;; Signed conversion to DImode.
4210
4211 (define_expand "fix_truncxfdi2"
4212 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4213 (fix:DI (match_operand:XF 1 "register_operand" "")))
4214 (clobber (reg:CC FLAGS_REG))])]
4215 "TARGET_80387"
4216 {
4217 if (TARGET_FISTTP)
4218 {
4219 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4220 DONE;
4221 }
4222 })
4223
4224 (define_expand "fix_trunc<mode>di2"
4225 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4226 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4227 (clobber (reg:CC FLAGS_REG))])]
4228 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4229 {
4230 if (TARGET_FISTTP
4231 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4232 {
4233 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4234 DONE;
4235 }
4236 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4237 {
4238 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4239 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4240 if (out != operands[0])
4241 emit_move_insn (operands[0], out);
4242 DONE;
4243 }
4244 })
4245
4246 ;; Signed conversion to SImode.
4247
4248 (define_expand "fix_truncxfsi2"
4249 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4250 (fix:SI (match_operand:XF 1 "register_operand" "")))
4251 (clobber (reg:CC FLAGS_REG))])]
4252 "TARGET_80387"
4253 {
4254 if (TARGET_FISTTP)
4255 {
4256 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4257 DONE;
4258 }
4259 })
4260
4261 (define_expand "fix_trunc<mode>si2"
4262 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4263 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4264 (clobber (reg:CC FLAGS_REG))])]
4265 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4266 {
4267 if (TARGET_FISTTP
4268 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4269 {
4270 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4271 DONE;
4272 }
4273 if (SSE_FLOAT_MODE_P (<MODE>mode))
4274 {
4275 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4276 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4277 if (out != operands[0])
4278 emit_move_insn (operands[0], out);
4279 DONE;
4280 }
4281 })
4282
4283 ;; Signed conversion to HImode.
4284
4285 (define_expand "fix_trunc<mode>hi2"
4286 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4287 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4288 (clobber (reg:CC FLAGS_REG))])]
4289 "TARGET_80387
4290 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4291 {
4292 if (TARGET_FISTTP)
4293 {
4294 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4295 DONE;
4296 }
4297 })
4298
4299 ;; Unsigned conversion to SImode.
4300
4301 (define_expand "fixuns_trunc<mode>si2"
4302 [(parallel
4303 [(set (match_operand:SI 0 "register_operand" "")
4304 (unsigned_fix:SI
4305 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4306 (use (match_dup 2))
4307 (clobber (match_scratch:<ssevecmode> 3 ""))
4308 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4309 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4310 {
4311 enum machine_mode mode = <MODE>mode;
4312 enum machine_mode vecmode = <ssevecmode>mode;
4313 REAL_VALUE_TYPE TWO31r;
4314 rtx two31;
4315
4316 if (optimize_insn_for_size_p ())
4317 FAIL;
4318
4319 real_ldexp (&TWO31r, &dconst1, 31);
4320 two31 = const_double_from_real_value (TWO31r, mode);
4321 two31 = ix86_build_const_vector (vecmode, true, two31);
4322 operands[2] = force_reg (vecmode, two31);
4323 })
4324
4325 (define_insn_and_split "*fixuns_trunc<mode>_1"
4326 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4327 (unsigned_fix:SI
4328 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4329 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4330 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4331 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4332 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4333 && optimize_function_for_speed_p (cfun)"
4334 "#"
4335 "&& reload_completed"
4336 [(const_int 0)]
4337 {
4338 ix86_split_convert_uns_si_sse (operands);
4339 DONE;
4340 })
4341
4342 ;; Unsigned conversion to HImode.
4343 ;; Without these patterns, we'll try the unsigned SI conversion which
4344 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4345
4346 (define_expand "fixuns_trunc<mode>hi2"
4347 [(set (match_dup 2)
4348 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4349 (set (match_operand:HI 0 "nonimmediate_operand" "")
4350 (subreg:HI (match_dup 2) 0))]
4351 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4352 "operands[2] = gen_reg_rtx (SImode);")
4353
4354 ;; When SSE is available, it is always faster to use it!
4355 (define_insn "fix_trunc<mode>di_sse"
4356 [(set (match_operand:DI 0 "register_operand" "=r,r")
4357 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4358 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4359 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4360 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4361 [(set_attr "type" "sseicvt")
4362 (set_attr "prefix" "maybe_vex")
4363 (set_attr "prefix_rex" "1")
4364 (set_attr "mode" "<MODE>")
4365 (set_attr "athlon_decode" "double,vector")
4366 (set_attr "amdfam10_decode" "double,double")
4367 (set_attr "bdver1_decode" "double,double")])
4368
4369 (define_insn "fix_trunc<mode>si_sse"
4370 [(set (match_operand:SI 0 "register_operand" "=r,r")
4371 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4372 "SSE_FLOAT_MODE_P (<MODE>mode)
4373 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4374 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4375 [(set_attr "type" "sseicvt")
4376 (set_attr "prefix" "maybe_vex")
4377 (set_attr "mode" "<MODE>")
4378 (set_attr "athlon_decode" "double,vector")
4379 (set_attr "amdfam10_decode" "double,double")
4380 (set_attr "bdver1_decode" "double,double")])
4381
4382 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4383 (define_peephole2
4384 [(set (match_operand:MODEF 0 "register_operand" "")
4385 (match_operand:MODEF 1 "memory_operand" ""))
4386 (set (match_operand:SWI48x 2 "register_operand" "")
4387 (fix:SWI48x (match_dup 0)))]
4388 "TARGET_SHORTEN_X87_SSE
4389 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4390 && peep2_reg_dead_p (2, operands[0])"
4391 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4392
4393 ;; Avoid vector decoded forms of the instruction.
4394 (define_peephole2
4395 [(match_scratch:DF 2 "Y2")
4396 (set (match_operand:SWI48x 0 "register_operand" "")
4397 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4398 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4399 [(set (match_dup 2) (match_dup 1))
4400 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4401
4402 (define_peephole2
4403 [(match_scratch:SF 2 "x")
4404 (set (match_operand:SWI48x 0 "register_operand" "")
4405 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4406 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4407 [(set (match_dup 2) (match_dup 1))
4408 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4409
4410 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4411 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4412 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4413 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4414 && TARGET_FISTTP
4415 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4416 && (TARGET_64BIT || <MODE>mode != DImode))
4417 && TARGET_SSE_MATH)
4418 && can_create_pseudo_p ()"
4419 "#"
4420 "&& 1"
4421 [(const_int 0)]
4422 {
4423 if (memory_operand (operands[0], VOIDmode))
4424 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4425 else
4426 {
4427 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4428 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4429 operands[1],
4430 operands[2]));
4431 }
4432 DONE;
4433 }
4434 [(set_attr "type" "fisttp")
4435 (set_attr "mode" "<MODE>")])
4436
4437 (define_insn "fix_trunc<mode>_i387_fisttp"
4438 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4439 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4440 (clobber (match_scratch:XF 2 "=&1f"))]
4441 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4442 && TARGET_FISTTP
4443 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && (TARGET_64BIT || <MODE>mode != DImode))
4445 && TARGET_SSE_MATH)"
4446 "* return output_fix_trunc (insn, operands, true);"
4447 [(set_attr "type" "fisttp")
4448 (set_attr "mode" "<MODE>")])
4449
4450 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4451 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4452 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4453 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4454 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4455 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4456 && TARGET_FISTTP
4457 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4458 && (TARGET_64BIT || <MODE>mode != DImode))
4459 && TARGET_SSE_MATH)"
4460 "#"
4461 [(set_attr "type" "fisttp")
4462 (set_attr "mode" "<MODE>")])
4463
4464 (define_split
4465 [(set (match_operand:SWI248x 0 "register_operand" "")
4466 (fix:SWI248x (match_operand 1 "register_operand" "")))
4467 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4468 (clobber (match_scratch 3 ""))]
4469 "reload_completed"
4470 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4471 (clobber (match_dup 3))])
4472 (set (match_dup 0) (match_dup 2))])
4473
4474 (define_split
4475 [(set (match_operand:SWI248x 0 "memory_operand" "")
4476 (fix:SWI248x (match_operand 1 "register_operand" "")))
4477 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4478 (clobber (match_scratch 3 ""))]
4479 "reload_completed"
4480 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4481 (clobber (match_dup 3))])])
4482
4483 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4484 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4485 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4486 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4487 ;; function in i386.c.
4488 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4489 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4490 (fix:SWI248x (match_operand 1 "register_operand" "")))
4491 (clobber (reg:CC FLAGS_REG))]
4492 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4493 && !TARGET_FISTTP
4494 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && (TARGET_64BIT || <MODE>mode != DImode))
4496 && can_create_pseudo_p ()"
4497 "#"
4498 "&& 1"
4499 [(const_int 0)]
4500 {
4501 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4502
4503 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4504 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4505 if (memory_operand (operands[0], VOIDmode))
4506 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4507 operands[2], operands[3]));
4508 else
4509 {
4510 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4511 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4512 operands[2], operands[3],
4513 operands[4]));
4514 }
4515 DONE;
4516 }
4517 [(set_attr "type" "fistp")
4518 (set_attr "i387_cw" "trunc")
4519 (set_attr "mode" "<MODE>")])
4520
4521 (define_insn "fix_truncdi_i387"
4522 [(set (match_operand:DI 0 "memory_operand" "=m")
4523 (fix:DI (match_operand 1 "register_operand" "f")))
4524 (use (match_operand:HI 2 "memory_operand" "m"))
4525 (use (match_operand:HI 3 "memory_operand" "m"))
4526 (clobber (match_scratch:XF 4 "=&1f"))]
4527 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528 && !TARGET_FISTTP
4529 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4530 "* return output_fix_trunc (insn, operands, false);"
4531 [(set_attr "type" "fistp")
4532 (set_attr "i387_cw" "trunc")
4533 (set_attr "mode" "DI")])
4534
4535 (define_insn "fix_truncdi_i387_with_temp"
4536 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4537 (fix:DI (match_operand 1 "register_operand" "f,f")))
4538 (use (match_operand:HI 2 "memory_operand" "m,m"))
4539 (use (match_operand:HI 3 "memory_operand" "m,m"))
4540 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4541 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4542 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4543 && !TARGET_FISTTP
4544 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4545 "#"
4546 [(set_attr "type" "fistp")
4547 (set_attr "i387_cw" "trunc")
4548 (set_attr "mode" "DI")])
4549
4550 (define_split
4551 [(set (match_operand:DI 0 "register_operand" "")
4552 (fix:DI (match_operand 1 "register_operand" "")))
4553 (use (match_operand:HI 2 "memory_operand" ""))
4554 (use (match_operand:HI 3 "memory_operand" ""))
4555 (clobber (match_operand:DI 4 "memory_operand" ""))
4556 (clobber (match_scratch 5 ""))]
4557 "reload_completed"
4558 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4559 (use (match_dup 2))
4560 (use (match_dup 3))
4561 (clobber (match_dup 5))])
4562 (set (match_dup 0) (match_dup 4))])
4563
4564 (define_split
4565 [(set (match_operand:DI 0 "memory_operand" "")
4566 (fix:DI (match_operand 1 "register_operand" "")))
4567 (use (match_operand:HI 2 "memory_operand" ""))
4568 (use (match_operand:HI 3 "memory_operand" ""))
4569 (clobber (match_operand:DI 4 "memory_operand" ""))
4570 (clobber (match_scratch 5 ""))]
4571 "reload_completed"
4572 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4573 (use (match_dup 2))
4574 (use (match_dup 3))
4575 (clobber (match_dup 5))])])
4576
4577 (define_insn "fix_trunc<mode>_i387"
4578 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4579 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4580 (use (match_operand:HI 2 "memory_operand" "m"))
4581 (use (match_operand:HI 3 "memory_operand" "m"))]
4582 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583 && !TARGET_FISTTP
4584 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4585 "* return output_fix_trunc (insn, operands, false);"
4586 [(set_attr "type" "fistp")
4587 (set_attr "i387_cw" "trunc")
4588 (set_attr "mode" "<MODE>")])
4589
4590 (define_insn "fix_trunc<mode>_i387_with_temp"
4591 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4592 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4593 (use (match_operand:HI 2 "memory_operand" "m,m"))
4594 (use (match_operand:HI 3 "memory_operand" "m,m"))
4595 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4596 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4597 && !TARGET_FISTTP
4598 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4599 "#"
4600 [(set_attr "type" "fistp")
4601 (set_attr "i387_cw" "trunc")
4602 (set_attr "mode" "<MODE>")])
4603
4604 (define_split
4605 [(set (match_operand:SWI24 0 "register_operand" "")
4606 (fix:SWI24 (match_operand 1 "register_operand" "")))
4607 (use (match_operand:HI 2 "memory_operand" ""))
4608 (use (match_operand:HI 3 "memory_operand" ""))
4609 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4610 "reload_completed"
4611 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4612 (use (match_dup 2))
4613 (use (match_dup 3))])
4614 (set (match_dup 0) (match_dup 4))])
4615
4616 (define_split
4617 [(set (match_operand:SWI24 0 "memory_operand" "")
4618 (fix:SWI24 (match_operand 1 "register_operand" "")))
4619 (use (match_operand:HI 2 "memory_operand" ""))
4620 (use (match_operand:HI 3 "memory_operand" ""))
4621 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4622 "reload_completed"
4623 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4624 (use (match_dup 2))
4625 (use (match_dup 3))])])
4626
4627 (define_insn "x86_fnstcw_1"
4628 [(set (match_operand:HI 0 "memory_operand" "=m")
4629 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4630 "TARGET_80387"
4631 "fnstcw\t%0"
4632 [(set (attr "length")
4633 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4634 (set_attr "mode" "HI")
4635 (set_attr "unit" "i387")
4636 (set_attr "bdver1_decode" "vector")])
4637
4638 (define_insn "x86_fldcw_1"
4639 [(set (reg:HI FPCR_REG)
4640 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4641 "TARGET_80387"
4642 "fldcw\t%0"
4643 [(set (attr "length")
4644 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4645 (set_attr "mode" "HI")
4646 (set_attr "unit" "i387")
4647 (set_attr "athlon_decode" "vector")
4648 (set_attr "amdfam10_decode" "vector")
4649 (set_attr "bdver1_decode" "vector")])
4650 \f
4651 ;; Conversion between fixed point and floating point.
4652
4653 ;; Even though we only accept memory inputs, the backend _really_
4654 ;; wants to be able to do this between registers.
4655
4656 (define_expand "floathi<mode>2"
4657 [(set (match_operand:X87MODEF 0 "register_operand" "")
4658 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4659 "TARGET_80387
4660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4661 || TARGET_MIX_SSE_I387)")
4662
4663 ;; Pre-reload splitter to add memory clobber to the pattern.
4664 (define_insn_and_split "*floathi<mode>2_1"
4665 [(set (match_operand:X87MODEF 0 "register_operand" "")
4666 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4667 "TARGET_80387
4668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4669 || TARGET_MIX_SSE_I387)
4670 && can_create_pseudo_p ()"
4671 "#"
4672 "&& 1"
4673 [(parallel [(set (match_dup 0)
4674 (float:X87MODEF (match_dup 1)))
4675 (clobber (match_dup 2))])]
4676 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4677
4678 (define_insn "*floathi<mode>2_i387_with_temp"
4679 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4680 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4681 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4682 "TARGET_80387
4683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4684 || TARGET_MIX_SSE_I387)"
4685 "#"
4686 [(set_attr "type" "fmov,multi")
4687 (set_attr "mode" "<MODE>")
4688 (set_attr "unit" "*,i387")
4689 (set_attr "fp_int_src" "true")])
4690
4691 (define_insn "*floathi<mode>2_i387"
4692 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4693 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4694 "TARGET_80387
4695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4696 || TARGET_MIX_SSE_I387)"
4697 "fild%Z1\t%1"
4698 [(set_attr "type" "fmov")
4699 (set_attr "mode" "<MODE>")
4700 (set_attr "fp_int_src" "true")])
4701
4702 (define_split
4703 [(set (match_operand:X87MODEF 0 "register_operand" "")
4704 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4705 (clobber (match_operand:HI 2 "memory_operand" ""))]
4706 "TARGET_80387
4707 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4708 || TARGET_MIX_SSE_I387)
4709 && reload_completed"
4710 [(set (match_dup 2) (match_dup 1))
4711 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4712
4713 (define_split
4714 [(set (match_operand:X87MODEF 0 "register_operand" "")
4715 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4716 (clobber (match_operand:HI 2 "memory_operand" ""))]
4717 "TARGET_80387
4718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4719 || TARGET_MIX_SSE_I387)
4720 && reload_completed"
4721 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4722
4723 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4724 [(set (match_operand:X87MODEF 0 "register_operand" "")
4725 (float:X87MODEF
4726 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4727 "TARGET_80387
4728 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4729 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4730 {
4731 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4732 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4733 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4734 {
4735 rtx reg = gen_reg_rtx (XFmode);
4736 rtx (*insn)(rtx, rtx);
4737
4738 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4739
4740 if (<X87MODEF:MODE>mode == SFmode)
4741 insn = gen_truncxfsf2;
4742 else if (<X87MODEF:MODE>mode == DFmode)
4743 insn = gen_truncxfdf2;
4744 else
4745 gcc_unreachable ();
4746
4747 emit_insn (insn (operands[0], reg));
4748 DONE;
4749 }
4750 })
4751
4752 ;; Pre-reload splitter to add memory clobber to the pattern.
4753 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4754 [(set (match_operand:X87MODEF 0 "register_operand" "")
4755 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4756 "((TARGET_80387
4757 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4758 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4759 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4760 || TARGET_MIX_SSE_I387))
4761 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4762 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4763 && ((<SWI48x:MODE>mode == SImode
4764 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4765 && optimize_function_for_speed_p (cfun)
4766 && flag_trapping_math)
4767 || !(TARGET_INTER_UNIT_CONVERSIONS
4768 || optimize_function_for_size_p (cfun)))))
4769 && can_create_pseudo_p ()"
4770 "#"
4771 "&& 1"
4772 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4773 (clobber (match_dup 2))])]
4774 {
4775 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4776
4777 /* Avoid store forwarding (partial memory) stall penalty
4778 by passing DImode value through XMM registers. */
4779 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4780 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4781 && optimize_function_for_speed_p (cfun))
4782 {
4783 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4784 operands[1],
4785 operands[2]));
4786 DONE;
4787 }
4788 })
4789
4790 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4791 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4792 (float:MODEF
4793 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4794 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4795 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4796 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4797 "#"
4798 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4799 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4800 (set_attr "unit" "*,i387,*,*,*")
4801 (set_attr "athlon_decode" "*,*,double,direct,double")
4802 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4803 (set_attr "bdver1_decode" "*,*,double,direct,double")
4804 (set_attr "fp_int_src" "true")])
4805
4806 (define_insn "*floatsi<mode>2_vector_mixed"
4807 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4808 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4809 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4810 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4811 "@
4812 fild%Z1\t%1
4813 #"
4814 [(set_attr "type" "fmov,sseicvt")
4815 (set_attr "mode" "<MODE>,<ssevecmode>")
4816 (set_attr "unit" "i387,*")
4817 (set_attr "athlon_decode" "*,direct")
4818 (set_attr "amdfam10_decode" "*,double")
4819 (set_attr "bdver1_decode" "*,direct")
4820 (set_attr "fp_int_src" "true")])
4821
4822 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4823 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4824 (float:MODEF
4825 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4826 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4827 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4828 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4829 "#"
4830 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4831 (set_attr "mode" "<MODEF:MODE>")
4832 (set_attr "unit" "*,i387,*,*")
4833 (set_attr "athlon_decode" "*,*,double,direct")
4834 (set_attr "amdfam10_decode" "*,*,vector,double")
4835 (set_attr "bdver1_decode" "*,*,double,direct")
4836 (set_attr "fp_int_src" "true")])
4837
4838 (define_split
4839 [(set (match_operand:MODEF 0 "register_operand" "")
4840 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4841 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4842 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4843 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4844 && TARGET_INTER_UNIT_CONVERSIONS
4845 && reload_completed
4846 && (SSE_REG_P (operands[0])
4847 || (GET_CODE (operands[0]) == SUBREG
4848 && SSE_REG_P (operands[0])))"
4849 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4850
4851 (define_split
4852 [(set (match_operand:MODEF 0 "register_operand" "")
4853 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4854 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4855 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4856 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4857 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4858 && reload_completed
4859 && (SSE_REG_P (operands[0])
4860 || (GET_CODE (operands[0]) == SUBREG
4861 && SSE_REG_P (operands[0])))"
4862 [(set (match_dup 2) (match_dup 1))
4863 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4864
4865 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4866 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4867 (float:MODEF
4868 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4869 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4870 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4871 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4872 "@
4873 fild%Z1\t%1
4874 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4875 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4876 [(set_attr "type" "fmov,sseicvt,sseicvt")
4877 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4878 (set_attr "mode" "<MODEF:MODE>")
4879 (set (attr "prefix_rex")
4880 (if_then_else
4881 (and (eq_attr "prefix" "maybe_vex")
4882 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4883 (const_string "1")
4884 (const_string "*")))
4885 (set_attr "unit" "i387,*,*")
4886 (set_attr "athlon_decode" "*,double,direct")
4887 (set_attr "amdfam10_decode" "*,vector,double")
4888 (set_attr "bdver1_decode" "*,double,direct")
4889 (set_attr "fp_int_src" "true")])
4890
4891 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4892 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4893 (float:MODEF
4894 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4895 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4896 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4897 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4898 "@
4899 fild%Z1\t%1
4900 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4901 [(set_attr "type" "fmov,sseicvt")
4902 (set_attr "prefix" "orig,maybe_vex")
4903 (set_attr "mode" "<MODEF:MODE>")
4904 (set (attr "prefix_rex")
4905 (if_then_else
4906 (and (eq_attr "prefix" "maybe_vex")
4907 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4908 (const_string "1")
4909 (const_string "*")))
4910 (set_attr "athlon_decode" "*,direct")
4911 (set_attr "amdfam10_decode" "*,double")
4912 (set_attr "bdver1_decode" "*,direct")
4913 (set_attr "fp_int_src" "true")])
4914
4915 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4916 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4917 (float:MODEF
4918 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4919 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4920 "TARGET_SSE2 && TARGET_SSE_MATH
4921 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4922 "#"
4923 [(set_attr "type" "sseicvt")
4924 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4925 (set_attr "athlon_decode" "double,direct,double")
4926 (set_attr "amdfam10_decode" "vector,double,double")
4927 (set_attr "bdver1_decode" "double,direct,double")
4928 (set_attr "fp_int_src" "true")])
4929
4930 (define_insn "*floatsi<mode>2_vector_sse"
4931 [(set (match_operand:MODEF 0 "register_operand" "=x")
4932 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4933 "TARGET_SSE2 && TARGET_SSE_MATH
4934 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4935 "#"
4936 [(set_attr "type" "sseicvt")
4937 (set_attr "mode" "<MODE>")
4938 (set_attr "athlon_decode" "direct")
4939 (set_attr "amdfam10_decode" "double")
4940 (set_attr "bdver1_decode" "direct")
4941 (set_attr "fp_int_src" "true")])
4942
4943 (define_split
4944 [(set (match_operand:MODEF 0 "register_operand" "")
4945 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4946 (clobber (match_operand:SI 2 "memory_operand" ""))]
4947 "TARGET_SSE2 && TARGET_SSE_MATH
4948 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4949 && reload_completed
4950 && (SSE_REG_P (operands[0])
4951 || (GET_CODE (operands[0]) == SUBREG
4952 && SSE_REG_P (operands[0])))"
4953 [(const_int 0)]
4954 {
4955 rtx op1 = operands[1];
4956
4957 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4958 <MODE>mode, 0);
4959 if (GET_CODE (op1) == SUBREG)
4960 op1 = SUBREG_REG (op1);
4961
4962 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4963 {
4964 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4965 emit_insn (gen_sse2_loadld (operands[4],
4966 CONST0_RTX (V4SImode), operands[1]));
4967 }
4968 /* We can ignore possible trapping value in the
4969 high part of SSE register for non-trapping math. */
4970 else if (SSE_REG_P (op1) && !flag_trapping_math)
4971 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4972 else
4973 {
4974 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4975 emit_move_insn (operands[2], operands[1]);
4976 emit_insn (gen_sse2_loadld (operands[4],
4977 CONST0_RTX (V4SImode), operands[2]));
4978 }
4979 emit_insn
4980 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
4981 DONE;
4982 })
4983
4984 (define_split
4985 [(set (match_operand:MODEF 0 "register_operand" "")
4986 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4987 (clobber (match_operand:SI 2 "memory_operand" ""))]
4988 "TARGET_SSE2 && TARGET_SSE_MATH
4989 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4990 && reload_completed
4991 && (SSE_REG_P (operands[0])
4992 || (GET_CODE (operands[0]) == SUBREG
4993 && SSE_REG_P (operands[0])))"
4994 [(const_int 0)]
4995 {
4996 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4997 <MODE>mode, 0);
4998 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4999
5000 emit_insn (gen_sse2_loadld (operands[4],
5001 CONST0_RTX (V4SImode), operands[1]));
5002 emit_insn
5003 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5004 DONE;
5005 })
5006
5007 (define_split
5008 [(set (match_operand:MODEF 0 "register_operand" "")
5009 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5010 "TARGET_SSE2 && TARGET_SSE_MATH
5011 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5012 && reload_completed
5013 && (SSE_REG_P (operands[0])
5014 || (GET_CODE (operands[0]) == SUBREG
5015 && SSE_REG_P (operands[0])))"
5016 [(const_int 0)]
5017 {
5018 rtx op1 = operands[1];
5019
5020 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5021 <MODE>mode, 0);
5022 if (GET_CODE (op1) == SUBREG)
5023 op1 = SUBREG_REG (op1);
5024
5025 if (GENERAL_REG_P (op1))
5026 {
5027 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5028 if (TARGET_INTER_UNIT_MOVES)
5029 emit_insn (gen_sse2_loadld (operands[4],
5030 CONST0_RTX (V4SImode), operands[1]));
5031 else
5032 {
5033 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5034 operands[1]);
5035 emit_insn (gen_sse2_loadld (operands[4],
5036 CONST0_RTX (V4SImode), operands[5]));
5037 ix86_free_from_memory (GET_MODE (operands[1]));
5038 }
5039 }
5040 /* We can ignore possible trapping value in the
5041 high part of SSE register for non-trapping math. */
5042 else if (SSE_REG_P (op1) && !flag_trapping_math)
5043 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5044 else
5045 gcc_unreachable ();
5046 emit_insn
5047 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5048 DONE;
5049 })
5050
5051 (define_split
5052 [(set (match_operand:MODEF 0 "register_operand" "")
5053 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5054 "TARGET_SSE2 && TARGET_SSE_MATH
5055 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5056 && reload_completed
5057 && (SSE_REG_P (operands[0])
5058 || (GET_CODE (operands[0]) == SUBREG
5059 && SSE_REG_P (operands[0])))"
5060 [(const_int 0)]
5061 {
5062 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5063 <MODE>mode, 0);
5064 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5065
5066 emit_insn (gen_sse2_loadld (operands[4],
5067 CONST0_RTX (V4SImode), operands[1]));
5068 emit_insn
5069 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5070 DONE;
5071 })
5072
5073 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5074 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5075 (float:MODEF
5076 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5077 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5078 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5079 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5080 "#"
5081 [(set_attr "type" "sseicvt")
5082 (set_attr "mode" "<MODEF:MODE>")
5083 (set_attr "athlon_decode" "double,direct")
5084 (set_attr "amdfam10_decode" "vector,double")
5085 (set_attr "bdver1_decode" "double,direct")
5086 (set_attr "fp_int_src" "true")])
5087
5088 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5089 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5090 (float:MODEF
5091 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5092 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5093 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5094 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5095 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5096 [(set_attr "type" "sseicvt")
5097 (set_attr "prefix" "maybe_vex")
5098 (set_attr "mode" "<MODEF:MODE>")
5099 (set (attr "prefix_rex")
5100 (if_then_else
5101 (and (eq_attr "prefix" "maybe_vex")
5102 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5103 (const_string "1")
5104 (const_string "*")))
5105 (set_attr "athlon_decode" "double,direct")
5106 (set_attr "amdfam10_decode" "vector,double")
5107 (set_attr "bdver1_decode" "double,direct")
5108 (set_attr "fp_int_src" "true")])
5109
5110 (define_split
5111 [(set (match_operand:MODEF 0 "register_operand" "")
5112 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5113 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5114 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5115 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5116 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5117 && reload_completed
5118 && (SSE_REG_P (operands[0])
5119 || (GET_CODE (operands[0]) == SUBREG
5120 && SSE_REG_P (operands[0])))"
5121 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5122
5123 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5124 [(set (match_operand:MODEF 0 "register_operand" "=x")
5125 (float:MODEF
5126 (match_operand:SWI48x 1 "memory_operand" "m")))]
5127 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5128 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5129 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5130 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5131 [(set_attr "type" "sseicvt")
5132 (set_attr "prefix" "maybe_vex")
5133 (set_attr "mode" "<MODEF:MODE>")
5134 (set (attr "prefix_rex")
5135 (if_then_else
5136 (and (eq_attr "prefix" "maybe_vex")
5137 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5138 (const_string "1")
5139 (const_string "*")))
5140 (set_attr "athlon_decode" "direct")
5141 (set_attr "amdfam10_decode" "double")
5142 (set_attr "bdver1_decode" "direct")
5143 (set_attr "fp_int_src" "true")])
5144
5145 (define_split
5146 [(set (match_operand:MODEF 0 "register_operand" "")
5147 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5148 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5149 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5150 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5151 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5152 && reload_completed
5153 && (SSE_REG_P (operands[0])
5154 || (GET_CODE (operands[0]) == SUBREG
5155 && SSE_REG_P (operands[0])))"
5156 [(set (match_dup 2) (match_dup 1))
5157 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5158
5159 (define_split
5160 [(set (match_operand:MODEF 0 "register_operand" "")
5161 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5162 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5163 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5164 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5165 && reload_completed
5166 && (SSE_REG_P (operands[0])
5167 || (GET_CODE (operands[0]) == SUBREG
5168 && SSE_REG_P (operands[0])))"
5169 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5170
5171 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5172 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5173 (float:X87MODEF
5174 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5175 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5176 "TARGET_80387
5177 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5178 "@
5179 fild%Z1\t%1
5180 #"
5181 [(set_attr "type" "fmov,multi")
5182 (set_attr "mode" "<X87MODEF:MODE>")
5183 (set_attr "unit" "*,i387")
5184 (set_attr "fp_int_src" "true")])
5185
5186 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5187 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5188 (float:X87MODEF
5189 (match_operand:SWI48x 1 "memory_operand" "m")))]
5190 "TARGET_80387
5191 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5192 "fild%Z1\t%1"
5193 [(set_attr "type" "fmov")
5194 (set_attr "mode" "<X87MODEF:MODE>")
5195 (set_attr "fp_int_src" "true")])
5196
5197 (define_split
5198 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5199 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5200 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5201 "TARGET_80387
5202 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5203 && reload_completed"
5204 [(set (match_dup 2) (match_dup 1))
5205 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5206
5207 (define_split
5208 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5209 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5210 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5211 "TARGET_80387
5212 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5213 && reload_completed"
5214 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5215
5216 ;; Avoid store forwarding (partial memory) stall penalty
5217 ;; by passing DImode value through XMM registers. */
5218
5219 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5220 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5221 (float:X87MODEF
5222 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5223 (clobber (match_scratch:V4SI 3 "=X,x"))
5224 (clobber (match_scratch:V4SI 4 "=X,x"))
5225 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5226 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5227 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5228 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5229 "#"
5230 [(set_attr "type" "multi")
5231 (set_attr "mode" "<X87MODEF:MODE>")
5232 (set_attr "unit" "i387")
5233 (set_attr "fp_int_src" "true")])
5234
5235 (define_split
5236 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5237 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5238 (clobber (match_scratch:V4SI 3 ""))
5239 (clobber (match_scratch:V4SI 4 ""))
5240 (clobber (match_operand:DI 2 "memory_operand" ""))]
5241 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5242 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5243 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5244 && reload_completed"
5245 [(set (match_dup 2) (match_dup 3))
5246 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5247 {
5248 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5249 Assemble the 64-bit DImode value in an xmm register. */
5250 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5251 gen_rtx_SUBREG (SImode, operands[1], 0)));
5252 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5253 gen_rtx_SUBREG (SImode, operands[1], 4)));
5254 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5255 operands[4]));
5256
5257 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5258 })
5259
5260 (define_split
5261 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5262 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5263 (clobber (match_scratch:V4SI 3 ""))
5264 (clobber (match_scratch:V4SI 4 ""))
5265 (clobber (match_operand:DI 2 "memory_operand" ""))]
5266 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5267 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5268 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5269 && reload_completed"
5270 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5271
5272 ;; Avoid store forwarding (partial memory) stall penalty by extending
5273 ;; SImode value to DImode through XMM register instead of pushing two
5274 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5275 ;; targets benefit from this optimization. Also note that fild
5276 ;; loads from memory only.
5277
5278 (define_insn "*floatunssi<mode>2_1"
5279 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5280 (unsigned_float:X87MODEF
5281 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5282 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5283 (clobber (match_scratch:SI 3 "=X,x"))]
5284 "!TARGET_64BIT
5285 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5286 && TARGET_SSE"
5287 "#"
5288 [(set_attr "type" "multi")
5289 (set_attr "mode" "<MODE>")])
5290
5291 (define_split
5292 [(set (match_operand:X87MODEF 0 "register_operand" "")
5293 (unsigned_float:X87MODEF
5294 (match_operand:SI 1 "register_operand" "")))
5295 (clobber (match_operand:DI 2 "memory_operand" ""))
5296 (clobber (match_scratch:SI 3 ""))]
5297 "!TARGET_64BIT
5298 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5299 && TARGET_SSE
5300 && reload_completed"
5301 [(set (match_dup 2) (match_dup 1))
5302 (set (match_dup 0)
5303 (float:X87MODEF (match_dup 2)))]
5304 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5305
5306 (define_split
5307 [(set (match_operand:X87MODEF 0 "register_operand" "")
5308 (unsigned_float:X87MODEF
5309 (match_operand:SI 1 "memory_operand" "")))
5310 (clobber (match_operand:DI 2 "memory_operand" ""))
5311 (clobber (match_scratch:SI 3 ""))]
5312 "!TARGET_64BIT
5313 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5314 && TARGET_SSE
5315 && reload_completed"
5316 [(set (match_dup 2) (match_dup 3))
5317 (set (match_dup 0)
5318 (float:X87MODEF (match_dup 2)))]
5319 {
5320 emit_move_insn (operands[3], operands[1]);
5321 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5322 })
5323
5324 (define_expand "floatunssi<mode>2"
5325 [(parallel
5326 [(set (match_operand:X87MODEF 0 "register_operand" "")
5327 (unsigned_float:X87MODEF
5328 (match_operand:SI 1 "nonimmediate_operand" "")))
5329 (clobber (match_dup 2))
5330 (clobber (match_scratch:SI 3 ""))])]
5331 "!TARGET_64BIT
5332 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5333 && TARGET_SSE)
5334 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5335 {
5336 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5337 {
5338 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5339 DONE;
5340 }
5341 else
5342 {
5343 enum ix86_stack_slot slot = (virtuals_instantiated
5344 ? SLOT_TEMP
5345 : SLOT_VIRTUAL);
5346 operands[2] = assign_386_stack_local (DImode, slot);
5347 }
5348 })
5349
5350 (define_expand "floatunsdisf2"
5351 [(use (match_operand:SF 0 "register_operand" ""))
5352 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5353 "TARGET_64BIT && TARGET_SSE_MATH"
5354 "x86_emit_floatuns (operands); DONE;")
5355
5356 (define_expand "floatunsdidf2"
5357 [(use (match_operand:DF 0 "register_operand" ""))
5358 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5359 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5360 && TARGET_SSE2 && TARGET_SSE_MATH"
5361 {
5362 if (TARGET_64BIT)
5363 x86_emit_floatuns (operands);
5364 else
5365 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5366 DONE;
5367 })
5368 \f
5369 ;; Add instructions
5370
5371 (define_expand "add<mode>3"
5372 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5373 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5374 (match_operand:SDWIM 2 "<general_operand>" "")))]
5375 ""
5376 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5377
5378 (define_insn_and_split "*add<dwi>3_doubleword"
5379 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5380 (plus:<DWI>
5381 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5382 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5383 (clobber (reg:CC FLAGS_REG))]
5384 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5385 "#"
5386 "reload_completed"
5387 [(parallel [(set (reg:CC FLAGS_REG)
5388 (unspec:CC [(match_dup 1) (match_dup 2)]
5389 UNSPEC_ADD_CARRY))
5390 (set (match_dup 0)
5391 (plus:DWIH (match_dup 1) (match_dup 2)))])
5392 (parallel [(set (match_dup 3)
5393 (plus:DWIH
5394 (match_dup 4)
5395 (plus:DWIH
5396 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5397 (match_dup 5))))
5398 (clobber (reg:CC FLAGS_REG))])]
5399 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5400
5401 (define_insn "*add<mode>3_cc"
5402 [(set (reg:CC FLAGS_REG)
5403 (unspec:CC
5404 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5405 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5406 UNSPEC_ADD_CARRY))
5407 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5408 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5409 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5410 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5411 [(set_attr "type" "alu")
5412 (set_attr "mode" "<MODE>")])
5413
5414 (define_insn "addqi3_cc"
5415 [(set (reg:CC FLAGS_REG)
5416 (unspec:CC
5417 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5418 (match_operand:QI 2 "general_operand" "qn,qm")]
5419 UNSPEC_ADD_CARRY))
5420 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5421 (plus:QI (match_dup 1) (match_dup 2)))]
5422 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5423 "add{b}\t{%2, %0|%0, %2}"
5424 [(set_attr "type" "alu")
5425 (set_attr "mode" "QI")])
5426
5427 (define_insn "*lea_1"
5428 [(set (match_operand:SWI48 0 "register_operand" "=r")
5429 (match_operand:SWI48 1 "no_seg_address_operand" "p"))]
5430 ""
5431 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5432 [(set_attr "type" "lea")
5433 (set_attr "mode" "<MODE>")])
5434
5435 (define_insn "*lea_1_zext"
5436 [(set (match_operand:DI 0 "register_operand" "=r")
5437 (zero_extend:DI
5438 (match_operand:SI 1 "no_seg_address_operand" "p")))]
5439 "TARGET_64BIT"
5440 "lea{l}\t{%a1, %k0|%k0, %a1}"
5441 [(set_attr "type" "lea")
5442 (set_attr "mode" "SI")])
5443
5444 (define_insn "*lea_2"
5445 [(set (match_operand:SI 0 "register_operand" "=r")
5446 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5447 "TARGET_64BIT"
5448 "lea{l}\t{%a1, %0|%0, %a1}"
5449 [(set_attr "type" "lea")
5450 (set_attr "mode" "SI")])
5451
5452 (define_insn "*lea_2_zext"
5453 [(set (match_operand:DI 0 "register_operand" "=r")
5454 (zero_extend:DI
5455 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5456 "TARGET_64BIT"
5457 "lea{l}\t{%a1, %k0|%k0, %a1}"
5458 [(set_attr "type" "lea")
5459 (set_attr "mode" "SI")])
5460
5461 (define_insn "*add<mode>_1"
5462 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5463 (plus:SWI48
5464 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5465 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5466 (clobber (reg:CC FLAGS_REG))]
5467 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5468 {
5469 switch (get_attr_type (insn))
5470 {
5471 case TYPE_LEA:
5472 return "#";
5473
5474 case TYPE_INCDEC:
5475 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5476 if (operands[2] == const1_rtx)
5477 return "inc{<imodesuffix>}\t%0";
5478 else
5479 {
5480 gcc_assert (operands[2] == constm1_rtx);
5481 return "dec{<imodesuffix>}\t%0";
5482 }
5483
5484 default:
5485 /* For most processors, ADD is faster than LEA. This alternative
5486 was added to use ADD as much as possible. */
5487 if (which_alternative == 2)
5488 {
5489 rtx tmp;
5490 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5491 }
5492
5493 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5494 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5495 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5496
5497 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5498 }
5499 }
5500 [(set (attr "type")
5501 (cond [(eq_attr "alternative" "3")
5502 (const_string "lea")
5503 (match_operand:SWI48 2 "incdec_operand" "")
5504 (const_string "incdec")
5505 ]
5506 (const_string "alu")))
5507 (set (attr "length_immediate")
5508 (if_then_else
5509 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5510 (const_string "1")
5511 (const_string "*")))
5512 (set_attr "mode" "<MODE>")])
5513
5514 ;; It may seem that nonimmediate operand is proper one for operand 1.
5515 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5516 ;; we take care in ix86_binary_operator_ok to not allow two memory
5517 ;; operands so proper swapping will be done in reload. This allow
5518 ;; patterns constructed from addsi_1 to match.
5519
5520 (define_insn "addsi_1_zext"
5521 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5522 (zero_extend:DI
5523 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5524 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5525 (clobber (reg:CC FLAGS_REG))]
5526 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5527 {
5528 switch (get_attr_type (insn))
5529 {
5530 case TYPE_LEA:
5531 return "#";
5532
5533 case TYPE_INCDEC:
5534 if (operands[2] == const1_rtx)
5535 return "inc{l}\t%k0";
5536 else
5537 {
5538 gcc_assert (operands[2] == constm1_rtx);
5539 return "dec{l}\t%k0";
5540 }
5541
5542 default:
5543 /* For most processors, ADD is faster than LEA. This alternative
5544 was added to use ADD as much as possible. */
5545 if (which_alternative == 1)
5546 {
5547 rtx tmp;
5548 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5549 }
5550
5551 if (x86_maybe_negate_const_int (&operands[2], SImode))
5552 return "sub{l}\t{%2, %k0|%k0, %2}";
5553
5554 return "add{l}\t{%2, %k0|%k0, %2}";
5555 }
5556 }
5557 [(set (attr "type")
5558 (cond [(eq_attr "alternative" "2")
5559 (const_string "lea")
5560 (match_operand:SI 2 "incdec_operand" "")
5561 (const_string "incdec")
5562 ]
5563 (const_string "alu")))
5564 (set (attr "length_immediate")
5565 (if_then_else
5566 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5567 (const_string "1")
5568 (const_string "*")))
5569 (set_attr "mode" "SI")])
5570
5571 (define_insn "*addhi_1"
5572 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5573 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5574 (match_operand:HI 2 "general_operand" "rn,rm")))
5575 (clobber (reg:CC FLAGS_REG))]
5576 "TARGET_PARTIAL_REG_STALL
5577 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5578 {
5579 switch (get_attr_type (insn))
5580 {
5581 case TYPE_INCDEC:
5582 if (operands[2] == const1_rtx)
5583 return "inc{w}\t%0";
5584 else
5585 {
5586 gcc_assert (operands[2] == constm1_rtx);
5587 return "dec{w}\t%0";
5588 }
5589
5590 default:
5591 if (x86_maybe_negate_const_int (&operands[2], HImode))
5592 return "sub{w}\t{%2, %0|%0, %2}";
5593
5594 return "add{w}\t{%2, %0|%0, %2}";
5595 }
5596 }
5597 [(set (attr "type")
5598 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5599 (const_string "incdec")
5600 (const_string "alu")))
5601 (set (attr "length_immediate")
5602 (if_then_else
5603 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5604 (const_string "1")
5605 (const_string "*")))
5606 (set_attr "mode" "HI")])
5607
5608 (define_insn "*addhi_1_lea"
5609 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5610 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5611 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5612 (clobber (reg:CC FLAGS_REG))]
5613 "!TARGET_PARTIAL_REG_STALL
5614 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5615 {
5616 switch (get_attr_type (insn))
5617 {
5618 case TYPE_LEA:
5619 return "#";
5620
5621 case TYPE_INCDEC:
5622 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5623 if (operands[2] == const1_rtx)
5624 return "inc{w}\t%0";
5625 else
5626 {
5627 gcc_assert (operands[2] == constm1_rtx);
5628 return "dec{w}\t%0";
5629 }
5630
5631 default:
5632 /* For most processors, ADD is faster than LEA. This alternative
5633 was added to use ADD as much as possible. */
5634 if (which_alternative == 2)
5635 {
5636 rtx tmp;
5637 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5638 }
5639
5640 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641 if (x86_maybe_negate_const_int (&operands[2], HImode))
5642 return "sub{w}\t{%2, %0|%0, %2}";
5643
5644 return "add{w}\t{%2, %0|%0, %2}";
5645 }
5646 }
5647 [(set (attr "type")
5648 (cond [(eq_attr "alternative" "3")
5649 (const_string "lea")
5650 (match_operand:HI 2 "incdec_operand" "")
5651 (const_string "incdec")
5652 ]
5653 (const_string "alu")))
5654 (set (attr "length_immediate")
5655 (if_then_else
5656 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5657 (const_string "1")
5658 (const_string "*")))
5659 (set_attr "mode" "HI,HI,HI,SI")])
5660
5661 ;; %%% Potential partial reg stall on alternative 2. What to do?
5662 (define_insn "*addqi_1"
5663 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5664 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5665 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5666 (clobber (reg:CC FLAGS_REG))]
5667 "TARGET_PARTIAL_REG_STALL
5668 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5669 {
5670 int widen = (which_alternative == 2);
5671 switch (get_attr_type (insn))
5672 {
5673 case TYPE_INCDEC:
5674 if (operands[2] == const1_rtx)
5675 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5676 else
5677 {
5678 gcc_assert (operands[2] == constm1_rtx);
5679 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5680 }
5681
5682 default:
5683 if (x86_maybe_negate_const_int (&operands[2], QImode))
5684 {
5685 if (widen)
5686 return "sub{l}\t{%2, %k0|%k0, %2}";
5687 else
5688 return "sub{b}\t{%2, %0|%0, %2}";
5689 }
5690 if (widen)
5691 return "add{l}\t{%k2, %k0|%k0, %k2}";
5692 else
5693 return "add{b}\t{%2, %0|%0, %2}";
5694 }
5695 }
5696 [(set (attr "type")
5697 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5698 (const_string "incdec")
5699 (const_string "alu")))
5700 (set (attr "length_immediate")
5701 (if_then_else
5702 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5703 (const_string "1")
5704 (const_string "*")))
5705 (set_attr "mode" "QI,QI,SI")])
5706
5707 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5708 (define_insn "*addqi_1_lea"
5709 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5710 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5711 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5712 (clobber (reg:CC FLAGS_REG))]
5713 "!TARGET_PARTIAL_REG_STALL
5714 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5715 {
5716 int widen = (which_alternative == 3 || which_alternative == 4);
5717
5718 switch (get_attr_type (insn))
5719 {
5720 case TYPE_LEA:
5721 return "#";
5722
5723 case TYPE_INCDEC:
5724 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5725 if (operands[2] == const1_rtx)
5726 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5727 else
5728 {
5729 gcc_assert (operands[2] == constm1_rtx);
5730 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5731 }
5732
5733 default:
5734 /* For most processors, ADD is faster than LEA. These alternatives
5735 were added to use ADD as much as possible. */
5736 if (which_alternative == 2 || which_alternative == 4)
5737 {
5738 rtx tmp;
5739 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5740 }
5741
5742 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5743 if (x86_maybe_negate_const_int (&operands[2], QImode))
5744 {
5745 if (widen)
5746 return "sub{l}\t{%2, %k0|%k0, %2}";
5747 else
5748 return "sub{b}\t{%2, %0|%0, %2}";
5749 }
5750 if (widen)
5751 return "add{l}\t{%k2, %k0|%k0, %k2}";
5752 else
5753 return "add{b}\t{%2, %0|%0, %2}";
5754 }
5755 }
5756 [(set (attr "type")
5757 (cond [(eq_attr "alternative" "5")
5758 (const_string "lea")
5759 (match_operand:QI 2 "incdec_operand" "")
5760 (const_string "incdec")
5761 ]
5762 (const_string "alu")))
5763 (set (attr "length_immediate")
5764 (if_then_else
5765 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5766 (const_string "1")
5767 (const_string "*")))
5768 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5769
5770 (define_insn "*addqi_1_slp"
5771 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5772 (plus:QI (match_dup 0)
5773 (match_operand:QI 1 "general_operand" "qn,qnm")))
5774 (clobber (reg:CC FLAGS_REG))]
5775 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5776 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5777 {
5778 switch (get_attr_type (insn))
5779 {
5780 case TYPE_INCDEC:
5781 if (operands[1] == const1_rtx)
5782 return "inc{b}\t%0";
5783 else
5784 {
5785 gcc_assert (operands[1] == constm1_rtx);
5786 return "dec{b}\t%0";
5787 }
5788
5789 default:
5790 if (x86_maybe_negate_const_int (&operands[1], QImode))
5791 return "sub{b}\t{%1, %0|%0, %1}";
5792
5793 return "add{b}\t{%1, %0|%0, %1}";
5794 }
5795 }
5796 [(set (attr "type")
5797 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5798 (const_string "incdec")
5799 (const_string "alu1")))
5800 (set (attr "memory")
5801 (if_then_else (match_operand 1 "memory_operand" "")
5802 (const_string "load")
5803 (const_string "none")))
5804 (set_attr "mode" "QI")])
5805
5806 ;; Convert add to the lea pattern to avoid flags dependency.
5807 (define_split
5808 [(set (match_operand:SWI 0 "register_operand" "")
5809 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5810 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5811 (clobber (reg:CC FLAGS_REG))]
5812 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5813 [(const_int 0)]
5814 {
5815 enum machine_mode mode = <MODE>mode;
5816 rtx pat;
5817
5818 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5819 {
5820 mode = SImode;
5821 operands[0] = gen_lowpart (mode, operands[0]);
5822 operands[1] = gen_lowpart (mode, operands[1]);
5823 operands[2] = gen_lowpart (mode, operands[2]);
5824 }
5825
5826 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5827
5828 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5829 DONE;
5830 })
5831
5832 ;; Convert add to the lea pattern to avoid flags dependency.
5833 (define_split
5834 [(set (match_operand:DI 0 "register_operand" "")
5835 (zero_extend:DI
5836 (plus:SI (match_operand:SI 1 "register_operand" "")
5837 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5838 (clobber (reg:CC FLAGS_REG))]
5839 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5840 [(set (match_dup 0)
5841 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5842
5843 (define_insn "*add<mode>_2"
5844 [(set (reg FLAGS_REG)
5845 (compare
5846 (plus:SWI
5847 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5848 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5849 (const_int 0)))
5850 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5851 (plus:SWI (match_dup 1) (match_dup 2)))]
5852 "ix86_match_ccmode (insn, CCGOCmode)
5853 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5854 {
5855 switch (get_attr_type (insn))
5856 {
5857 case TYPE_INCDEC:
5858 if (operands[2] == const1_rtx)
5859 return "inc{<imodesuffix>}\t%0";
5860 else
5861 {
5862 gcc_assert (operands[2] == constm1_rtx);
5863 return "dec{<imodesuffix>}\t%0";
5864 }
5865
5866 default:
5867 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5868 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5869
5870 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5871 }
5872 }
5873 [(set (attr "type")
5874 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5875 (const_string "incdec")
5876 (const_string "alu")))
5877 (set (attr "length_immediate")
5878 (if_then_else
5879 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5880 (const_string "1")
5881 (const_string "*")))
5882 (set_attr "mode" "<MODE>")])
5883
5884 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5885 (define_insn "*addsi_2_zext"
5886 [(set (reg FLAGS_REG)
5887 (compare
5888 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5889 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5890 (const_int 0)))
5891 (set (match_operand:DI 0 "register_operand" "=r")
5892 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5893 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5894 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5895 {
5896 switch (get_attr_type (insn))
5897 {
5898 case TYPE_INCDEC:
5899 if (operands[2] == const1_rtx)
5900 return "inc{l}\t%k0";
5901 else
5902 {
5903 gcc_assert (operands[2] == constm1_rtx);
5904 return "dec{l}\t%k0";
5905 }
5906
5907 default:
5908 if (x86_maybe_negate_const_int (&operands[2], SImode))
5909 return "sub{l}\t{%2, %k0|%k0, %2}";
5910
5911 return "add{l}\t{%2, %k0|%k0, %2}";
5912 }
5913 }
5914 [(set (attr "type")
5915 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5916 (const_string "incdec")
5917 (const_string "alu")))
5918 (set (attr "length_immediate")
5919 (if_then_else
5920 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5921 (const_string "1")
5922 (const_string "*")))
5923 (set_attr "mode" "SI")])
5924
5925 (define_insn "*add<mode>_3"
5926 [(set (reg FLAGS_REG)
5927 (compare
5928 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5929 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5930 (clobber (match_scratch:SWI 0 "=<r>"))]
5931 "ix86_match_ccmode (insn, CCZmode)
5932 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5933 {
5934 switch (get_attr_type (insn))
5935 {
5936 case TYPE_INCDEC:
5937 if (operands[2] == const1_rtx)
5938 return "inc{<imodesuffix>}\t%0";
5939 else
5940 {
5941 gcc_assert (operands[2] == constm1_rtx);
5942 return "dec{<imodesuffix>}\t%0";
5943 }
5944
5945 default:
5946 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5947 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5948
5949 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5950 }
5951 }
5952 [(set (attr "type")
5953 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5954 (const_string "incdec")
5955 (const_string "alu")))
5956 (set (attr "length_immediate")
5957 (if_then_else
5958 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5959 (const_string "1")
5960 (const_string "*")))
5961 (set_attr "mode" "<MODE>")])
5962
5963 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5964 (define_insn "*addsi_3_zext"
5965 [(set (reg FLAGS_REG)
5966 (compare
5967 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5968 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5969 (set (match_operand:DI 0 "register_operand" "=r")
5970 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5971 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5972 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5973 {
5974 switch (get_attr_type (insn))
5975 {
5976 case TYPE_INCDEC:
5977 if (operands[2] == const1_rtx)
5978 return "inc{l}\t%k0";
5979 else
5980 {
5981 gcc_assert (operands[2] == constm1_rtx);
5982 return "dec{l}\t%k0";
5983 }
5984
5985 default:
5986 if (x86_maybe_negate_const_int (&operands[2], SImode))
5987 return "sub{l}\t{%2, %k0|%k0, %2}";
5988
5989 return "add{l}\t{%2, %k0|%k0, %2}";
5990 }
5991 }
5992 [(set (attr "type")
5993 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5994 (const_string "incdec")
5995 (const_string "alu")))
5996 (set (attr "length_immediate")
5997 (if_then_else
5998 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5999 (const_string "1")
6000 (const_string "*")))
6001 (set_attr "mode" "SI")])
6002
6003 ; For comparisons against 1, -1 and 128, we may generate better code
6004 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6005 ; is matched then. We can't accept general immediate, because for
6006 ; case of overflows, the result is messed up.
6007 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6008 ; only for comparisons not depending on it.
6009
6010 (define_insn "*adddi_4"
6011 [(set (reg FLAGS_REG)
6012 (compare
6013 (match_operand:DI 1 "nonimmediate_operand" "0")
6014 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6015 (clobber (match_scratch:DI 0 "=rm"))]
6016 "TARGET_64BIT
6017 && ix86_match_ccmode (insn, CCGCmode)"
6018 {
6019 switch (get_attr_type (insn))
6020 {
6021 case TYPE_INCDEC:
6022 if (operands[2] == constm1_rtx)
6023 return "inc{q}\t%0";
6024 else
6025 {
6026 gcc_assert (operands[2] == const1_rtx);
6027 return "dec{q}\t%0";
6028 }
6029
6030 default:
6031 if (x86_maybe_negate_const_int (&operands[2], DImode))
6032 return "add{q}\t{%2, %0|%0, %2}";
6033
6034 return "sub{q}\t{%2, %0|%0, %2}";
6035 }
6036 }
6037 [(set (attr "type")
6038 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6039 (const_string "incdec")
6040 (const_string "alu")))
6041 (set (attr "length_immediate")
6042 (if_then_else
6043 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6044 (const_string "1")
6045 (const_string "*")))
6046 (set_attr "mode" "DI")])
6047
6048 ; For comparisons against 1, -1 and 128, we may generate better code
6049 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6050 ; is matched then. We can't accept general immediate, because for
6051 ; case of overflows, the result is messed up.
6052 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6053 ; only for comparisons not depending on it.
6054
6055 (define_insn "*add<mode>_4"
6056 [(set (reg FLAGS_REG)
6057 (compare
6058 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6059 (match_operand:SWI124 2 "const_int_operand" "n")))
6060 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6061 "ix86_match_ccmode (insn, CCGCmode)"
6062 {
6063 switch (get_attr_type (insn))
6064 {
6065 case TYPE_INCDEC:
6066 if (operands[2] == constm1_rtx)
6067 return "inc{<imodesuffix>}\t%0";
6068 else
6069 {
6070 gcc_assert (operands[2] == const1_rtx);
6071 return "dec{<imodesuffix>}\t%0";
6072 }
6073
6074 default:
6075 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6076 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6077
6078 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6079 }
6080 }
6081 [(set (attr "type")
6082 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6083 (const_string "incdec")
6084 (const_string "alu")))
6085 (set (attr "length_immediate")
6086 (if_then_else
6087 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6088 (const_string "1")
6089 (const_string "*")))
6090 (set_attr "mode" "<MODE>")])
6091
6092 (define_insn "*add<mode>_5"
6093 [(set (reg FLAGS_REG)
6094 (compare
6095 (plus:SWI
6096 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6097 (match_operand:SWI 2 "<general_operand>" "<g>"))
6098 (const_int 0)))
6099 (clobber (match_scratch:SWI 0 "=<r>"))]
6100 "ix86_match_ccmode (insn, CCGOCmode)
6101 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6102 {
6103 switch (get_attr_type (insn))
6104 {
6105 case TYPE_INCDEC:
6106 if (operands[2] == const1_rtx)
6107 return "inc{<imodesuffix>}\t%0";
6108 else
6109 {
6110 gcc_assert (operands[2] == constm1_rtx);
6111 return "dec{<imodesuffix>}\t%0";
6112 }
6113
6114 default:
6115 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6116 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6117
6118 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6119 }
6120 }
6121 [(set (attr "type")
6122 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6123 (const_string "incdec")
6124 (const_string "alu")))
6125 (set (attr "length_immediate")
6126 (if_then_else
6127 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6128 (const_string "1")
6129 (const_string "*")))
6130 (set_attr "mode" "<MODE>")])
6131
6132 (define_insn "*addqi_ext_1_rex64"
6133 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6134 (const_int 8)
6135 (const_int 8))
6136 (plus:SI
6137 (zero_extract:SI
6138 (match_operand 1 "ext_register_operand" "0")
6139 (const_int 8)
6140 (const_int 8))
6141 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6142 (clobber (reg:CC FLAGS_REG))]
6143 "TARGET_64BIT"
6144 {
6145 switch (get_attr_type (insn))
6146 {
6147 case TYPE_INCDEC:
6148 if (operands[2] == const1_rtx)
6149 return "inc{b}\t%h0";
6150 else
6151 {
6152 gcc_assert (operands[2] == constm1_rtx);
6153 return "dec{b}\t%h0";
6154 }
6155
6156 default:
6157 return "add{b}\t{%2, %h0|%h0, %2}";
6158 }
6159 }
6160 [(set (attr "type")
6161 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6162 (const_string "incdec")
6163 (const_string "alu")))
6164 (set_attr "modrm" "1")
6165 (set_attr "mode" "QI")])
6166
6167 (define_insn "addqi_ext_1"
6168 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6169 (const_int 8)
6170 (const_int 8))
6171 (plus:SI
6172 (zero_extract:SI
6173 (match_operand 1 "ext_register_operand" "0")
6174 (const_int 8)
6175 (const_int 8))
6176 (match_operand:QI 2 "general_operand" "Qmn")))
6177 (clobber (reg:CC FLAGS_REG))]
6178 "!TARGET_64BIT"
6179 {
6180 switch (get_attr_type (insn))
6181 {
6182 case TYPE_INCDEC:
6183 if (operands[2] == const1_rtx)
6184 return "inc{b}\t%h0";
6185 else
6186 {
6187 gcc_assert (operands[2] == constm1_rtx);
6188 return "dec{b}\t%h0";
6189 }
6190
6191 default:
6192 return "add{b}\t{%2, %h0|%h0, %2}";
6193 }
6194 }
6195 [(set (attr "type")
6196 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6197 (const_string "incdec")
6198 (const_string "alu")))
6199 (set_attr "modrm" "1")
6200 (set_attr "mode" "QI")])
6201
6202 (define_insn "*addqi_ext_2"
6203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6204 (const_int 8)
6205 (const_int 8))
6206 (plus:SI
6207 (zero_extract:SI
6208 (match_operand 1 "ext_register_operand" "%0")
6209 (const_int 8)
6210 (const_int 8))
6211 (zero_extract:SI
6212 (match_operand 2 "ext_register_operand" "Q")
6213 (const_int 8)
6214 (const_int 8))))
6215 (clobber (reg:CC FLAGS_REG))]
6216 ""
6217 "add{b}\t{%h2, %h0|%h0, %h2}"
6218 [(set_attr "type" "alu")
6219 (set_attr "mode" "QI")])
6220
6221 ;; The lea patterns for modes less than 32 bits need to be matched by
6222 ;; several insns converted to real lea by splitters.
6223
6224 (define_insn_and_split "*lea_general_1"
6225 [(set (match_operand 0 "register_operand" "=r")
6226 (plus (plus (match_operand 1 "index_register_operand" "l")
6227 (match_operand 2 "register_operand" "r"))
6228 (match_operand 3 "immediate_operand" "i")))]
6229 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6230 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6231 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6232 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6233 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6234 || GET_MODE (operands[3]) == VOIDmode)"
6235 "#"
6236 "&& reload_completed"
6237 [(const_int 0)]
6238 {
6239 enum machine_mode mode = SImode;
6240 rtx pat;
6241
6242 operands[0] = gen_lowpart (mode, operands[0]);
6243 operands[1] = gen_lowpart (mode, operands[1]);
6244 operands[2] = gen_lowpart (mode, operands[2]);
6245 operands[3] = gen_lowpart (mode, operands[3]);
6246
6247 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6248 operands[3]);
6249
6250 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6251 DONE;
6252 }
6253 [(set_attr "type" "lea")
6254 (set_attr "mode" "SI")])
6255
6256 (define_insn_and_split "*lea_general_2"
6257 [(set (match_operand 0 "register_operand" "=r")
6258 (plus (mult (match_operand 1 "index_register_operand" "l")
6259 (match_operand 2 "const248_operand" "n"))
6260 (match_operand 3 "nonmemory_operand" "ri")))]
6261 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6262 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6263 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6264 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6265 || GET_MODE (operands[3]) == VOIDmode)"
6266 "#"
6267 "&& reload_completed"
6268 [(const_int 0)]
6269 {
6270 enum machine_mode mode = SImode;
6271 rtx pat;
6272
6273 operands[0] = gen_lowpart (mode, operands[0]);
6274 operands[1] = gen_lowpart (mode, operands[1]);
6275 operands[3] = gen_lowpart (mode, operands[3]);
6276
6277 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6278 operands[3]);
6279
6280 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6281 DONE;
6282 }
6283 [(set_attr "type" "lea")
6284 (set_attr "mode" "SI")])
6285
6286 (define_insn_and_split "*lea_general_3"
6287 [(set (match_operand 0 "register_operand" "=r")
6288 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6289 (match_operand 2 "const248_operand" "n"))
6290 (match_operand 3 "register_operand" "r"))
6291 (match_operand 4 "immediate_operand" "i")))]
6292 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6293 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6294 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6295 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6296 "#"
6297 "&& reload_completed"
6298 [(const_int 0)]
6299 {
6300 enum machine_mode mode = SImode;
6301 rtx pat;
6302
6303 operands[0] = gen_lowpart (mode, operands[0]);
6304 operands[1] = gen_lowpart (mode, operands[1]);
6305 operands[3] = gen_lowpart (mode, operands[3]);
6306 operands[4] = gen_lowpart (mode, operands[4]);
6307
6308 pat = gen_rtx_PLUS (mode,
6309 gen_rtx_PLUS (mode,
6310 gen_rtx_MULT (mode, operands[1],
6311 operands[2]),
6312 operands[3]),
6313 operands[4]);
6314
6315 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6316 DONE;
6317 }
6318 [(set_attr "type" "lea")
6319 (set_attr "mode" "SI")])
6320
6321 (define_insn_and_split "*lea_general_4"
6322 [(set (match_operand 0 "register_operand" "=r")
6323 (any_or (ashift
6324 (match_operand 1 "index_register_operand" "l")
6325 (match_operand 2 "const_int_operand" "n"))
6326 (match_operand 3 "const_int_operand" "n")))]
6327 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6328 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6329 || GET_MODE (operands[0]) == SImode
6330 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6331 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6332 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6333 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6334 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6335 "#"
6336 "&& reload_completed"
6337 [(const_int 0)]
6338 {
6339 enum machine_mode mode = GET_MODE (operands[0]);
6340 rtx pat;
6341
6342 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6343 {
6344 mode = SImode;
6345 operands[0] = gen_lowpart (mode, operands[0]);
6346 operands[1] = gen_lowpart (mode, operands[1]);
6347 }
6348
6349 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6350
6351 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6352 INTVAL (operands[3]));
6353
6354 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6355 DONE;
6356 }
6357 [(set_attr "type" "lea")
6358 (set (attr "mode")
6359 (if_then_else (match_operand:DI 0 "" "")
6360 (const_string "DI")
6361 (const_string "SI")))])
6362 \f
6363 ;; Subtract instructions
6364
6365 (define_expand "sub<mode>3"
6366 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6367 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6368 (match_operand:SDWIM 2 "<general_operand>" "")))]
6369 ""
6370 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6371
6372 (define_insn_and_split "*sub<dwi>3_doubleword"
6373 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6374 (minus:<DWI>
6375 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6376 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6377 (clobber (reg:CC FLAGS_REG))]
6378 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6379 "#"
6380 "reload_completed"
6381 [(parallel [(set (reg:CC FLAGS_REG)
6382 (compare:CC (match_dup 1) (match_dup 2)))
6383 (set (match_dup 0)
6384 (minus:DWIH (match_dup 1) (match_dup 2)))])
6385 (parallel [(set (match_dup 3)
6386 (minus:DWIH
6387 (match_dup 4)
6388 (plus:DWIH
6389 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6390 (match_dup 5))))
6391 (clobber (reg:CC FLAGS_REG))])]
6392 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6393
6394 (define_insn "*sub<mode>_1"
6395 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6396 (minus:SWI
6397 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6398 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6399 (clobber (reg:CC FLAGS_REG))]
6400 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6401 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6402 [(set_attr "type" "alu")
6403 (set_attr "mode" "<MODE>")])
6404
6405 (define_insn "*subsi_1_zext"
6406 [(set (match_operand:DI 0 "register_operand" "=r")
6407 (zero_extend:DI
6408 (minus:SI (match_operand:SI 1 "register_operand" "0")
6409 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6410 (clobber (reg:CC FLAGS_REG))]
6411 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6412 "sub{l}\t{%2, %k0|%k0, %2}"
6413 [(set_attr "type" "alu")
6414 (set_attr "mode" "SI")])
6415
6416 (define_insn "*subqi_1_slp"
6417 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6418 (minus:QI (match_dup 0)
6419 (match_operand:QI 1 "general_operand" "qn,qm")))
6420 (clobber (reg:CC FLAGS_REG))]
6421 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6422 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6423 "sub{b}\t{%1, %0|%0, %1}"
6424 [(set_attr "type" "alu1")
6425 (set_attr "mode" "QI")])
6426
6427 (define_insn "*sub<mode>_2"
6428 [(set (reg FLAGS_REG)
6429 (compare
6430 (minus:SWI
6431 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6432 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6433 (const_int 0)))
6434 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6435 (minus:SWI (match_dup 1) (match_dup 2)))]
6436 "ix86_match_ccmode (insn, CCGOCmode)
6437 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6438 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6439 [(set_attr "type" "alu")
6440 (set_attr "mode" "<MODE>")])
6441
6442 (define_insn "*subsi_2_zext"
6443 [(set (reg FLAGS_REG)
6444 (compare
6445 (minus:SI (match_operand:SI 1 "register_operand" "0")
6446 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6447 (const_int 0)))
6448 (set (match_operand:DI 0 "register_operand" "=r")
6449 (zero_extend:DI
6450 (minus:SI (match_dup 1)
6451 (match_dup 2))))]
6452 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6453 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6454 "sub{l}\t{%2, %k0|%k0, %2}"
6455 [(set_attr "type" "alu")
6456 (set_attr "mode" "SI")])
6457
6458 (define_insn "*sub<mode>_3"
6459 [(set (reg FLAGS_REG)
6460 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6461 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6462 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6463 (minus:SWI (match_dup 1) (match_dup 2)))]
6464 "ix86_match_ccmode (insn, CCmode)
6465 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6466 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "<MODE>")])
6469
6470 (define_insn "*subsi_3_zext"
6471 [(set (reg FLAGS_REG)
6472 (compare (match_operand:SI 1 "register_operand" "0")
6473 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6474 (set (match_operand:DI 0 "register_operand" "=r")
6475 (zero_extend:DI
6476 (minus:SI (match_dup 1)
6477 (match_dup 2))))]
6478 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6479 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6480 "sub{l}\t{%2, %1|%1, %2}"
6481 [(set_attr "type" "alu")
6482 (set_attr "mode" "SI")])
6483 \f
6484 ;; Add with carry and subtract with borrow
6485
6486 (define_expand "<plusminus_insn><mode>3_carry"
6487 [(parallel
6488 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6489 (plusminus:SWI
6490 (match_operand:SWI 1 "nonimmediate_operand" "")
6491 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6492 [(match_operand 3 "flags_reg_operand" "")
6493 (const_int 0)])
6494 (match_operand:SWI 2 "<general_operand>" ""))))
6495 (clobber (reg:CC FLAGS_REG))])]
6496 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6497
6498 (define_insn "*<plusminus_insn><mode>3_carry"
6499 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6500 (plusminus:SWI
6501 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6502 (plus:SWI
6503 (match_operator 3 "ix86_carry_flag_operator"
6504 [(reg FLAGS_REG) (const_int 0)])
6505 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6506 (clobber (reg:CC FLAGS_REG))]
6507 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6508 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6509 [(set_attr "type" "alu")
6510 (set_attr "use_carry" "1")
6511 (set_attr "pent_pair" "pu")
6512 (set_attr "mode" "<MODE>")])
6513
6514 (define_insn "*addsi3_carry_zext"
6515 [(set (match_operand:DI 0 "register_operand" "=r")
6516 (zero_extend:DI
6517 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6518 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6519 [(reg FLAGS_REG) (const_int 0)])
6520 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6521 (clobber (reg:CC FLAGS_REG))]
6522 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6523 "adc{l}\t{%2, %k0|%k0, %2}"
6524 [(set_attr "type" "alu")
6525 (set_attr "use_carry" "1")
6526 (set_attr "pent_pair" "pu")
6527 (set_attr "mode" "SI")])
6528
6529 (define_insn "*subsi3_carry_zext"
6530 [(set (match_operand:DI 0 "register_operand" "=r")
6531 (zero_extend:DI
6532 (minus:SI (match_operand:SI 1 "register_operand" "0")
6533 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6534 [(reg FLAGS_REG) (const_int 0)])
6535 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6536 (clobber (reg:CC FLAGS_REG))]
6537 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6538 "sbb{l}\t{%2, %k0|%k0, %2}"
6539 [(set_attr "type" "alu")
6540 (set_attr "pent_pair" "pu")
6541 (set_attr "mode" "SI")])
6542 \f
6543 ;; Overflow setting add and subtract instructions
6544
6545 (define_insn "*add<mode>3_cconly_overflow"
6546 [(set (reg:CCC FLAGS_REG)
6547 (compare:CCC
6548 (plus:SWI
6549 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6550 (match_operand:SWI 2 "<general_operand>" "<g>"))
6551 (match_dup 1)))
6552 (clobber (match_scratch:SWI 0 "=<r>"))]
6553 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6554 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "mode" "<MODE>")])
6557
6558 (define_insn "*sub<mode>3_cconly_overflow"
6559 [(set (reg:CCC FLAGS_REG)
6560 (compare:CCC
6561 (minus:SWI
6562 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6563 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6564 (match_dup 0)))]
6565 ""
6566 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6567 [(set_attr "type" "icmp")
6568 (set_attr "mode" "<MODE>")])
6569
6570 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6571 [(set (reg:CCC FLAGS_REG)
6572 (compare:CCC
6573 (plusminus:SWI
6574 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6575 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6576 (match_dup 1)))
6577 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6578 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6579 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6580 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6581 [(set_attr "type" "alu")
6582 (set_attr "mode" "<MODE>")])
6583
6584 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6585 [(set (reg:CCC FLAGS_REG)
6586 (compare:CCC
6587 (plusminus:SI
6588 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6589 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6590 (match_dup 1)))
6591 (set (match_operand:DI 0 "register_operand" "=r")
6592 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6593 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6594 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6595 [(set_attr "type" "alu")
6596 (set_attr "mode" "SI")])
6597
6598 ;; The patterns that match these are at the end of this file.
6599
6600 (define_expand "<plusminus_insn>xf3"
6601 [(set (match_operand:XF 0 "register_operand" "")
6602 (plusminus:XF
6603 (match_operand:XF 1 "register_operand" "")
6604 (match_operand:XF 2 "register_operand" "")))]
6605 "TARGET_80387")
6606
6607 (define_expand "<plusminus_insn><mode>3"
6608 [(set (match_operand:MODEF 0 "register_operand" "")
6609 (plusminus:MODEF
6610 (match_operand:MODEF 1 "register_operand" "")
6611 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6612 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6613 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6614 \f
6615 ;; Multiply instructions
6616
6617 (define_expand "mul<mode>3"
6618 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6619 (mult:SWIM248
6620 (match_operand:SWIM248 1 "register_operand" "")
6621 (match_operand:SWIM248 2 "<general_operand>" "")))
6622 (clobber (reg:CC FLAGS_REG))])])
6623
6624 (define_expand "mulqi3"
6625 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6626 (mult:QI
6627 (match_operand:QI 1 "register_operand" "")
6628 (match_operand:QI 2 "nonimmediate_operand" "")))
6629 (clobber (reg:CC FLAGS_REG))])]
6630 "TARGET_QIMODE_MATH")
6631
6632 ;; On AMDFAM10
6633 ;; IMUL reg32/64, reg32/64, imm8 Direct
6634 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6635 ;; IMUL reg32/64, reg32/64, imm32 Direct
6636 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6637 ;; IMUL reg32/64, reg32/64 Direct
6638 ;; IMUL reg32/64, mem32/64 Direct
6639 ;;
6640 ;; On BDVER1, all above IMULs use DirectPath
6641
6642 (define_insn "*mul<mode>3_1"
6643 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6644 (mult:SWI48
6645 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6646 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6647 (clobber (reg:CC FLAGS_REG))]
6648 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6649 "@
6650 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6651 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6652 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6653 [(set_attr "type" "imul")
6654 (set_attr "prefix_0f" "0,0,1")
6655 (set (attr "athlon_decode")
6656 (cond [(eq_attr "cpu" "athlon")
6657 (const_string "vector")
6658 (eq_attr "alternative" "1")
6659 (const_string "vector")
6660 (and (eq_attr "alternative" "2")
6661 (match_operand 1 "memory_operand" ""))
6662 (const_string "vector")]
6663 (const_string "direct")))
6664 (set (attr "amdfam10_decode")
6665 (cond [(and (eq_attr "alternative" "0,1")
6666 (match_operand 1 "memory_operand" ""))
6667 (const_string "vector")]
6668 (const_string "direct")))
6669 (set_attr "bdver1_decode" "direct")
6670 (set_attr "mode" "<MODE>")])
6671
6672 (define_insn "*mulsi3_1_zext"
6673 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6674 (zero_extend:DI
6675 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6676 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6677 (clobber (reg:CC FLAGS_REG))]
6678 "TARGET_64BIT
6679 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6680 "@
6681 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6682 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6683 imul{l}\t{%2, %k0|%k0, %2}"
6684 [(set_attr "type" "imul")
6685 (set_attr "prefix_0f" "0,0,1")
6686 (set (attr "athlon_decode")
6687 (cond [(eq_attr "cpu" "athlon")
6688 (const_string "vector")
6689 (eq_attr "alternative" "1")
6690 (const_string "vector")
6691 (and (eq_attr "alternative" "2")
6692 (match_operand 1 "memory_operand" ""))
6693 (const_string "vector")]
6694 (const_string "direct")))
6695 (set (attr "amdfam10_decode")
6696 (cond [(and (eq_attr "alternative" "0,1")
6697 (match_operand 1 "memory_operand" ""))
6698 (const_string "vector")]
6699 (const_string "direct")))
6700 (set_attr "bdver1_decode" "direct")
6701 (set_attr "mode" "SI")])
6702
6703 ;; On AMDFAM10
6704 ;; IMUL reg16, reg16, imm8 VectorPath
6705 ;; IMUL reg16, mem16, imm8 VectorPath
6706 ;; IMUL reg16, reg16, imm16 VectorPath
6707 ;; IMUL reg16, mem16, imm16 VectorPath
6708 ;; IMUL reg16, reg16 Direct
6709 ;; IMUL reg16, mem16 Direct
6710 ;;
6711 ;; On BDVER1, all HI MULs use DoublePath
6712
6713 (define_insn "*mulhi3_1"
6714 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6715 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6716 (match_operand:HI 2 "general_operand" "K,n,mr")))
6717 (clobber (reg:CC FLAGS_REG))]
6718 "TARGET_HIMODE_MATH
6719 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6720 "@
6721 imul{w}\t{%2, %1, %0|%0, %1, %2}
6722 imul{w}\t{%2, %1, %0|%0, %1, %2}
6723 imul{w}\t{%2, %0|%0, %2}"
6724 [(set_attr "type" "imul")
6725 (set_attr "prefix_0f" "0,0,1")
6726 (set (attr "athlon_decode")
6727 (cond [(eq_attr "cpu" "athlon")
6728 (const_string "vector")
6729 (eq_attr "alternative" "1,2")
6730 (const_string "vector")]
6731 (const_string "direct")))
6732 (set (attr "amdfam10_decode")
6733 (cond [(eq_attr "alternative" "0,1")
6734 (const_string "vector")]
6735 (const_string "direct")))
6736 (set_attr "bdver1_decode" "double")
6737 (set_attr "mode" "HI")])
6738
6739 ;;On AMDFAM10 and BDVER1
6740 ;; MUL reg8 Direct
6741 ;; MUL mem8 Direct
6742
6743 (define_insn "*mulqi3_1"
6744 [(set (match_operand:QI 0 "register_operand" "=a")
6745 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6746 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6747 (clobber (reg:CC FLAGS_REG))]
6748 "TARGET_QIMODE_MATH
6749 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6750 "mul{b}\t%2"
6751 [(set_attr "type" "imul")
6752 (set_attr "length_immediate" "0")
6753 (set (attr "athlon_decode")
6754 (if_then_else (eq_attr "cpu" "athlon")
6755 (const_string "vector")
6756 (const_string "direct")))
6757 (set_attr "amdfam10_decode" "direct")
6758 (set_attr "bdver1_decode" "direct")
6759 (set_attr "mode" "QI")])
6760
6761 (define_expand "<u>mul<mode><dwi>3"
6762 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6763 (mult:<DWI>
6764 (any_extend:<DWI>
6765 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6766 (any_extend:<DWI>
6767 (match_operand:DWIH 2 "register_operand" ""))))
6768 (clobber (reg:CC FLAGS_REG))])])
6769
6770 (define_expand "<u>mulqihi3"
6771 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6772 (mult:HI
6773 (any_extend:HI
6774 (match_operand:QI 1 "nonimmediate_operand" ""))
6775 (any_extend:HI
6776 (match_operand:QI 2 "register_operand" ""))))
6777 (clobber (reg:CC FLAGS_REG))])]
6778 "TARGET_QIMODE_MATH")
6779
6780 (define_insn "*<u>mul<mode><dwi>3_1"
6781 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6782 (mult:<DWI>
6783 (any_extend:<DWI>
6784 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6785 (any_extend:<DWI>
6786 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6787 (clobber (reg:CC FLAGS_REG))]
6788 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6789 "<sgnprefix>mul{<imodesuffix>}\t%2"
6790 [(set_attr "type" "imul")
6791 (set_attr "length_immediate" "0")
6792 (set (attr "athlon_decode")
6793 (if_then_else (eq_attr "cpu" "athlon")
6794 (const_string "vector")
6795 (const_string "double")))
6796 (set_attr "amdfam10_decode" "double")
6797 (set_attr "bdver1_decode" "direct")
6798 (set_attr "mode" "<MODE>")])
6799
6800 (define_insn "*<u>mulqihi3_1"
6801 [(set (match_operand:HI 0 "register_operand" "=a")
6802 (mult:HI
6803 (any_extend:HI
6804 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6805 (any_extend:HI
6806 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6807 (clobber (reg:CC FLAGS_REG))]
6808 "TARGET_QIMODE_MATH
6809 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6810 "<sgnprefix>mul{b}\t%2"
6811 [(set_attr "type" "imul")
6812 (set_attr "length_immediate" "0")
6813 (set (attr "athlon_decode")
6814 (if_then_else (eq_attr "cpu" "athlon")
6815 (const_string "vector")
6816 (const_string "direct")))
6817 (set_attr "amdfam10_decode" "direct")
6818 (set_attr "bdver1_decode" "direct")
6819 (set_attr "mode" "QI")])
6820
6821 (define_expand "<s>mul<mode>3_highpart"
6822 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6823 (truncate:SWI48
6824 (lshiftrt:<DWI>
6825 (mult:<DWI>
6826 (any_extend:<DWI>
6827 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6828 (any_extend:<DWI>
6829 (match_operand:SWI48 2 "register_operand" "")))
6830 (match_dup 4))))
6831 (clobber (match_scratch:SWI48 3 ""))
6832 (clobber (reg:CC FLAGS_REG))])]
6833 ""
6834 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6835
6836 (define_insn "*<s>muldi3_highpart_1"
6837 [(set (match_operand:DI 0 "register_operand" "=d")
6838 (truncate:DI
6839 (lshiftrt:TI
6840 (mult:TI
6841 (any_extend:TI
6842 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6843 (any_extend:TI
6844 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6845 (const_int 64))))
6846 (clobber (match_scratch:DI 3 "=1"))
6847 (clobber (reg:CC FLAGS_REG))]
6848 "TARGET_64BIT
6849 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6850 "<sgnprefix>mul{q}\t%2"
6851 [(set_attr "type" "imul")
6852 (set_attr "length_immediate" "0")
6853 (set (attr "athlon_decode")
6854 (if_then_else (eq_attr "cpu" "athlon")
6855 (const_string "vector")
6856 (const_string "double")))
6857 (set_attr "amdfam10_decode" "double")
6858 (set_attr "bdver1_decode" "direct")
6859 (set_attr "mode" "DI")])
6860
6861 (define_insn "*<s>mulsi3_highpart_1"
6862 [(set (match_operand:SI 0 "register_operand" "=d")
6863 (truncate:SI
6864 (lshiftrt:DI
6865 (mult:DI
6866 (any_extend:DI
6867 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6868 (any_extend:DI
6869 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6870 (const_int 32))))
6871 (clobber (match_scratch:SI 3 "=1"))
6872 (clobber (reg:CC FLAGS_REG))]
6873 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6874 "<sgnprefix>mul{l}\t%2"
6875 [(set_attr "type" "imul")
6876 (set_attr "length_immediate" "0")
6877 (set (attr "athlon_decode")
6878 (if_then_else (eq_attr "cpu" "athlon")
6879 (const_string "vector")
6880 (const_string "double")))
6881 (set_attr "amdfam10_decode" "double")
6882 (set_attr "bdver1_decode" "direct")
6883 (set_attr "mode" "SI")])
6884
6885 (define_insn "*<s>mulsi3_highpart_zext"
6886 [(set (match_operand:DI 0 "register_operand" "=d")
6887 (zero_extend:DI (truncate:SI
6888 (lshiftrt:DI
6889 (mult:DI (any_extend:DI
6890 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6891 (any_extend:DI
6892 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6893 (const_int 32)))))
6894 (clobber (match_scratch:SI 3 "=1"))
6895 (clobber (reg:CC FLAGS_REG))]
6896 "TARGET_64BIT
6897 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6898 "<sgnprefix>mul{l}\t%2"
6899 [(set_attr "type" "imul")
6900 (set_attr "length_immediate" "0")
6901 (set (attr "athlon_decode")
6902 (if_then_else (eq_attr "cpu" "athlon")
6903 (const_string "vector")
6904 (const_string "double")))
6905 (set_attr "amdfam10_decode" "double")
6906 (set_attr "bdver1_decode" "direct")
6907 (set_attr "mode" "SI")])
6908
6909 ;; The patterns that match these are at the end of this file.
6910
6911 (define_expand "mulxf3"
6912 [(set (match_operand:XF 0 "register_operand" "")
6913 (mult:XF (match_operand:XF 1 "register_operand" "")
6914 (match_operand:XF 2 "register_operand" "")))]
6915 "TARGET_80387")
6916
6917 (define_expand "mul<mode>3"
6918 [(set (match_operand:MODEF 0 "register_operand" "")
6919 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6920 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6921 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6922 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6923 \f
6924 ;; Divide instructions
6925
6926 ;; The patterns that match these are at the end of this file.
6927
6928 (define_expand "divxf3"
6929 [(set (match_operand:XF 0 "register_operand" "")
6930 (div:XF (match_operand:XF 1 "register_operand" "")
6931 (match_operand:XF 2 "register_operand" "")))]
6932 "TARGET_80387")
6933
6934 (define_expand "divdf3"
6935 [(set (match_operand:DF 0 "register_operand" "")
6936 (div:DF (match_operand:DF 1 "register_operand" "")
6937 (match_operand:DF 2 "nonimmediate_operand" "")))]
6938 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6939 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6940
6941 (define_expand "divsf3"
6942 [(set (match_operand:SF 0 "register_operand" "")
6943 (div:SF (match_operand:SF 1 "register_operand" "")
6944 (match_operand:SF 2 "nonimmediate_operand" "")))]
6945 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6946 || TARGET_SSE_MATH"
6947 {
6948 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
6949 && flag_finite_math_only && !flag_trapping_math
6950 && flag_unsafe_math_optimizations)
6951 {
6952 ix86_emit_swdivsf (operands[0], operands[1],
6953 operands[2], SFmode);
6954 DONE;
6955 }
6956 })
6957 \f
6958 ;; Divmod instructions.
6959
6960 (define_expand "divmod<mode>4"
6961 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6962 (div:SWIM248
6963 (match_operand:SWIM248 1 "register_operand" "")
6964 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
6965 (set (match_operand:SWIM248 3 "register_operand" "")
6966 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6967 (clobber (reg:CC FLAGS_REG))])])
6968
6969 ;; Split with 8bit unsigned divide:
6970 ;; if (dividend an divisor are in [0-255])
6971 ;; use 8bit unsigned integer divide
6972 ;; else
6973 ;; use original integer divide
6974 (define_split
6975 [(set (match_operand:SWI48 0 "register_operand" "")
6976 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
6977 (match_operand:SWI48 3 "nonimmediate_operand" "")))
6978 (set (match_operand:SWI48 1 "register_operand" "")
6979 (mod:SWI48 (match_dup 2) (match_dup 3)))
6980 (clobber (reg:CC FLAGS_REG))]
6981 "TARGET_USE_8BIT_IDIV
6982 && TARGET_QIMODE_MATH
6983 && can_create_pseudo_p ()
6984 && !optimize_insn_for_size_p ()"
6985 [(const_int 0)]
6986 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6987
6988 (define_insn_and_split "divmod<mode>4_1"
6989 [(set (match_operand:SWI48 0 "register_operand" "=a")
6990 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6991 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6992 (set (match_operand:SWI48 1 "register_operand" "=&d")
6993 (mod:SWI48 (match_dup 2) (match_dup 3)))
6994 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6995 (clobber (reg:CC FLAGS_REG))]
6996 ""
6997 "#"
6998 "reload_completed"
6999 [(parallel [(set (match_dup 1)
7000 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7001 (clobber (reg:CC FLAGS_REG))])
7002 (parallel [(set (match_dup 0)
7003 (div:SWI48 (match_dup 2) (match_dup 3)))
7004 (set (match_dup 1)
7005 (mod:SWI48 (match_dup 2) (match_dup 3)))
7006 (use (match_dup 1))
7007 (clobber (reg:CC FLAGS_REG))])]
7008 {
7009 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7010
7011 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7012 operands[4] = operands[2];
7013 else
7014 {
7015 /* Avoid use of cltd in favor of a mov+shift. */
7016 emit_move_insn (operands[1], operands[2]);
7017 operands[4] = operands[1];
7018 }
7019 }
7020 [(set_attr "type" "multi")
7021 (set_attr "mode" "<MODE>")])
7022
7023 (define_insn_and_split "*divmod<mode>4"
7024 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7025 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7026 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7027 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7028 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7029 (clobber (reg:CC FLAGS_REG))]
7030 ""
7031 "#"
7032 "reload_completed"
7033 [(parallel [(set (match_dup 1)
7034 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7035 (clobber (reg:CC FLAGS_REG))])
7036 (parallel [(set (match_dup 0)
7037 (div:SWIM248 (match_dup 2) (match_dup 3)))
7038 (set (match_dup 1)
7039 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7040 (use (match_dup 1))
7041 (clobber (reg:CC FLAGS_REG))])]
7042 {
7043 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7044
7045 if (<MODE>mode != HImode
7046 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7047 operands[4] = operands[2];
7048 else
7049 {
7050 /* Avoid use of cltd in favor of a mov+shift. */
7051 emit_move_insn (operands[1], operands[2]);
7052 operands[4] = operands[1];
7053 }
7054 }
7055 [(set_attr "type" "multi")
7056 (set_attr "mode" "<MODE>")])
7057
7058 (define_insn "*divmod<mode>4_noext"
7059 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7060 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7061 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7062 (set (match_operand:SWIM248 1 "register_operand" "=d")
7063 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7064 (use (match_operand:SWIM248 4 "register_operand" "1"))
7065 (clobber (reg:CC FLAGS_REG))]
7066 ""
7067 "idiv{<imodesuffix>}\t%3"
7068 [(set_attr "type" "idiv")
7069 (set_attr "mode" "<MODE>")])
7070
7071 (define_expand "divmodqi4"
7072 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7073 (div:QI
7074 (match_operand:QI 1 "register_operand" "")
7075 (match_operand:QI 2 "nonimmediate_operand" "")))
7076 (set (match_operand:QI 3 "register_operand" "")
7077 (mod:QI (match_dup 1) (match_dup 2)))
7078 (clobber (reg:CC FLAGS_REG))])]
7079 "TARGET_QIMODE_MATH"
7080 {
7081 rtx div, mod, insn;
7082 rtx tmp0, tmp1;
7083
7084 tmp0 = gen_reg_rtx (HImode);
7085 tmp1 = gen_reg_rtx (HImode);
7086
7087 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7088 in AX. */
7089 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7090 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7091
7092 /* Extract remainder from AH. */
7093 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7094 insn = emit_move_insn (operands[3], tmp1);
7095
7096 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7097 set_unique_reg_note (insn, REG_EQUAL, mod);
7098
7099 /* Extract quotient from AL. */
7100 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7101
7102 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7103 set_unique_reg_note (insn, REG_EQUAL, div);
7104
7105 DONE;
7106 })
7107
7108 ;; Divide AX by r/m8, with result stored in
7109 ;; AL <- Quotient
7110 ;; AH <- Remainder
7111 ;; Change div/mod to HImode and extend the second argument to HImode
7112 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7113 ;; combine may fail.
7114 (define_insn "divmodhiqi3"
7115 [(set (match_operand:HI 0 "register_operand" "=a")
7116 (ior:HI
7117 (ashift:HI
7118 (zero_extend:HI
7119 (truncate:QI
7120 (mod:HI (match_operand:HI 1 "register_operand" "0")
7121 (sign_extend:HI
7122 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7123 (const_int 8))
7124 (zero_extend:HI
7125 (truncate:QI
7126 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7127 (clobber (reg:CC FLAGS_REG))]
7128 "TARGET_QIMODE_MATH"
7129 "idiv{b}\t%2"
7130 [(set_attr "type" "idiv")
7131 (set_attr "mode" "QI")])
7132
7133 (define_expand "udivmod<mode>4"
7134 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7135 (udiv:SWIM248
7136 (match_operand:SWIM248 1 "register_operand" "")
7137 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7138 (set (match_operand:SWIM248 3 "register_operand" "")
7139 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7140 (clobber (reg:CC FLAGS_REG))])])
7141
7142 ;; Split with 8bit unsigned divide:
7143 ;; if (dividend an divisor are in [0-255])
7144 ;; use 8bit unsigned integer divide
7145 ;; else
7146 ;; use original integer divide
7147 (define_split
7148 [(set (match_operand:SWI48 0 "register_operand" "")
7149 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7150 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7151 (set (match_operand:SWI48 1 "register_operand" "")
7152 (umod:SWI48 (match_dup 2) (match_dup 3)))
7153 (clobber (reg:CC FLAGS_REG))]
7154 "TARGET_USE_8BIT_IDIV
7155 && TARGET_QIMODE_MATH
7156 && can_create_pseudo_p ()
7157 && !optimize_insn_for_size_p ()"
7158 [(const_int 0)]
7159 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7160
7161 (define_insn_and_split "udivmod<mode>4_1"
7162 [(set (match_operand:SWI48 0 "register_operand" "=a")
7163 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7164 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7165 (set (match_operand:SWI48 1 "register_operand" "=&d")
7166 (umod:SWI48 (match_dup 2) (match_dup 3)))
7167 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7168 (clobber (reg:CC FLAGS_REG))]
7169 ""
7170 "#"
7171 "reload_completed"
7172 [(set (match_dup 1) (const_int 0))
7173 (parallel [(set (match_dup 0)
7174 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7175 (set (match_dup 1)
7176 (umod:SWI48 (match_dup 2) (match_dup 3)))
7177 (use (match_dup 1))
7178 (clobber (reg:CC FLAGS_REG))])]
7179 ""
7180 [(set_attr "type" "multi")
7181 (set_attr "mode" "<MODE>")])
7182
7183 (define_insn_and_split "*udivmod<mode>4"
7184 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7185 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7186 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7187 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7188 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7189 (clobber (reg:CC FLAGS_REG))]
7190 ""
7191 "#"
7192 "reload_completed"
7193 [(set (match_dup 1) (const_int 0))
7194 (parallel [(set (match_dup 0)
7195 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7196 (set (match_dup 1)
7197 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7198 (use (match_dup 1))
7199 (clobber (reg:CC FLAGS_REG))])]
7200 ""
7201 [(set_attr "type" "multi")
7202 (set_attr "mode" "<MODE>")])
7203
7204 (define_insn "*udivmod<mode>4_noext"
7205 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7206 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7207 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7208 (set (match_operand:SWIM248 1 "register_operand" "=d")
7209 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7210 (use (match_operand:SWIM248 4 "register_operand" "1"))
7211 (clobber (reg:CC FLAGS_REG))]
7212 ""
7213 "div{<imodesuffix>}\t%3"
7214 [(set_attr "type" "idiv")
7215 (set_attr "mode" "<MODE>")])
7216
7217 (define_expand "udivmodqi4"
7218 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7219 (udiv:QI
7220 (match_operand:QI 1 "register_operand" "")
7221 (match_operand:QI 2 "nonimmediate_operand" "")))
7222 (set (match_operand:QI 3 "register_operand" "")
7223 (umod:QI (match_dup 1) (match_dup 2)))
7224 (clobber (reg:CC FLAGS_REG))])]
7225 "TARGET_QIMODE_MATH"
7226 {
7227 rtx div, mod, insn;
7228 rtx tmp0, tmp1;
7229
7230 tmp0 = gen_reg_rtx (HImode);
7231 tmp1 = gen_reg_rtx (HImode);
7232
7233 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7234 in AX. */
7235 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7236 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7237
7238 /* Extract remainder from AH. */
7239 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7240 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7241 insn = emit_move_insn (operands[3], tmp1);
7242
7243 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7244 set_unique_reg_note (insn, REG_EQUAL, mod);
7245
7246 /* Extract quotient from AL. */
7247 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7248
7249 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7250 set_unique_reg_note (insn, REG_EQUAL, div);
7251
7252 DONE;
7253 })
7254
7255 (define_insn "udivmodhiqi3"
7256 [(set (match_operand:HI 0 "register_operand" "=a")
7257 (ior:HI
7258 (ashift:HI
7259 (zero_extend:HI
7260 (truncate:QI
7261 (mod:HI (match_operand:HI 1 "register_operand" "0")
7262 (zero_extend:HI
7263 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7264 (const_int 8))
7265 (zero_extend:HI
7266 (truncate:QI
7267 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7268 (clobber (reg:CC FLAGS_REG))]
7269 "TARGET_QIMODE_MATH"
7270 "div{b}\t%2"
7271 [(set_attr "type" "idiv")
7272 (set_attr "mode" "QI")])
7273
7274 ;; We cannot use div/idiv for double division, because it causes
7275 ;; "division by zero" on the overflow and that's not what we expect
7276 ;; from truncate. Because true (non truncating) double division is
7277 ;; never generated, we can't create this insn anyway.
7278 ;
7279 ;(define_insn ""
7280 ; [(set (match_operand:SI 0 "register_operand" "=a")
7281 ; (truncate:SI
7282 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7283 ; (zero_extend:DI
7284 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7285 ; (set (match_operand:SI 3 "register_operand" "=d")
7286 ; (truncate:SI
7287 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7288 ; (clobber (reg:CC FLAGS_REG))]
7289 ; ""
7290 ; "div{l}\t{%2, %0|%0, %2}"
7291 ; [(set_attr "type" "idiv")])
7292 \f
7293 ;;- Logical AND instructions
7294
7295 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7296 ;; Note that this excludes ah.
7297
7298 (define_expand "testsi_ccno_1"
7299 [(set (reg:CCNO FLAGS_REG)
7300 (compare:CCNO
7301 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7302 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7303 (const_int 0)))])
7304
7305 (define_expand "testqi_ccz_1"
7306 [(set (reg:CCZ FLAGS_REG)
7307 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7308 (match_operand:QI 1 "nonmemory_operand" ""))
7309 (const_int 0)))])
7310
7311 (define_expand "testdi_ccno_1"
7312 [(set (reg:CCNO FLAGS_REG)
7313 (compare:CCNO
7314 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7315 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7316 (const_int 0)))]
7317 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7318
7319 (define_insn "*testdi_1"
7320 [(set (reg FLAGS_REG)
7321 (compare
7322 (and:DI
7323 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7324 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7325 (const_int 0)))]
7326 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7327 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7328 "@
7329 test{l}\t{%k1, %k0|%k0, %k1}
7330 test{l}\t{%k1, %k0|%k0, %k1}
7331 test{q}\t{%1, %0|%0, %1}
7332 test{q}\t{%1, %0|%0, %1}
7333 test{q}\t{%1, %0|%0, %1}"
7334 [(set_attr "type" "test")
7335 (set_attr "modrm" "0,1,0,1,1")
7336 (set_attr "mode" "SI,SI,DI,DI,DI")])
7337
7338 (define_insn "*testqi_1_maybe_si"
7339 [(set (reg FLAGS_REG)
7340 (compare
7341 (and:QI
7342 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7343 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7344 (const_int 0)))]
7345 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7346 && ix86_match_ccmode (insn,
7347 CONST_INT_P (operands[1])
7348 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7349 {
7350 if (which_alternative == 3)
7351 {
7352 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7353 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7354 return "test{l}\t{%1, %k0|%k0, %1}";
7355 }
7356 return "test{b}\t{%1, %0|%0, %1}";
7357 }
7358 [(set_attr "type" "test")
7359 (set_attr "modrm" "0,1,1,1")
7360 (set_attr "mode" "QI,QI,QI,SI")
7361 (set_attr "pent_pair" "uv,np,uv,np")])
7362
7363 (define_insn "*test<mode>_1"
7364 [(set (reg FLAGS_REG)
7365 (compare
7366 (and:SWI124
7367 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7368 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7369 (const_int 0)))]
7370 "ix86_match_ccmode (insn, CCNOmode)
7371 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7372 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7373 [(set_attr "type" "test")
7374 (set_attr "modrm" "0,1,1")
7375 (set_attr "mode" "<MODE>")
7376 (set_attr "pent_pair" "uv,np,uv")])
7377
7378 (define_expand "testqi_ext_ccno_0"
7379 [(set (reg:CCNO FLAGS_REG)
7380 (compare:CCNO
7381 (and:SI
7382 (zero_extract:SI
7383 (match_operand 0 "ext_register_operand" "")
7384 (const_int 8)
7385 (const_int 8))
7386 (match_operand 1 "const_int_operand" ""))
7387 (const_int 0)))])
7388
7389 (define_insn "*testqi_ext_0"
7390 [(set (reg FLAGS_REG)
7391 (compare
7392 (and:SI
7393 (zero_extract:SI
7394 (match_operand 0 "ext_register_operand" "Q")
7395 (const_int 8)
7396 (const_int 8))
7397 (match_operand 1 "const_int_operand" "n"))
7398 (const_int 0)))]
7399 "ix86_match_ccmode (insn, CCNOmode)"
7400 "test{b}\t{%1, %h0|%h0, %1}"
7401 [(set_attr "type" "test")
7402 (set_attr "mode" "QI")
7403 (set_attr "length_immediate" "1")
7404 (set_attr "modrm" "1")
7405 (set_attr "pent_pair" "np")])
7406
7407 (define_insn "*testqi_ext_1_rex64"
7408 [(set (reg FLAGS_REG)
7409 (compare
7410 (and:SI
7411 (zero_extract:SI
7412 (match_operand 0 "ext_register_operand" "Q")
7413 (const_int 8)
7414 (const_int 8))
7415 (zero_extend:SI
7416 (match_operand:QI 1 "register_operand" "Q")))
7417 (const_int 0)))]
7418 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7419 "test{b}\t{%1, %h0|%h0, %1}"
7420 [(set_attr "type" "test")
7421 (set_attr "mode" "QI")])
7422
7423 (define_insn "*testqi_ext_1"
7424 [(set (reg FLAGS_REG)
7425 (compare
7426 (and:SI
7427 (zero_extract:SI
7428 (match_operand 0 "ext_register_operand" "Q")
7429 (const_int 8)
7430 (const_int 8))
7431 (zero_extend:SI
7432 (match_operand:QI 1 "general_operand" "Qm")))
7433 (const_int 0)))]
7434 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7435 "test{b}\t{%1, %h0|%h0, %1}"
7436 [(set_attr "type" "test")
7437 (set_attr "mode" "QI")])
7438
7439 (define_insn "*testqi_ext_2"
7440 [(set (reg FLAGS_REG)
7441 (compare
7442 (and:SI
7443 (zero_extract:SI
7444 (match_operand 0 "ext_register_operand" "Q")
7445 (const_int 8)
7446 (const_int 8))
7447 (zero_extract:SI
7448 (match_operand 1 "ext_register_operand" "Q")
7449 (const_int 8)
7450 (const_int 8)))
7451 (const_int 0)))]
7452 "ix86_match_ccmode (insn, CCNOmode)"
7453 "test{b}\t{%h1, %h0|%h0, %h1}"
7454 [(set_attr "type" "test")
7455 (set_attr "mode" "QI")])
7456
7457 (define_insn "*testqi_ext_3_rex64"
7458 [(set (reg FLAGS_REG)
7459 (compare (zero_extract:DI
7460 (match_operand 0 "nonimmediate_operand" "rm")
7461 (match_operand:DI 1 "const_int_operand" "")
7462 (match_operand:DI 2 "const_int_operand" ""))
7463 (const_int 0)))]
7464 "TARGET_64BIT
7465 && ix86_match_ccmode (insn, CCNOmode)
7466 && INTVAL (operands[1]) > 0
7467 && INTVAL (operands[2]) >= 0
7468 /* Ensure that resulting mask is zero or sign extended operand. */
7469 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7470 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7471 && INTVAL (operands[1]) > 32))
7472 && (GET_MODE (operands[0]) == SImode
7473 || GET_MODE (operands[0]) == DImode
7474 || GET_MODE (operands[0]) == HImode
7475 || GET_MODE (operands[0]) == QImode)"
7476 "#")
7477
7478 ;; Combine likes to form bit extractions for some tests. Humor it.
7479 (define_insn "*testqi_ext_3"
7480 [(set (reg FLAGS_REG)
7481 (compare (zero_extract:SI
7482 (match_operand 0 "nonimmediate_operand" "rm")
7483 (match_operand:SI 1 "const_int_operand" "")
7484 (match_operand:SI 2 "const_int_operand" ""))
7485 (const_int 0)))]
7486 "ix86_match_ccmode (insn, CCNOmode)
7487 && INTVAL (operands[1]) > 0
7488 && INTVAL (operands[2]) >= 0
7489 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7490 && (GET_MODE (operands[0]) == SImode
7491 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7492 || GET_MODE (operands[0]) == HImode
7493 || GET_MODE (operands[0]) == QImode)"
7494 "#")
7495
7496 (define_split
7497 [(set (match_operand 0 "flags_reg_operand" "")
7498 (match_operator 1 "compare_operator"
7499 [(zero_extract
7500 (match_operand 2 "nonimmediate_operand" "")
7501 (match_operand 3 "const_int_operand" "")
7502 (match_operand 4 "const_int_operand" ""))
7503 (const_int 0)]))]
7504 "ix86_match_ccmode (insn, CCNOmode)"
7505 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7506 {
7507 rtx val = operands[2];
7508 HOST_WIDE_INT len = INTVAL (operands[3]);
7509 HOST_WIDE_INT pos = INTVAL (operands[4]);
7510 HOST_WIDE_INT mask;
7511 enum machine_mode mode, submode;
7512
7513 mode = GET_MODE (val);
7514 if (MEM_P (val))
7515 {
7516 /* ??? Combine likes to put non-volatile mem extractions in QImode
7517 no matter the size of the test. So find a mode that works. */
7518 if (! MEM_VOLATILE_P (val))
7519 {
7520 mode = smallest_mode_for_size (pos + len, MODE_INT);
7521 val = adjust_address (val, mode, 0);
7522 }
7523 }
7524 else if (GET_CODE (val) == SUBREG
7525 && (submode = GET_MODE (SUBREG_REG (val)),
7526 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7527 && pos + len <= GET_MODE_BITSIZE (submode)
7528 && GET_MODE_CLASS (submode) == MODE_INT)
7529 {
7530 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7531 mode = submode;
7532 val = SUBREG_REG (val);
7533 }
7534 else if (mode == HImode && pos + len <= 8)
7535 {
7536 /* Small HImode tests can be converted to QImode. */
7537 mode = QImode;
7538 val = gen_lowpart (QImode, val);
7539 }
7540
7541 if (len == HOST_BITS_PER_WIDE_INT)
7542 mask = -1;
7543 else
7544 mask = ((HOST_WIDE_INT)1 << len) - 1;
7545 mask <<= pos;
7546
7547 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7548 })
7549
7550 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7551 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7552 ;; this is relatively important trick.
7553 ;; Do the conversion only post-reload to avoid limiting of the register class
7554 ;; to QI regs.
7555 (define_split
7556 [(set (match_operand 0 "flags_reg_operand" "")
7557 (match_operator 1 "compare_operator"
7558 [(and (match_operand 2 "register_operand" "")
7559 (match_operand 3 "const_int_operand" ""))
7560 (const_int 0)]))]
7561 "reload_completed
7562 && QI_REG_P (operands[2])
7563 && GET_MODE (operands[2]) != QImode
7564 && ((ix86_match_ccmode (insn, CCZmode)
7565 && !(INTVAL (operands[3]) & ~(255 << 8)))
7566 || (ix86_match_ccmode (insn, CCNOmode)
7567 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7568 [(set (match_dup 0)
7569 (match_op_dup 1
7570 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7571 (match_dup 3))
7572 (const_int 0)]))]
7573 "operands[2] = gen_lowpart (SImode, operands[2]);
7574 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7575
7576 (define_split
7577 [(set (match_operand 0 "flags_reg_operand" "")
7578 (match_operator 1 "compare_operator"
7579 [(and (match_operand 2 "nonimmediate_operand" "")
7580 (match_operand 3 "const_int_operand" ""))
7581 (const_int 0)]))]
7582 "reload_completed
7583 && GET_MODE (operands[2]) != QImode
7584 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7585 && ((ix86_match_ccmode (insn, CCZmode)
7586 && !(INTVAL (operands[3]) & ~255))
7587 || (ix86_match_ccmode (insn, CCNOmode)
7588 && !(INTVAL (operands[3]) & ~127)))"
7589 [(set (match_dup 0)
7590 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7591 (const_int 0)]))]
7592 "operands[2] = gen_lowpart (QImode, operands[2]);
7593 operands[3] = gen_lowpart (QImode, operands[3]);")
7594
7595 ;; %%% This used to optimize known byte-wide and operations to memory,
7596 ;; and sometimes to QImode registers. If this is considered useful,
7597 ;; it should be done with splitters.
7598
7599 (define_expand "and<mode>3"
7600 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7601 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7602 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7603 ""
7604 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7605
7606 (define_insn "*anddi_1"
7607 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7608 (and:DI
7609 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7610 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7611 (clobber (reg:CC FLAGS_REG))]
7612 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7613 {
7614 switch (get_attr_type (insn))
7615 {
7616 case TYPE_IMOVX:
7617 {
7618 enum machine_mode mode;
7619
7620 gcc_assert (CONST_INT_P (operands[2]));
7621 if (INTVAL (operands[2]) == 0xff)
7622 mode = QImode;
7623 else
7624 {
7625 gcc_assert (INTVAL (operands[2]) == 0xffff);
7626 mode = HImode;
7627 }
7628
7629 operands[1] = gen_lowpart (mode, operands[1]);
7630 if (mode == QImode)
7631 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7632 else
7633 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7634 }
7635
7636 default:
7637 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7638 if (get_attr_mode (insn) == MODE_SI)
7639 return "and{l}\t{%k2, %k0|%k0, %k2}";
7640 else
7641 return "and{q}\t{%2, %0|%0, %2}";
7642 }
7643 }
7644 [(set_attr "type" "alu,alu,alu,imovx")
7645 (set_attr "length_immediate" "*,*,*,0")
7646 (set (attr "prefix_rex")
7647 (if_then_else
7648 (and (eq_attr "type" "imovx")
7649 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7650 (match_operand 1 "ext_QIreg_operand" "")))
7651 (const_string "1")
7652 (const_string "*")))
7653 (set_attr "mode" "SI,DI,DI,SI")])
7654
7655 (define_insn "*andsi_1"
7656 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7657 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7658 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7659 (clobber (reg:CC FLAGS_REG))]
7660 "ix86_binary_operator_ok (AND, SImode, operands)"
7661 {
7662 switch (get_attr_type (insn))
7663 {
7664 case TYPE_IMOVX:
7665 {
7666 enum machine_mode mode;
7667
7668 gcc_assert (CONST_INT_P (operands[2]));
7669 if (INTVAL (operands[2]) == 0xff)
7670 mode = QImode;
7671 else
7672 {
7673 gcc_assert (INTVAL (operands[2]) == 0xffff);
7674 mode = HImode;
7675 }
7676
7677 operands[1] = gen_lowpart (mode, operands[1]);
7678 if (mode == QImode)
7679 return "movz{bl|x}\t{%1, %0|%0, %1}";
7680 else
7681 return "movz{wl|x}\t{%1, %0|%0, %1}";
7682 }
7683
7684 default:
7685 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7686 return "and{l}\t{%2, %0|%0, %2}";
7687 }
7688 }
7689 [(set_attr "type" "alu,alu,imovx")
7690 (set (attr "prefix_rex")
7691 (if_then_else
7692 (and (eq_attr "type" "imovx")
7693 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7694 (match_operand 1 "ext_QIreg_operand" "")))
7695 (const_string "1")
7696 (const_string "*")))
7697 (set_attr "length_immediate" "*,*,0")
7698 (set_attr "mode" "SI")])
7699
7700 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7701 (define_insn "*andsi_1_zext"
7702 [(set (match_operand:DI 0 "register_operand" "=r")
7703 (zero_extend:DI
7704 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7705 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7706 (clobber (reg:CC FLAGS_REG))]
7707 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7708 "and{l}\t{%2, %k0|%k0, %2}"
7709 [(set_attr "type" "alu")
7710 (set_attr "mode" "SI")])
7711
7712 (define_insn "*andhi_1"
7713 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7714 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7715 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7716 (clobber (reg:CC FLAGS_REG))]
7717 "ix86_binary_operator_ok (AND, HImode, operands)"
7718 {
7719 switch (get_attr_type (insn))
7720 {
7721 case TYPE_IMOVX:
7722 gcc_assert (CONST_INT_P (operands[2]));
7723 gcc_assert (INTVAL (operands[2]) == 0xff);
7724 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7725
7726 default:
7727 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7728
7729 return "and{w}\t{%2, %0|%0, %2}";
7730 }
7731 }
7732 [(set_attr "type" "alu,alu,imovx")
7733 (set_attr "length_immediate" "*,*,0")
7734 (set (attr "prefix_rex")
7735 (if_then_else
7736 (and (eq_attr "type" "imovx")
7737 (match_operand 1 "ext_QIreg_operand" ""))
7738 (const_string "1")
7739 (const_string "*")))
7740 (set_attr "mode" "HI,HI,SI")])
7741
7742 ;; %%% Potential partial reg stall on alternative 2. What to do?
7743 (define_insn "*andqi_1"
7744 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7745 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7746 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7747 (clobber (reg:CC FLAGS_REG))]
7748 "ix86_binary_operator_ok (AND, QImode, operands)"
7749 "@
7750 and{b}\t{%2, %0|%0, %2}
7751 and{b}\t{%2, %0|%0, %2}
7752 and{l}\t{%k2, %k0|%k0, %k2}"
7753 [(set_attr "type" "alu")
7754 (set_attr "mode" "QI,QI,SI")])
7755
7756 (define_insn "*andqi_1_slp"
7757 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7758 (and:QI (match_dup 0)
7759 (match_operand:QI 1 "general_operand" "qn,qmn")))
7760 (clobber (reg:CC FLAGS_REG))]
7761 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7762 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7763 "and{b}\t{%1, %0|%0, %1}"
7764 [(set_attr "type" "alu1")
7765 (set_attr "mode" "QI")])
7766
7767 (define_split
7768 [(set (match_operand 0 "register_operand" "")
7769 (and (match_dup 0)
7770 (const_int -65536)))
7771 (clobber (reg:CC FLAGS_REG))]
7772 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7773 || optimize_function_for_size_p (cfun)"
7774 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7775 "operands[1] = gen_lowpart (HImode, operands[0]);")
7776
7777 (define_split
7778 [(set (match_operand 0 "ext_register_operand" "")
7779 (and (match_dup 0)
7780 (const_int -256)))
7781 (clobber (reg:CC FLAGS_REG))]
7782 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7783 && reload_completed"
7784 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7785 "operands[1] = gen_lowpart (QImode, operands[0]);")
7786
7787 (define_split
7788 [(set (match_operand 0 "ext_register_operand" "")
7789 (and (match_dup 0)
7790 (const_int -65281)))
7791 (clobber (reg:CC FLAGS_REG))]
7792 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7793 && reload_completed"
7794 [(parallel [(set (zero_extract:SI (match_dup 0)
7795 (const_int 8)
7796 (const_int 8))
7797 (xor:SI
7798 (zero_extract:SI (match_dup 0)
7799 (const_int 8)
7800 (const_int 8))
7801 (zero_extract:SI (match_dup 0)
7802 (const_int 8)
7803 (const_int 8))))
7804 (clobber (reg:CC FLAGS_REG))])]
7805 "operands[0] = gen_lowpart (SImode, operands[0]);")
7806
7807 (define_insn "*anddi_2"
7808 [(set (reg FLAGS_REG)
7809 (compare
7810 (and:DI
7811 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7812 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7813 (const_int 0)))
7814 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7815 (and:DI (match_dup 1) (match_dup 2)))]
7816 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7817 && ix86_binary_operator_ok (AND, DImode, operands)"
7818 "@
7819 and{l}\t{%k2, %k0|%k0, %k2}
7820 and{q}\t{%2, %0|%0, %2}
7821 and{q}\t{%2, %0|%0, %2}"
7822 [(set_attr "type" "alu")
7823 (set_attr "mode" "SI,DI,DI")])
7824
7825 (define_insn "*andqi_2_maybe_si"
7826 [(set (reg FLAGS_REG)
7827 (compare (and:QI
7828 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7829 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7830 (const_int 0)))
7831 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7832 (and:QI (match_dup 1) (match_dup 2)))]
7833 "ix86_binary_operator_ok (AND, QImode, operands)
7834 && ix86_match_ccmode (insn,
7835 CONST_INT_P (operands[2])
7836 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7837 {
7838 if (which_alternative == 2)
7839 {
7840 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7841 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7842 return "and{l}\t{%2, %k0|%k0, %2}";
7843 }
7844 return "and{b}\t{%2, %0|%0, %2}";
7845 }
7846 [(set_attr "type" "alu")
7847 (set_attr "mode" "QI,QI,SI")])
7848
7849 (define_insn "*and<mode>_2"
7850 [(set (reg FLAGS_REG)
7851 (compare (and:SWI124
7852 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7853 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7854 (const_int 0)))
7855 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7856 (and:SWI124 (match_dup 1) (match_dup 2)))]
7857 "ix86_match_ccmode (insn, CCNOmode)
7858 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7859 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7860 [(set_attr "type" "alu")
7861 (set_attr "mode" "<MODE>")])
7862
7863 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7864 (define_insn "*andsi_2_zext"
7865 [(set (reg FLAGS_REG)
7866 (compare (and:SI
7867 (match_operand:SI 1 "nonimmediate_operand" "%0")
7868 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7869 (const_int 0)))
7870 (set (match_operand:DI 0 "register_operand" "=r")
7871 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7872 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7873 && ix86_binary_operator_ok (AND, SImode, operands)"
7874 "and{l}\t{%2, %k0|%k0, %2}"
7875 [(set_attr "type" "alu")
7876 (set_attr "mode" "SI")])
7877
7878 (define_insn "*andqi_2_slp"
7879 [(set (reg FLAGS_REG)
7880 (compare (and:QI
7881 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7882 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7883 (const_int 0)))
7884 (set (strict_low_part (match_dup 0))
7885 (and:QI (match_dup 0) (match_dup 1)))]
7886 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7887 && ix86_match_ccmode (insn, CCNOmode)
7888 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7889 "and{b}\t{%1, %0|%0, %1}"
7890 [(set_attr "type" "alu1")
7891 (set_attr "mode" "QI")])
7892
7893 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7894 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7895 ;; for a QImode operand, which of course failed.
7896 (define_insn "andqi_ext_0"
7897 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7898 (const_int 8)
7899 (const_int 8))
7900 (and:SI
7901 (zero_extract:SI
7902 (match_operand 1 "ext_register_operand" "0")
7903 (const_int 8)
7904 (const_int 8))
7905 (match_operand 2 "const_int_operand" "n")))
7906 (clobber (reg:CC FLAGS_REG))]
7907 ""
7908 "and{b}\t{%2, %h0|%h0, %2}"
7909 [(set_attr "type" "alu")
7910 (set_attr "length_immediate" "1")
7911 (set_attr "modrm" "1")
7912 (set_attr "mode" "QI")])
7913
7914 ;; Generated by peephole translating test to and. This shows up
7915 ;; often in fp comparisons.
7916 (define_insn "*andqi_ext_0_cc"
7917 [(set (reg FLAGS_REG)
7918 (compare
7919 (and:SI
7920 (zero_extract:SI
7921 (match_operand 1 "ext_register_operand" "0")
7922 (const_int 8)
7923 (const_int 8))
7924 (match_operand 2 "const_int_operand" "n"))
7925 (const_int 0)))
7926 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7927 (const_int 8)
7928 (const_int 8))
7929 (and:SI
7930 (zero_extract:SI
7931 (match_dup 1)
7932 (const_int 8)
7933 (const_int 8))
7934 (match_dup 2)))]
7935 "ix86_match_ccmode (insn, CCNOmode)"
7936 "and{b}\t{%2, %h0|%h0, %2}"
7937 [(set_attr "type" "alu")
7938 (set_attr "length_immediate" "1")
7939 (set_attr "modrm" "1")
7940 (set_attr "mode" "QI")])
7941
7942 (define_insn "*andqi_ext_1_rex64"
7943 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7944 (const_int 8)
7945 (const_int 8))
7946 (and:SI
7947 (zero_extract:SI
7948 (match_operand 1 "ext_register_operand" "0")
7949 (const_int 8)
7950 (const_int 8))
7951 (zero_extend:SI
7952 (match_operand 2 "ext_register_operand" "Q"))))
7953 (clobber (reg:CC FLAGS_REG))]
7954 "TARGET_64BIT"
7955 "and{b}\t{%2, %h0|%h0, %2}"
7956 [(set_attr "type" "alu")
7957 (set_attr "length_immediate" "0")
7958 (set_attr "mode" "QI")])
7959
7960 (define_insn "*andqi_ext_1"
7961 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7962 (const_int 8)
7963 (const_int 8))
7964 (and:SI
7965 (zero_extract:SI
7966 (match_operand 1 "ext_register_operand" "0")
7967 (const_int 8)
7968 (const_int 8))
7969 (zero_extend:SI
7970 (match_operand:QI 2 "general_operand" "Qm"))))
7971 (clobber (reg:CC FLAGS_REG))]
7972 "!TARGET_64BIT"
7973 "and{b}\t{%2, %h0|%h0, %2}"
7974 [(set_attr "type" "alu")
7975 (set_attr "length_immediate" "0")
7976 (set_attr "mode" "QI")])
7977
7978 (define_insn "*andqi_ext_2"
7979 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7980 (const_int 8)
7981 (const_int 8))
7982 (and:SI
7983 (zero_extract:SI
7984 (match_operand 1 "ext_register_operand" "%0")
7985 (const_int 8)
7986 (const_int 8))
7987 (zero_extract:SI
7988 (match_operand 2 "ext_register_operand" "Q")
7989 (const_int 8)
7990 (const_int 8))))
7991 (clobber (reg:CC FLAGS_REG))]
7992 ""
7993 "and{b}\t{%h2, %h0|%h0, %h2}"
7994 [(set_attr "type" "alu")
7995 (set_attr "length_immediate" "0")
7996 (set_attr "mode" "QI")])
7997
7998 ;; Convert wide AND instructions with immediate operand to shorter QImode
7999 ;; equivalents when possible.
8000 ;; Don't do the splitting with memory operands, since it introduces risk
8001 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8002 ;; for size, but that can (should?) be handled by generic code instead.
8003 (define_split
8004 [(set (match_operand 0 "register_operand" "")
8005 (and (match_operand 1 "register_operand" "")
8006 (match_operand 2 "const_int_operand" "")))
8007 (clobber (reg:CC FLAGS_REG))]
8008 "reload_completed
8009 && QI_REG_P (operands[0])
8010 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8011 && !(~INTVAL (operands[2]) & ~(255 << 8))
8012 && GET_MODE (operands[0]) != QImode"
8013 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8014 (and:SI (zero_extract:SI (match_dup 1)
8015 (const_int 8) (const_int 8))
8016 (match_dup 2)))
8017 (clobber (reg:CC FLAGS_REG))])]
8018 "operands[0] = gen_lowpart (SImode, operands[0]);
8019 operands[1] = gen_lowpart (SImode, operands[1]);
8020 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8021
8022 ;; Since AND can be encoded with sign extended immediate, this is only
8023 ;; profitable when 7th bit is not set.
8024 (define_split
8025 [(set (match_operand 0 "register_operand" "")
8026 (and (match_operand 1 "general_operand" "")
8027 (match_operand 2 "const_int_operand" "")))
8028 (clobber (reg:CC FLAGS_REG))]
8029 "reload_completed
8030 && ANY_QI_REG_P (operands[0])
8031 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8032 && !(~INTVAL (operands[2]) & ~255)
8033 && !(INTVAL (operands[2]) & 128)
8034 && GET_MODE (operands[0]) != QImode"
8035 [(parallel [(set (strict_low_part (match_dup 0))
8036 (and:QI (match_dup 1)
8037 (match_dup 2)))
8038 (clobber (reg:CC FLAGS_REG))])]
8039 "operands[0] = gen_lowpart (QImode, operands[0]);
8040 operands[1] = gen_lowpart (QImode, operands[1]);
8041 operands[2] = gen_lowpart (QImode, operands[2]);")
8042 \f
8043 ;; Logical inclusive and exclusive OR instructions
8044
8045 ;; %%% This used to optimize known byte-wide and operations to memory.
8046 ;; If this is considered useful, it should be done with splitters.
8047
8048 (define_expand "<code><mode>3"
8049 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8050 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8051 (match_operand:SWIM 2 "<general_operand>" "")))]
8052 ""
8053 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8054
8055 (define_insn "*<code><mode>_1"
8056 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8057 (any_or:SWI248
8058 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8059 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8060 (clobber (reg:CC FLAGS_REG))]
8061 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8062 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8063 [(set_attr "type" "alu")
8064 (set_attr "mode" "<MODE>")])
8065
8066 ;; %%% Potential partial reg stall on alternative 2. What to do?
8067 (define_insn "*<code>qi_1"
8068 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8069 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8070 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8071 (clobber (reg:CC FLAGS_REG))]
8072 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8073 "@
8074 <logic>{b}\t{%2, %0|%0, %2}
8075 <logic>{b}\t{%2, %0|%0, %2}
8076 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8077 [(set_attr "type" "alu")
8078 (set_attr "mode" "QI,QI,SI")])
8079
8080 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8081 (define_insn "*<code>si_1_zext"
8082 [(set (match_operand:DI 0 "register_operand" "=r")
8083 (zero_extend:DI
8084 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8085 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8086 (clobber (reg:CC FLAGS_REG))]
8087 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8088 "<logic>{l}\t{%2, %k0|%k0, %2}"
8089 [(set_attr "type" "alu")
8090 (set_attr "mode" "SI")])
8091
8092 (define_insn "*<code>si_1_zext_imm"
8093 [(set (match_operand:DI 0 "register_operand" "=r")
8094 (any_or:DI
8095 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8096 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8097 (clobber (reg:CC FLAGS_REG))]
8098 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8099 "<logic>{l}\t{%2, %k0|%k0, %2}"
8100 [(set_attr "type" "alu")
8101 (set_attr "mode" "SI")])
8102
8103 (define_insn "*<code>qi_1_slp"
8104 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8105 (any_or:QI (match_dup 0)
8106 (match_operand:QI 1 "general_operand" "qmn,qn")))
8107 (clobber (reg:CC FLAGS_REG))]
8108 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8109 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8110 "<logic>{b}\t{%1, %0|%0, %1}"
8111 [(set_attr "type" "alu1")
8112 (set_attr "mode" "QI")])
8113
8114 (define_insn "*<code><mode>_2"
8115 [(set (reg FLAGS_REG)
8116 (compare (any_or:SWI
8117 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8118 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8119 (const_int 0)))
8120 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8121 (any_or:SWI (match_dup 1) (match_dup 2)))]
8122 "ix86_match_ccmode (insn, CCNOmode)
8123 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8124 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8125 [(set_attr "type" "alu")
8126 (set_attr "mode" "<MODE>")])
8127
8128 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8129 ;; ??? Special case for immediate operand is missing - it is tricky.
8130 (define_insn "*<code>si_2_zext"
8131 [(set (reg FLAGS_REG)
8132 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8133 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8134 (const_int 0)))
8135 (set (match_operand:DI 0 "register_operand" "=r")
8136 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8137 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8138 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8139 "<logic>{l}\t{%2, %k0|%k0, %2}"
8140 [(set_attr "type" "alu")
8141 (set_attr "mode" "SI")])
8142
8143 (define_insn "*<code>si_2_zext_imm"
8144 [(set (reg FLAGS_REG)
8145 (compare (any_or:SI
8146 (match_operand:SI 1 "nonimmediate_operand" "%0")
8147 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8148 (const_int 0)))
8149 (set (match_operand:DI 0 "register_operand" "=r")
8150 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8151 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8152 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8153 "<logic>{l}\t{%2, %k0|%k0, %2}"
8154 [(set_attr "type" "alu")
8155 (set_attr "mode" "SI")])
8156
8157 (define_insn "*<code>qi_2_slp"
8158 [(set (reg FLAGS_REG)
8159 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8160 (match_operand:QI 1 "general_operand" "qmn,qn"))
8161 (const_int 0)))
8162 (set (strict_low_part (match_dup 0))
8163 (any_or:QI (match_dup 0) (match_dup 1)))]
8164 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8165 && ix86_match_ccmode (insn, CCNOmode)
8166 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8167 "<logic>{b}\t{%1, %0|%0, %1}"
8168 [(set_attr "type" "alu1")
8169 (set_attr "mode" "QI")])
8170
8171 (define_insn "*<code><mode>_3"
8172 [(set (reg FLAGS_REG)
8173 (compare (any_or:SWI
8174 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8175 (match_operand:SWI 2 "<general_operand>" "<g>"))
8176 (const_int 0)))
8177 (clobber (match_scratch:SWI 0 "=<r>"))]
8178 "ix86_match_ccmode (insn, CCNOmode)
8179 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8180 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8181 [(set_attr "type" "alu")
8182 (set_attr "mode" "<MODE>")])
8183
8184 (define_insn "*<code>qi_ext_0"
8185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8186 (const_int 8)
8187 (const_int 8))
8188 (any_or:SI
8189 (zero_extract:SI
8190 (match_operand 1 "ext_register_operand" "0")
8191 (const_int 8)
8192 (const_int 8))
8193 (match_operand 2 "const_int_operand" "n")))
8194 (clobber (reg:CC FLAGS_REG))]
8195 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8196 "<logic>{b}\t{%2, %h0|%h0, %2}"
8197 [(set_attr "type" "alu")
8198 (set_attr "length_immediate" "1")
8199 (set_attr "modrm" "1")
8200 (set_attr "mode" "QI")])
8201
8202 (define_insn "*<code>qi_ext_1_rex64"
8203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8204 (const_int 8)
8205 (const_int 8))
8206 (any_or:SI
8207 (zero_extract:SI
8208 (match_operand 1 "ext_register_operand" "0")
8209 (const_int 8)
8210 (const_int 8))
8211 (zero_extend:SI
8212 (match_operand 2 "ext_register_operand" "Q"))))
8213 (clobber (reg:CC FLAGS_REG))]
8214 "TARGET_64BIT
8215 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8216 "<logic>{b}\t{%2, %h0|%h0, %2}"
8217 [(set_attr "type" "alu")
8218 (set_attr "length_immediate" "0")
8219 (set_attr "mode" "QI")])
8220
8221 (define_insn "*<code>qi_ext_1"
8222 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8223 (const_int 8)
8224 (const_int 8))
8225 (any_or:SI
8226 (zero_extract:SI
8227 (match_operand 1 "ext_register_operand" "0")
8228 (const_int 8)
8229 (const_int 8))
8230 (zero_extend:SI
8231 (match_operand:QI 2 "general_operand" "Qm"))))
8232 (clobber (reg:CC FLAGS_REG))]
8233 "!TARGET_64BIT
8234 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8235 "<logic>{b}\t{%2, %h0|%h0, %2}"
8236 [(set_attr "type" "alu")
8237 (set_attr "length_immediate" "0")
8238 (set_attr "mode" "QI")])
8239
8240 (define_insn "*<code>qi_ext_2"
8241 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8242 (const_int 8)
8243 (const_int 8))
8244 (any_or:SI
8245 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8246 (const_int 8)
8247 (const_int 8))
8248 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8249 (const_int 8)
8250 (const_int 8))))
8251 (clobber (reg:CC FLAGS_REG))]
8252 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8253 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8254 [(set_attr "type" "alu")
8255 (set_attr "length_immediate" "0")
8256 (set_attr "mode" "QI")])
8257
8258 (define_split
8259 [(set (match_operand 0 "register_operand" "")
8260 (any_or (match_operand 1 "register_operand" "")
8261 (match_operand 2 "const_int_operand" "")))
8262 (clobber (reg:CC FLAGS_REG))]
8263 "reload_completed
8264 && QI_REG_P (operands[0])
8265 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8266 && !(INTVAL (operands[2]) & ~(255 << 8))
8267 && GET_MODE (operands[0]) != QImode"
8268 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8269 (any_or:SI (zero_extract:SI (match_dup 1)
8270 (const_int 8) (const_int 8))
8271 (match_dup 2)))
8272 (clobber (reg:CC FLAGS_REG))])]
8273 "operands[0] = gen_lowpart (SImode, operands[0]);
8274 operands[1] = gen_lowpart (SImode, operands[1]);
8275 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8276
8277 ;; Since OR can be encoded with sign extended immediate, this is only
8278 ;; profitable when 7th bit is set.
8279 (define_split
8280 [(set (match_operand 0 "register_operand" "")
8281 (any_or (match_operand 1 "general_operand" "")
8282 (match_operand 2 "const_int_operand" "")))
8283 (clobber (reg:CC FLAGS_REG))]
8284 "reload_completed
8285 && ANY_QI_REG_P (operands[0])
8286 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8287 && !(INTVAL (operands[2]) & ~255)
8288 && (INTVAL (operands[2]) & 128)
8289 && GET_MODE (operands[0]) != QImode"
8290 [(parallel [(set (strict_low_part (match_dup 0))
8291 (any_or:QI (match_dup 1)
8292 (match_dup 2)))
8293 (clobber (reg:CC FLAGS_REG))])]
8294 "operands[0] = gen_lowpart (QImode, operands[0]);
8295 operands[1] = gen_lowpart (QImode, operands[1]);
8296 operands[2] = gen_lowpart (QImode, operands[2]);")
8297
8298 (define_expand "xorqi_cc_ext_1"
8299 [(parallel [
8300 (set (reg:CCNO FLAGS_REG)
8301 (compare:CCNO
8302 (xor:SI
8303 (zero_extract:SI
8304 (match_operand 1 "ext_register_operand" "")
8305 (const_int 8)
8306 (const_int 8))
8307 (match_operand:QI 2 "general_operand" ""))
8308 (const_int 0)))
8309 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8310 (const_int 8)
8311 (const_int 8))
8312 (xor:SI
8313 (zero_extract:SI
8314 (match_dup 1)
8315 (const_int 8)
8316 (const_int 8))
8317 (match_dup 2)))])])
8318
8319 (define_insn "*xorqi_cc_ext_1_rex64"
8320 [(set (reg FLAGS_REG)
8321 (compare
8322 (xor:SI
8323 (zero_extract:SI
8324 (match_operand 1 "ext_register_operand" "0")
8325 (const_int 8)
8326 (const_int 8))
8327 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8328 (const_int 0)))
8329 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8330 (const_int 8)
8331 (const_int 8))
8332 (xor:SI
8333 (zero_extract:SI
8334 (match_dup 1)
8335 (const_int 8)
8336 (const_int 8))
8337 (match_dup 2)))]
8338 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8339 "xor{b}\t{%2, %h0|%h0, %2}"
8340 [(set_attr "type" "alu")
8341 (set_attr "modrm" "1")
8342 (set_attr "mode" "QI")])
8343
8344 (define_insn "*xorqi_cc_ext_1"
8345 [(set (reg FLAGS_REG)
8346 (compare
8347 (xor:SI
8348 (zero_extract:SI
8349 (match_operand 1 "ext_register_operand" "0")
8350 (const_int 8)
8351 (const_int 8))
8352 (match_operand:QI 2 "general_operand" "qmn"))
8353 (const_int 0)))
8354 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8355 (const_int 8)
8356 (const_int 8))
8357 (xor:SI
8358 (zero_extract:SI
8359 (match_dup 1)
8360 (const_int 8)
8361 (const_int 8))
8362 (match_dup 2)))]
8363 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8364 "xor{b}\t{%2, %h0|%h0, %2}"
8365 [(set_attr "type" "alu")
8366 (set_attr "modrm" "1")
8367 (set_attr "mode" "QI")])
8368 \f
8369 ;; Negation instructions
8370
8371 (define_expand "neg<mode>2"
8372 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8373 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8374 ""
8375 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8376
8377 (define_insn_and_split "*neg<dwi>2_doubleword"
8378 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8379 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8380 (clobber (reg:CC FLAGS_REG))]
8381 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8382 "#"
8383 "reload_completed"
8384 [(parallel
8385 [(set (reg:CCZ FLAGS_REG)
8386 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8387 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8388 (parallel
8389 [(set (match_dup 2)
8390 (plus:DWIH (match_dup 3)
8391 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8392 (const_int 0))))
8393 (clobber (reg:CC FLAGS_REG))])
8394 (parallel
8395 [(set (match_dup 2)
8396 (neg:DWIH (match_dup 2)))
8397 (clobber (reg:CC FLAGS_REG))])]
8398 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8399
8400 (define_insn "*neg<mode>2_1"
8401 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8402 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8403 (clobber (reg:CC FLAGS_REG))]
8404 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8405 "neg{<imodesuffix>}\t%0"
8406 [(set_attr "type" "negnot")
8407 (set_attr "mode" "<MODE>")])
8408
8409 ;; Combine is quite creative about this pattern.
8410 (define_insn "*negsi2_1_zext"
8411 [(set (match_operand:DI 0 "register_operand" "=r")
8412 (lshiftrt:DI
8413 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8414 (const_int 32)))
8415 (const_int 32)))
8416 (clobber (reg:CC FLAGS_REG))]
8417 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8418 "neg{l}\t%k0"
8419 [(set_attr "type" "negnot")
8420 (set_attr "mode" "SI")])
8421
8422 ;; The problem with neg is that it does not perform (compare x 0),
8423 ;; it really performs (compare 0 x), which leaves us with the zero
8424 ;; flag being the only useful item.
8425
8426 (define_insn "*neg<mode>2_cmpz"
8427 [(set (reg:CCZ FLAGS_REG)
8428 (compare:CCZ
8429 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8430 (const_int 0)))
8431 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8432 (neg:SWI (match_dup 1)))]
8433 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8434 "neg{<imodesuffix>}\t%0"
8435 [(set_attr "type" "negnot")
8436 (set_attr "mode" "<MODE>")])
8437
8438 (define_insn "*negsi2_cmpz_zext"
8439 [(set (reg:CCZ FLAGS_REG)
8440 (compare:CCZ
8441 (lshiftrt:DI
8442 (neg:DI (ashift:DI
8443 (match_operand:DI 1 "register_operand" "0")
8444 (const_int 32)))
8445 (const_int 32))
8446 (const_int 0)))
8447 (set (match_operand:DI 0 "register_operand" "=r")
8448 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8449 (const_int 32)))
8450 (const_int 32)))]
8451 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8452 "neg{l}\t%k0"
8453 [(set_attr "type" "negnot")
8454 (set_attr "mode" "SI")])
8455
8456 ;; Changing of sign for FP values is doable using integer unit too.
8457
8458 (define_expand "<code><mode>2"
8459 [(set (match_operand:X87MODEF 0 "register_operand" "")
8460 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8461 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8462 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8463
8464 (define_insn "*absneg<mode>2_mixed"
8465 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8466 (match_operator:MODEF 3 "absneg_operator"
8467 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8468 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8469 (clobber (reg:CC FLAGS_REG))]
8470 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8471 "#")
8472
8473 (define_insn "*absneg<mode>2_sse"
8474 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8475 (match_operator:MODEF 3 "absneg_operator"
8476 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8477 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8478 (clobber (reg:CC FLAGS_REG))]
8479 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8480 "#")
8481
8482 (define_insn "*absneg<mode>2_i387"
8483 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8484 (match_operator:X87MODEF 3 "absneg_operator"
8485 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8486 (use (match_operand 2 "" ""))
8487 (clobber (reg:CC FLAGS_REG))]
8488 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8489 "#")
8490
8491 (define_expand "<code>tf2"
8492 [(set (match_operand:TF 0 "register_operand" "")
8493 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8494 "TARGET_SSE2"
8495 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8496
8497 (define_insn "*absnegtf2_sse"
8498 [(set (match_operand:TF 0 "register_operand" "=x,x")
8499 (match_operator:TF 3 "absneg_operator"
8500 [(match_operand:TF 1 "register_operand" "0,x")]))
8501 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8502 (clobber (reg:CC FLAGS_REG))]
8503 "TARGET_SSE2"
8504 "#")
8505
8506 ;; Splitters for fp abs and neg.
8507
8508 (define_split
8509 [(set (match_operand 0 "fp_register_operand" "")
8510 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8511 (use (match_operand 2 "" ""))
8512 (clobber (reg:CC FLAGS_REG))]
8513 "reload_completed"
8514 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8515
8516 (define_split
8517 [(set (match_operand 0 "register_operand" "")
8518 (match_operator 3 "absneg_operator"
8519 [(match_operand 1 "register_operand" "")]))
8520 (use (match_operand 2 "nonimmediate_operand" ""))
8521 (clobber (reg:CC FLAGS_REG))]
8522 "reload_completed && SSE_REG_P (operands[0])"
8523 [(set (match_dup 0) (match_dup 3))]
8524 {
8525 enum machine_mode mode = GET_MODE (operands[0]);
8526 enum machine_mode vmode = GET_MODE (operands[2]);
8527 rtx tmp;
8528
8529 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8530 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8531 if (operands_match_p (operands[0], operands[2]))
8532 {
8533 tmp = operands[1];
8534 operands[1] = operands[2];
8535 operands[2] = tmp;
8536 }
8537 if (GET_CODE (operands[3]) == ABS)
8538 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8539 else
8540 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8541 operands[3] = tmp;
8542 })
8543
8544 (define_split
8545 [(set (match_operand:SF 0 "register_operand" "")
8546 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8547 (use (match_operand:V4SF 2 "" ""))
8548 (clobber (reg:CC FLAGS_REG))]
8549 "reload_completed"
8550 [(parallel [(set (match_dup 0) (match_dup 1))
8551 (clobber (reg:CC FLAGS_REG))])]
8552 {
8553 rtx tmp;
8554 operands[0] = gen_lowpart (SImode, operands[0]);
8555 if (GET_CODE (operands[1]) == ABS)
8556 {
8557 tmp = gen_int_mode (0x7fffffff, SImode);
8558 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8559 }
8560 else
8561 {
8562 tmp = gen_int_mode (0x80000000, SImode);
8563 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8564 }
8565 operands[1] = tmp;
8566 })
8567
8568 (define_split
8569 [(set (match_operand:DF 0 "register_operand" "")
8570 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8571 (use (match_operand 2 "" ""))
8572 (clobber (reg:CC FLAGS_REG))]
8573 "reload_completed"
8574 [(parallel [(set (match_dup 0) (match_dup 1))
8575 (clobber (reg:CC FLAGS_REG))])]
8576 {
8577 rtx tmp;
8578 if (TARGET_64BIT)
8579 {
8580 tmp = gen_lowpart (DImode, operands[0]);
8581 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8582 operands[0] = tmp;
8583
8584 if (GET_CODE (operands[1]) == ABS)
8585 tmp = const0_rtx;
8586 else
8587 tmp = gen_rtx_NOT (DImode, tmp);
8588 }
8589 else
8590 {
8591 operands[0] = gen_highpart (SImode, operands[0]);
8592 if (GET_CODE (operands[1]) == ABS)
8593 {
8594 tmp = gen_int_mode (0x7fffffff, SImode);
8595 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8596 }
8597 else
8598 {
8599 tmp = gen_int_mode (0x80000000, SImode);
8600 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8601 }
8602 }
8603 operands[1] = tmp;
8604 })
8605
8606 (define_split
8607 [(set (match_operand:XF 0 "register_operand" "")
8608 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8609 (use (match_operand 2 "" ""))
8610 (clobber (reg:CC FLAGS_REG))]
8611 "reload_completed"
8612 [(parallel [(set (match_dup 0) (match_dup 1))
8613 (clobber (reg:CC FLAGS_REG))])]
8614 {
8615 rtx tmp;
8616 operands[0] = gen_rtx_REG (SImode,
8617 true_regnum (operands[0])
8618 + (TARGET_64BIT ? 1 : 2));
8619 if (GET_CODE (operands[1]) == ABS)
8620 {
8621 tmp = GEN_INT (0x7fff);
8622 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8623 }
8624 else
8625 {
8626 tmp = GEN_INT (0x8000);
8627 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8628 }
8629 operands[1] = tmp;
8630 })
8631
8632 ;; Conditionalize these after reload. If they match before reload, we
8633 ;; lose the clobber and ability to use integer instructions.
8634
8635 (define_insn "*<code><mode>2_1"
8636 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8637 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8638 "TARGET_80387
8639 && (reload_completed
8640 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8641 "f<absneg_mnemonic>"
8642 [(set_attr "type" "fsgn")
8643 (set_attr "mode" "<MODE>")])
8644
8645 (define_insn "*<code>extendsfdf2"
8646 [(set (match_operand:DF 0 "register_operand" "=f")
8647 (absneg:DF (float_extend:DF
8648 (match_operand:SF 1 "register_operand" "0"))))]
8649 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8650 "f<absneg_mnemonic>"
8651 [(set_attr "type" "fsgn")
8652 (set_attr "mode" "DF")])
8653
8654 (define_insn "*<code>extendsfxf2"
8655 [(set (match_operand:XF 0 "register_operand" "=f")
8656 (absneg:XF (float_extend:XF
8657 (match_operand:SF 1 "register_operand" "0"))))]
8658 "TARGET_80387"
8659 "f<absneg_mnemonic>"
8660 [(set_attr "type" "fsgn")
8661 (set_attr "mode" "XF")])
8662
8663 (define_insn "*<code>extenddfxf2"
8664 [(set (match_operand:XF 0 "register_operand" "=f")
8665 (absneg:XF (float_extend:XF
8666 (match_operand:DF 1 "register_operand" "0"))))]
8667 "TARGET_80387"
8668 "f<absneg_mnemonic>"
8669 [(set_attr "type" "fsgn")
8670 (set_attr "mode" "XF")])
8671
8672 ;; Copysign instructions
8673
8674 (define_mode_iterator CSGNMODE [SF DF TF])
8675 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8676
8677 (define_expand "copysign<mode>3"
8678 [(match_operand:CSGNMODE 0 "register_operand" "")
8679 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8680 (match_operand:CSGNMODE 2 "register_operand" "")]
8681 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8682 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8683 "ix86_expand_copysign (operands); DONE;")
8684
8685 (define_insn_and_split "copysign<mode>3_const"
8686 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8687 (unspec:CSGNMODE
8688 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8689 (match_operand:CSGNMODE 2 "register_operand" "0")
8690 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8691 UNSPEC_COPYSIGN))]
8692 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8693 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8694 "#"
8695 "&& reload_completed"
8696 [(const_int 0)]
8697 "ix86_split_copysign_const (operands); DONE;")
8698
8699 (define_insn "copysign<mode>3_var"
8700 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8701 (unspec:CSGNMODE
8702 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8703 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8704 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8705 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8706 UNSPEC_COPYSIGN))
8707 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8708 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8709 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8710 "#")
8711
8712 (define_split
8713 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8714 (unspec:CSGNMODE
8715 [(match_operand:CSGNMODE 2 "register_operand" "")
8716 (match_operand:CSGNMODE 3 "register_operand" "")
8717 (match_operand:<CSGNVMODE> 4 "" "")
8718 (match_operand:<CSGNVMODE> 5 "" "")]
8719 UNSPEC_COPYSIGN))
8720 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8721 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8722 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8723 && reload_completed"
8724 [(const_int 0)]
8725 "ix86_split_copysign_var (operands); DONE;")
8726 \f
8727 ;; One complement instructions
8728
8729 (define_expand "one_cmpl<mode>2"
8730 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8731 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8732 ""
8733 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8734
8735 (define_insn "*one_cmpl<mode>2_1"
8736 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8737 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8738 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8739 "not{<imodesuffix>}\t%0"
8740 [(set_attr "type" "negnot")
8741 (set_attr "mode" "<MODE>")])
8742
8743 ;; %%% Potential partial reg stall on alternative 1. What to do?
8744 (define_insn "*one_cmplqi2_1"
8745 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8746 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8747 "ix86_unary_operator_ok (NOT, QImode, operands)"
8748 "@
8749 not{b}\t%0
8750 not{l}\t%k0"
8751 [(set_attr "type" "negnot")
8752 (set_attr "mode" "QI,SI")])
8753
8754 ;; ??? Currently never generated - xor is used instead.
8755 (define_insn "*one_cmplsi2_1_zext"
8756 [(set (match_operand:DI 0 "register_operand" "=r")
8757 (zero_extend:DI
8758 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8759 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8760 "not{l}\t%k0"
8761 [(set_attr "type" "negnot")
8762 (set_attr "mode" "SI")])
8763
8764 (define_insn "*one_cmpl<mode>2_2"
8765 [(set (reg FLAGS_REG)
8766 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8767 (const_int 0)))
8768 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8769 (not:SWI (match_dup 1)))]
8770 "ix86_match_ccmode (insn, CCNOmode)
8771 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8772 "#"
8773 [(set_attr "type" "alu1")
8774 (set_attr "mode" "<MODE>")])
8775
8776 (define_split
8777 [(set (match_operand 0 "flags_reg_operand" "")
8778 (match_operator 2 "compare_operator"
8779 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8780 (const_int 0)]))
8781 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8782 (not:SWI (match_dup 3)))]
8783 "ix86_match_ccmode (insn, CCNOmode)"
8784 [(parallel [(set (match_dup 0)
8785 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8786 (const_int 0)]))
8787 (set (match_dup 1)
8788 (xor:SWI (match_dup 3) (const_int -1)))])])
8789
8790 ;; ??? Currently never generated - xor is used instead.
8791 (define_insn "*one_cmplsi2_2_zext"
8792 [(set (reg FLAGS_REG)
8793 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8794 (const_int 0)))
8795 (set (match_operand:DI 0 "register_operand" "=r")
8796 (zero_extend:DI (not:SI (match_dup 1))))]
8797 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8798 && ix86_unary_operator_ok (NOT, SImode, operands)"
8799 "#"
8800 [(set_attr "type" "alu1")
8801 (set_attr "mode" "SI")])
8802
8803 (define_split
8804 [(set (match_operand 0 "flags_reg_operand" "")
8805 (match_operator 2 "compare_operator"
8806 [(not:SI (match_operand:SI 3 "register_operand" ""))
8807 (const_int 0)]))
8808 (set (match_operand:DI 1 "register_operand" "")
8809 (zero_extend:DI (not:SI (match_dup 3))))]
8810 "ix86_match_ccmode (insn, CCNOmode)"
8811 [(parallel [(set (match_dup 0)
8812 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8813 (const_int 0)]))
8814 (set (match_dup 1)
8815 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8816 \f
8817 ;; Shift instructions
8818
8819 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8820 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8821 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8822 ;; from the assembler input.
8823 ;;
8824 ;; This instruction shifts the target reg/mem as usual, but instead of
8825 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8826 ;; is a left shift double, bits are taken from the high order bits of
8827 ;; reg, else if the insn is a shift right double, bits are taken from the
8828 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8829 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8830 ;;
8831 ;; Since sh[lr]d does not change the `reg' operand, that is done
8832 ;; separately, making all shifts emit pairs of shift double and normal
8833 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8834 ;; support a 63 bit shift, each shift where the count is in a reg expands
8835 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8836 ;;
8837 ;; If the shift count is a constant, we need never emit more than one
8838 ;; shift pair, instead using moves and sign extension for counts greater
8839 ;; than 31.
8840
8841 (define_expand "ashl<mode>3"
8842 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8843 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8844 (match_operand:QI 2 "nonmemory_operand" "")))]
8845 ""
8846 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8847
8848 (define_insn "*ashl<mode>3_doubleword"
8849 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8850 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8851 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8852 (clobber (reg:CC FLAGS_REG))]
8853 ""
8854 "#"
8855 [(set_attr "type" "multi")])
8856
8857 (define_split
8858 [(set (match_operand:DWI 0 "register_operand" "")
8859 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8860 (match_operand:QI 2 "nonmemory_operand" "")))
8861 (clobber (reg:CC FLAGS_REG))]
8862 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8863 [(const_int 0)]
8864 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8865
8866 ;; By default we don't ask for a scratch register, because when DWImode
8867 ;; values are manipulated, registers are already at a premium. But if
8868 ;; we have one handy, we won't turn it away.
8869
8870 (define_peephole2
8871 [(match_scratch:DWIH 3 "r")
8872 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8873 (ashift:<DWI>
8874 (match_operand:<DWI> 1 "nonmemory_operand" "")
8875 (match_operand:QI 2 "nonmemory_operand" "")))
8876 (clobber (reg:CC FLAGS_REG))])
8877 (match_dup 3)]
8878 "TARGET_CMOVE"
8879 [(const_int 0)]
8880 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8881
8882 (define_insn "x86_64_shld"
8883 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8884 (ior:DI (ashift:DI (match_dup 0)
8885 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8886 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8887 (minus:QI (const_int 64) (match_dup 2)))))
8888 (clobber (reg:CC FLAGS_REG))]
8889 "TARGET_64BIT"
8890 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8891 [(set_attr "type" "ishift")
8892 (set_attr "prefix_0f" "1")
8893 (set_attr "mode" "DI")
8894 (set_attr "athlon_decode" "vector")
8895 (set_attr "amdfam10_decode" "vector")
8896 (set_attr "bdver1_decode" "vector")])
8897
8898 (define_insn "x86_shld"
8899 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8900 (ior:SI (ashift:SI (match_dup 0)
8901 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8902 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8903 (minus:QI (const_int 32) (match_dup 2)))))
8904 (clobber (reg:CC FLAGS_REG))]
8905 ""
8906 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8907 [(set_attr "type" "ishift")
8908 (set_attr "prefix_0f" "1")
8909 (set_attr "mode" "SI")
8910 (set_attr "pent_pair" "np")
8911 (set_attr "athlon_decode" "vector")
8912 (set_attr "amdfam10_decode" "vector")
8913 (set_attr "bdver1_decode" "vector")])
8914
8915 (define_expand "x86_shift<mode>_adj_1"
8916 [(set (reg:CCZ FLAGS_REG)
8917 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8918 (match_dup 4))
8919 (const_int 0)))
8920 (set (match_operand:SWI48 0 "register_operand" "")
8921 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8922 (match_operand:SWI48 1 "register_operand" "")
8923 (match_dup 0)))
8924 (set (match_dup 1)
8925 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8926 (match_operand:SWI48 3 "register_operand" "r")
8927 (match_dup 1)))]
8928 "TARGET_CMOVE"
8929 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8930
8931 (define_expand "x86_shift<mode>_adj_2"
8932 [(use (match_operand:SWI48 0 "register_operand" ""))
8933 (use (match_operand:SWI48 1 "register_operand" ""))
8934 (use (match_operand:QI 2 "register_operand" ""))]
8935 ""
8936 {
8937 rtx label = gen_label_rtx ();
8938 rtx tmp;
8939
8940 emit_insn (gen_testqi_ccz_1 (operands[2],
8941 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8942
8943 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8944 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8945 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8946 gen_rtx_LABEL_REF (VOIDmode, label),
8947 pc_rtx);
8948 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8949 JUMP_LABEL (tmp) = label;
8950
8951 emit_move_insn (operands[0], operands[1]);
8952 ix86_expand_clear (operands[1]);
8953
8954 emit_label (label);
8955 LABEL_NUSES (label) = 1;
8956
8957 DONE;
8958 })
8959
8960 ;; Avoid useless masking of count operand.
8961 (define_insn_and_split "*ashl<mode>3_mask"
8962 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8963 (ashift:SWI48
8964 (match_operand:SWI48 1 "nonimmediate_operand" "0")
8965 (subreg:QI
8966 (and:SI
8967 (match_operand:SI 2 "nonimmediate_operand" "c")
8968 (match_operand:SI 3 "const_int_operand" "n")) 0)))
8969 (clobber (reg:CC FLAGS_REG))]
8970 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
8971 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
8972 == GET_MODE_BITSIZE (<MODE>mode)-1"
8973 "#"
8974 "&& 1"
8975 [(parallel [(set (match_dup 0)
8976 (ashift:SWI48 (match_dup 1) (match_dup 2)))
8977 (clobber (reg:CC FLAGS_REG))])]
8978 {
8979 if (can_create_pseudo_p ())
8980 operands [2] = force_reg (SImode, operands[2]);
8981
8982 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
8983 }
8984 [(set_attr "type" "ishift")
8985 (set_attr "mode" "<MODE>")])
8986
8987 (define_insn "*ashl<mode>3_1"
8988 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8989 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
8990 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
8991 (clobber (reg:CC FLAGS_REG))]
8992 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
8993 {
8994 switch (get_attr_type (insn))
8995 {
8996 case TYPE_LEA:
8997 return "#";
8998
8999 case TYPE_ALU:
9000 gcc_assert (operands[2] == const1_rtx);
9001 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9002 return "add{<imodesuffix>}\t%0, %0";
9003
9004 default:
9005 if (operands[2] == const1_rtx
9006 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9007 return "sal{<imodesuffix>}\t%0";
9008 else
9009 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9010 }
9011 }
9012 [(set (attr "type")
9013 (cond [(eq_attr "alternative" "1")
9014 (const_string "lea")
9015 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9016 (const_int 0))
9017 (match_operand 0 "register_operand" ""))
9018 (match_operand 2 "const1_operand" ""))
9019 (const_string "alu")
9020 ]
9021 (const_string "ishift")))
9022 (set (attr "length_immediate")
9023 (if_then_else
9024 (ior (eq_attr "type" "alu")
9025 (and (eq_attr "type" "ishift")
9026 (and (match_operand 2 "const1_operand" "")
9027 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9028 (const_int 0)))))
9029 (const_string "0")
9030 (const_string "*")))
9031 (set_attr "mode" "<MODE>")])
9032
9033 (define_insn "*ashlsi3_1_zext"
9034 [(set (match_operand:DI 0 "register_operand" "=r,r")
9035 (zero_extend:DI
9036 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9037 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9038 (clobber (reg:CC FLAGS_REG))]
9039 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9040 {
9041 switch (get_attr_type (insn))
9042 {
9043 case TYPE_LEA:
9044 return "#";
9045
9046 case TYPE_ALU:
9047 gcc_assert (operands[2] == const1_rtx);
9048 return "add{l}\t%k0, %k0";
9049
9050 default:
9051 if (operands[2] == const1_rtx
9052 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9053 return "sal{l}\t%k0";
9054 else
9055 return "sal{l}\t{%2, %k0|%k0, %2}";
9056 }
9057 }
9058 [(set (attr "type")
9059 (cond [(eq_attr "alternative" "1")
9060 (const_string "lea")
9061 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9062 (const_int 0))
9063 (match_operand 2 "const1_operand" ""))
9064 (const_string "alu")
9065 ]
9066 (const_string "ishift")))
9067 (set (attr "length_immediate")
9068 (if_then_else
9069 (ior (eq_attr "type" "alu")
9070 (and (eq_attr "type" "ishift")
9071 (and (match_operand 2 "const1_operand" "")
9072 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9073 (const_int 0)))))
9074 (const_string "0")
9075 (const_string "*")))
9076 (set_attr "mode" "SI")])
9077
9078 (define_insn "*ashlhi3_1"
9079 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9080 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9081 (match_operand:QI 2 "nonmemory_operand" "cI")))
9082 (clobber (reg:CC FLAGS_REG))]
9083 "TARGET_PARTIAL_REG_STALL
9084 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9085 {
9086 switch (get_attr_type (insn))
9087 {
9088 case TYPE_ALU:
9089 gcc_assert (operands[2] == const1_rtx);
9090 return "add{w}\t%0, %0";
9091
9092 default:
9093 if (operands[2] == const1_rtx
9094 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9095 return "sal{w}\t%0";
9096 else
9097 return "sal{w}\t{%2, %0|%0, %2}";
9098 }
9099 }
9100 [(set (attr "type")
9101 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9102 (const_int 0))
9103 (match_operand 0 "register_operand" ""))
9104 (match_operand 2 "const1_operand" ""))
9105 (const_string "alu")
9106 ]
9107 (const_string "ishift")))
9108 (set (attr "length_immediate")
9109 (if_then_else
9110 (ior (eq_attr "type" "alu")
9111 (and (eq_attr "type" "ishift")
9112 (and (match_operand 2 "const1_operand" "")
9113 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9114 (const_int 0)))))
9115 (const_string "0")
9116 (const_string "*")))
9117 (set_attr "mode" "HI")])
9118
9119 (define_insn "*ashlhi3_1_lea"
9120 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9121 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9122 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9123 (clobber (reg:CC FLAGS_REG))]
9124 "!TARGET_PARTIAL_REG_STALL
9125 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9126 {
9127 switch (get_attr_type (insn))
9128 {
9129 case TYPE_LEA:
9130 return "#";
9131
9132 case TYPE_ALU:
9133 gcc_assert (operands[2] == const1_rtx);
9134 return "add{w}\t%0, %0";
9135
9136 default:
9137 if (operands[2] == const1_rtx
9138 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9139 return "sal{w}\t%0";
9140 else
9141 return "sal{w}\t{%2, %0|%0, %2}";
9142 }
9143 }
9144 [(set (attr "type")
9145 (cond [(eq_attr "alternative" "1")
9146 (const_string "lea")
9147 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9148 (const_int 0))
9149 (match_operand 0 "register_operand" ""))
9150 (match_operand 2 "const1_operand" ""))
9151 (const_string "alu")
9152 ]
9153 (const_string "ishift")))
9154 (set (attr "length_immediate")
9155 (if_then_else
9156 (ior (eq_attr "type" "alu")
9157 (and (eq_attr "type" "ishift")
9158 (and (match_operand 2 "const1_operand" "")
9159 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9160 (const_int 0)))))
9161 (const_string "0")
9162 (const_string "*")))
9163 (set_attr "mode" "HI,SI")])
9164
9165 (define_insn "*ashlqi3_1"
9166 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9167 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9168 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9169 (clobber (reg:CC FLAGS_REG))]
9170 "TARGET_PARTIAL_REG_STALL
9171 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9172 {
9173 switch (get_attr_type (insn))
9174 {
9175 case TYPE_ALU:
9176 gcc_assert (operands[2] == const1_rtx);
9177 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9178 return "add{l}\t%k0, %k0";
9179 else
9180 return "add{b}\t%0, %0";
9181
9182 default:
9183 if (operands[2] == const1_rtx
9184 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9185 {
9186 if (get_attr_mode (insn) == MODE_SI)
9187 return "sal{l}\t%k0";
9188 else
9189 return "sal{b}\t%0";
9190 }
9191 else
9192 {
9193 if (get_attr_mode (insn) == MODE_SI)
9194 return "sal{l}\t{%2, %k0|%k0, %2}";
9195 else
9196 return "sal{b}\t{%2, %0|%0, %2}";
9197 }
9198 }
9199 }
9200 [(set (attr "type")
9201 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9202 (const_int 0))
9203 (match_operand 0 "register_operand" ""))
9204 (match_operand 2 "const1_operand" ""))
9205 (const_string "alu")
9206 ]
9207 (const_string "ishift")))
9208 (set (attr "length_immediate")
9209 (if_then_else
9210 (ior (eq_attr "type" "alu")
9211 (and (eq_attr "type" "ishift")
9212 (and (match_operand 2 "const1_operand" "")
9213 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9214 (const_int 0)))))
9215 (const_string "0")
9216 (const_string "*")))
9217 (set_attr "mode" "QI,SI")])
9218
9219 ;; %%% Potential partial reg stall on alternative 2. What to do?
9220 (define_insn "*ashlqi3_1_lea"
9221 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9222 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9223 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9224 (clobber (reg:CC FLAGS_REG))]
9225 "!TARGET_PARTIAL_REG_STALL
9226 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9227 {
9228 switch (get_attr_type (insn))
9229 {
9230 case TYPE_LEA:
9231 return "#";
9232
9233 case TYPE_ALU:
9234 gcc_assert (operands[2] == const1_rtx);
9235 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9236 return "add{l}\t%k0, %k0";
9237 else
9238 return "add{b}\t%0, %0";
9239
9240 default:
9241 if (operands[2] == const1_rtx
9242 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9243 {
9244 if (get_attr_mode (insn) == MODE_SI)
9245 return "sal{l}\t%k0";
9246 else
9247 return "sal{b}\t%0";
9248 }
9249 else
9250 {
9251 if (get_attr_mode (insn) == MODE_SI)
9252 return "sal{l}\t{%2, %k0|%k0, %2}";
9253 else
9254 return "sal{b}\t{%2, %0|%0, %2}";
9255 }
9256 }
9257 }
9258 [(set (attr "type")
9259 (cond [(eq_attr "alternative" "2")
9260 (const_string "lea")
9261 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9262 (const_int 0))
9263 (match_operand 0 "register_operand" ""))
9264 (match_operand 2 "const1_operand" ""))
9265 (const_string "alu")
9266 ]
9267 (const_string "ishift")))
9268 (set (attr "length_immediate")
9269 (if_then_else
9270 (ior (eq_attr "type" "alu")
9271 (and (eq_attr "type" "ishift")
9272 (and (match_operand 2 "const1_operand" "")
9273 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9274 (const_int 0)))))
9275 (const_string "0")
9276 (const_string "*")))
9277 (set_attr "mode" "QI,SI,SI")])
9278
9279 (define_insn "*ashlqi3_1_slp"
9280 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9281 (ashift:QI (match_dup 0)
9282 (match_operand:QI 1 "nonmemory_operand" "cI")))
9283 (clobber (reg:CC FLAGS_REG))]
9284 "(optimize_function_for_size_p (cfun)
9285 || !TARGET_PARTIAL_FLAG_REG_STALL
9286 || (operands[1] == const1_rtx
9287 && (TARGET_SHIFT1
9288 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9289 {
9290 switch (get_attr_type (insn))
9291 {
9292 case TYPE_ALU:
9293 gcc_assert (operands[1] == const1_rtx);
9294 return "add{b}\t%0, %0";
9295
9296 default:
9297 if (operands[1] == const1_rtx
9298 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9299 return "sal{b}\t%0";
9300 else
9301 return "sal{b}\t{%1, %0|%0, %1}";
9302 }
9303 }
9304 [(set (attr "type")
9305 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9306 (const_int 0))
9307 (match_operand 0 "register_operand" ""))
9308 (match_operand 1 "const1_operand" ""))
9309 (const_string "alu")
9310 ]
9311 (const_string "ishift1")))
9312 (set (attr "length_immediate")
9313 (if_then_else
9314 (ior (eq_attr "type" "alu")
9315 (and (eq_attr "type" "ishift1")
9316 (and (match_operand 1 "const1_operand" "")
9317 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9318 (const_int 0)))))
9319 (const_string "0")
9320 (const_string "*")))
9321 (set_attr "mode" "QI")])
9322
9323 ;; Convert ashift to the lea pattern to avoid flags dependency.
9324 (define_split
9325 [(set (match_operand 0 "register_operand" "")
9326 (ashift (match_operand 1 "index_register_operand" "")
9327 (match_operand:QI 2 "const_int_operand" "")))
9328 (clobber (reg:CC FLAGS_REG))]
9329 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9330 && reload_completed
9331 && true_regnum (operands[0]) != true_regnum (operands[1])"
9332 [(const_int 0)]
9333 {
9334 enum machine_mode mode = GET_MODE (operands[0]);
9335 rtx pat;
9336
9337 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9338 {
9339 mode = SImode;
9340 operands[0] = gen_lowpart (mode, operands[0]);
9341 operands[1] = gen_lowpart (mode, operands[1]);
9342 }
9343
9344 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9345
9346 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9347
9348 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9349 DONE;
9350 })
9351
9352 ;; Convert ashift to the lea pattern to avoid flags dependency.
9353 (define_split
9354 [(set (match_operand:DI 0 "register_operand" "")
9355 (zero_extend:DI
9356 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9357 (match_operand:QI 2 "const_int_operand" ""))))
9358 (clobber (reg:CC FLAGS_REG))]
9359 "TARGET_64BIT && reload_completed
9360 && true_regnum (operands[0]) != true_regnum (operands[1])"
9361 [(set (match_dup 0)
9362 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9363 {
9364 operands[1] = gen_lowpart (DImode, operands[1]);
9365 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9366 })
9367
9368 ;; This pattern can't accept a variable shift count, since shifts by
9369 ;; zero don't affect the flags. We assume that shifts by constant
9370 ;; zero are optimized away.
9371 (define_insn "*ashl<mode>3_cmp"
9372 [(set (reg FLAGS_REG)
9373 (compare
9374 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9375 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9376 (const_int 0)))
9377 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9378 (ashift:SWI (match_dup 1) (match_dup 2)))]
9379 "(optimize_function_for_size_p (cfun)
9380 || !TARGET_PARTIAL_FLAG_REG_STALL
9381 || (operands[2] == const1_rtx
9382 && (TARGET_SHIFT1
9383 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9384 && ix86_match_ccmode (insn, CCGOCmode)
9385 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9386 {
9387 switch (get_attr_type (insn))
9388 {
9389 case TYPE_ALU:
9390 gcc_assert (operands[2] == const1_rtx);
9391 return "add{<imodesuffix>}\t%0, %0";
9392
9393 default:
9394 if (operands[2] == const1_rtx
9395 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9396 return "sal{<imodesuffix>}\t%0";
9397 else
9398 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9399 }
9400 }
9401 [(set (attr "type")
9402 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9403 (const_int 0))
9404 (match_operand 0 "register_operand" ""))
9405 (match_operand 2 "const1_operand" ""))
9406 (const_string "alu")
9407 ]
9408 (const_string "ishift")))
9409 (set (attr "length_immediate")
9410 (if_then_else
9411 (ior (eq_attr "type" "alu")
9412 (and (eq_attr "type" "ishift")
9413 (and (match_operand 2 "const1_operand" "")
9414 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9415 (const_int 0)))))
9416 (const_string "0")
9417 (const_string "*")))
9418 (set_attr "mode" "<MODE>")])
9419
9420 (define_insn "*ashlsi3_cmp_zext"
9421 [(set (reg FLAGS_REG)
9422 (compare
9423 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9424 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9425 (const_int 0)))
9426 (set (match_operand:DI 0 "register_operand" "=r")
9427 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9428 "TARGET_64BIT
9429 && (optimize_function_for_size_p (cfun)
9430 || !TARGET_PARTIAL_FLAG_REG_STALL
9431 || (operands[2] == const1_rtx
9432 && (TARGET_SHIFT1
9433 || TARGET_DOUBLE_WITH_ADD)))
9434 && ix86_match_ccmode (insn, CCGOCmode)
9435 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9436 {
9437 switch (get_attr_type (insn))
9438 {
9439 case TYPE_ALU:
9440 gcc_assert (operands[2] == const1_rtx);
9441 return "add{l}\t%k0, %k0";
9442
9443 default:
9444 if (operands[2] == const1_rtx
9445 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9446 return "sal{l}\t%k0";
9447 else
9448 return "sal{l}\t{%2, %k0|%k0, %2}";
9449 }
9450 }
9451 [(set (attr "type")
9452 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9453 (const_int 0))
9454 (match_operand 2 "const1_operand" ""))
9455 (const_string "alu")
9456 ]
9457 (const_string "ishift")))
9458 (set (attr "length_immediate")
9459 (if_then_else
9460 (ior (eq_attr "type" "alu")
9461 (and (eq_attr "type" "ishift")
9462 (and (match_operand 2 "const1_operand" "")
9463 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9464 (const_int 0)))))
9465 (const_string "0")
9466 (const_string "*")))
9467 (set_attr "mode" "SI")])
9468
9469 (define_insn "*ashl<mode>3_cconly"
9470 [(set (reg FLAGS_REG)
9471 (compare
9472 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9473 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9474 (const_int 0)))
9475 (clobber (match_scratch:SWI 0 "=<r>"))]
9476 "(optimize_function_for_size_p (cfun)
9477 || !TARGET_PARTIAL_FLAG_REG_STALL
9478 || (operands[2] == const1_rtx
9479 && (TARGET_SHIFT1
9480 || TARGET_DOUBLE_WITH_ADD)))
9481 && ix86_match_ccmode (insn, CCGOCmode)"
9482 {
9483 switch (get_attr_type (insn))
9484 {
9485 case TYPE_ALU:
9486 gcc_assert (operands[2] == const1_rtx);
9487 return "add{<imodesuffix>}\t%0, %0";
9488
9489 default:
9490 if (operands[2] == const1_rtx
9491 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9492 return "sal{<imodesuffix>}\t%0";
9493 else
9494 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9495 }
9496 }
9497 [(set (attr "type")
9498 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9499 (const_int 0))
9500 (match_operand 0 "register_operand" ""))
9501 (match_operand 2 "const1_operand" ""))
9502 (const_string "alu")
9503 ]
9504 (const_string "ishift")))
9505 (set (attr "length_immediate")
9506 (if_then_else
9507 (ior (eq_attr "type" "alu")
9508 (and (eq_attr "type" "ishift")
9509 (and (match_operand 2 "const1_operand" "")
9510 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9511 (const_int 0)))))
9512 (const_string "0")
9513 (const_string "*")))
9514 (set_attr "mode" "<MODE>")])
9515
9516 ;; See comment above `ashl<mode>3' about how this works.
9517
9518 (define_expand "<shiftrt_insn><mode>3"
9519 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9520 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9521 (match_operand:QI 2 "nonmemory_operand" "")))]
9522 ""
9523 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9524
9525 ;; Avoid useless masking of count operand.
9526 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9527 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9528 (any_shiftrt:SWI48
9529 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9530 (subreg:QI
9531 (and:SI
9532 (match_operand:SI 2 "nonimmediate_operand" "c")
9533 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9534 (clobber (reg:CC FLAGS_REG))]
9535 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9536 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9537 == GET_MODE_BITSIZE (<MODE>mode)-1"
9538 "#"
9539 "&& 1"
9540 [(parallel [(set (match_dup 0)
9541 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9542 (clobber (reg:CC FLAGS_REG))])]
9543 {
9544 if (can_create_pseudo_p ())
9545 operands [2] = force_reg (SImode, operands[2]);
9546
9547 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9548 }
9549 [(set_attr "type" "ishift")
9550 (set_attr "mode" "<MODE>")])
9551
9552 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9553 [(set (match_operand:DWI 0 "register_operand" "=r")
9554 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9555 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9556 (clobber (reg:CC FLAGS_REG))]
9557 ""
9558 "#"
9559 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9560 [(const_int 0)]
9561 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9562 [(set_attr "type" "multi")])
9563
9564 ;; By default we don't ask for a scratch register, because when DWImode
9565 ;; values are manipulated, registers are already at a premium. But if
9566 ;; we have one handy, we won't turn it away.
9567
9568 (define_peephole2
9569 [(match_scratch:DWIH 3 "r")
9570 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9571 (any_shiftrt:<DWI>
9572 (match_operand:<DWI> 1 "register_operand" "")
9573 (match_operand:QI 2 "nonmemory_operand" "")))
9574 (clobber (reg:CC FLAGS_REG))])
9575 (match_dup 3)]
9576 "TARGET_CMOVE"
9577 [(const_int 0)]
9578 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9579
9580 (define_insn "x86_64_shrd"
9581 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9582 (ior:DI (ashiftrt:DI (match_dup 0)
9583 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9584 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9585 (minus:QI (const_int 64) (match_dup 2)))))
9586 (clobber (reg:CC FLAGS_REG))]
9587 "TARGET_64BIT"
9588 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9589 [(set_attr "type" "ishift")
9590 (set_attr "prefix_0f" "1")
9591 (set_attr "mode" "DI")
9592 (set_attr "athlon_decode" "vector")
9593 (set_attr "amdfam10_decode" "vector")
9594 (set_attr "bdver1_decode" "vector")])
9595
9596 (define_insn "x86_shrd"
9597 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9598 (ior:SI (ashiftrt:SI (match_dup 0)
9599 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9600 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9601 (minus:QI (const_int 32) (match_dup 2)))))
9602 (clobber (reg:CC FLAGS_REG))]
9603 ""
9604 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9605 [(set_attr "type" "ishift")
9606 (set_attr "prefix_0f" "1")
9607 (set_attr "mode" "SI")
9608 (set_attr "pent_pair" "np")
9609 (set_attr "athlon_decode" "vector")
9610 (set_attr "amdfam10_decode" "vector")
9611 (set_attr "bdver1_decode" "vector")])
9612
9613 (define_insn "ashrdi3_cvt"
9614 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9615 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9616 (match_operand:QI 2 "const_int_operand" "")))
9617 (clobber (reg:CC FLAGS_REG))]
9618 "TARGET_64BIT && INTVAL (operands[2]) == 63
9619 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9620 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9621 "@
9622 {cqto|cqo}
9623 sar{q}\t{%2, %0|%0, %2}"
9624 [(set_attr "type" "imovx,ishift")
9625 (set_attr "prefix_0f" "0,*")
9626 (set_attr "length_immediate" "0,*")
9627 (set_attr "modrm" "0,1")
9628 (set_attr "mode" "DI")])
9629
9630 (define_insn "ashrsi3_cvt"
9631 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9632 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9633 (match_operand:QI 2 "const_int_operand" "")))
9634 (clobber (reg:CC FLAGS_REG))]
9635 "INTVAL (operands[2]) == 31
9636 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9637 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9638 "@
9639 {cltd|cdq}
9640 sar{l}\t{%2, %0|%0, %2}"
9641 [(set_attr "type" "imovx,ishift")
9642 (set_attr "prefix_0f" "0,*")
9643 (set_attr "length_immediate" "0,*")
9644 (set_attr "modrm" "0,1")
9645 (set_attr "mode" "SI")])
9646
9647 (define_insn "*ashrsi3_cvt_zext"
9648 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9649 (zero_extend:DI
9650 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9651 (match_operand:QI 2 "const_int_operand" ""))))
9652 (clobber (reg:CC FLAGS_REG))]
9653 "TARGET_64BIT && INTVAL (operands[2]) == 31
9654 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9655 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9656 "@
9657 {cltd|cdq}
9658 sar{l}\t{%2, %k0|%k0, %2}"
9659 [(set_attr "type" "imovx,ishift")
9660 (set_attr "prefix_0f" "0,*")
9661 (set_attr "length_immediate" "0,*")
9662 (set_attr "modrm" "0,1")
9663 (set_attr "mode" "SI")])
9664
9665 (define_expand "x86_shift<mode>_adj_3"
9666 [(use (match_operand:SWI48 0 "register_operand" ""))
9667 (use (match_operand:SWI48 1 "register_operand" ""))
9668 (use (match_operand:QI 2 "register_operand" ""))]
9669 ""
9670 {
9671 rtx label = gen_label_rtx ();
9672 rtx tmp;
9673
9674 emit_insn (gen_testqi_ccz_1 (operands[2],
9675 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9676
9677 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9678 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9679 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9680 gen_rtx_LABEL_REF (VOIDmode, label),
9681 pc_rtx);
9682 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9683 JUMP_LABEL (tmp) = label;
9684
9685 emit_move_insn (operands[0], operands[1]);
9686 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9687 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9688 emit_label (label);
9689 LABEL_NUSES (label) = 1;
9690
9691 DONE;
9692 })
9693
9694 (define_insn "*<shiftrt_insn><mode>3_1"
9695 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9696 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9697 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9698 (clobber (reg:CC FLAGS_REG))]
9699 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9700 {
9701 if (operands[2] == const1_rtx
9702 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9703 return "<shiftrt>{<imodesuffix>}\t%0";
9704 else
9705 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9706 }
9707 [(set_attr "type" "ishift")
9708 (set (attr "length_immediate")
9709 (if_then_else
9710 (and (match_operand 2 "const1_operand" "")
9711 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9712 (const_int 0)))
9713 (const_string "0")
9714 (const_string "*")))
9715 (set_attr "mode" "<MODE>")])
9716
9717 (define_insn "*<shiftrt_insn>si3_1_zext"
9718 [(set (match_operand:DI 0 "register_operand" "=r")
9719 (zero_extend:DI
9720 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9721 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9722 (clobber (reg:CC FLAGS_REG))]
9723 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9724 {
9725 if (operands[2] == const1_rtx
9726 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9727 return "<shiftrt>{l}\t%k0";
9728 else
9729 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9730 }
9731 [(set_attr "type" "ishift")
9732 (set (attr "length_immediate")
9733 (if_then_else
9734 (and (match_operand 2 "const1_operand" "")
9735 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9736 (const_int 0)))
9737 (const_string "0")
9738 (const_string "*")))
9739 (set_attr "mode" "SI")])
9740
9741 (define_insn "*<shiftrt_insn>qi3_1_slp"
9742 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9743 (any_shiftrt:QI (match_dup 0)
9744 (match_operand:QI 1 "nonmemory_operand" "cI")))
9745 (clobber (reg:CC FLAGS_REG))]
9746 "(optimize_function_for_size_p (cfun)
9747 || !TARGET_PARTIAL_REG_STALL
9748 || (operands[1] == const1_rtx
9749 && TARGET_SHIFT1))"
9750 {
9751 if (operands[1] == const1_rtx
9752 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9753 return "<shiftrt>{b}\t%0";
9754 else
9755 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9756 }
9757 [(set_attr "type" "ishift1")
9758 (set (attr "length_immediate")
9759 (if_then_else
9760 (and (match_operand 1 "const1_operand" "")
9761 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9762 (const_int 0)))
9763 (const_string "0")
9764 (const_string "*")))
9765 (set_attr "mode" "QI")])
9766
9767 ;; This pattern can't accept a variable shift count, since shifts by
9768 ;; zero don't affect the flags. We assume that shifts by constant
9769 ;; zero are optimized away.
9770 (define_insn "*<shiftrt_insn><mode>3_cmp"
9771 [(set (reg FLAGS_REG)
9772 (compare
9773 (any_shiftrt:SWI
9774 (match_operand:SWI 1 "nonimmediate_operand" "0")
9775 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9776 (const_int 0)))
9777 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9778 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9779 "(optimize_function_for_size_p (cfun)
9780 || !TARGET_PARTIAL_FLAG_REG_STALL
9781 || (operands[2] == const1_rtx
9782 && TARGET_SHIFT1))
9783 && ix86_match_ccmode (insn, CCGOCmode)
9784 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9785 {
9786 if (operands[2] == const1_rtx
9787 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9788 return "<shiftrt>{<imodesuffix>}\t%0";
9789 else
9790 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9791 }
9792 [(set_attr "type" "ishift")
9793 (set (attr "length_immediate")
9794 (if_then_else
9795 (and (match_operand 2 "const1_operand" "")
9796 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9797 (const_int 0)))
9798 (const_string "0")
9799 (const_string "*")))
9800 (set_attr "mode" "<MODE>")])
9801
9802 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9803 [(set (reg FLAGS_REG)
9804 (compare
9805 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9806 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9807 (const_int 0)))
9808 (set (match_operand:DI 0 "register_operand" "=r")
9809 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9810 "TARGET_64BIT
9811 && (optimize_function_for_size_p (cfun)
9812 || !TARGET_PARTIAL_FLAG_REG_STALL
9813 || (operands[2] == const1_rtx
9814 && TARGET_SHIFT1))
9815 && ix86_match_ccmode (insn, CCGOCmode)
9816 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9817 {
9818 if (operands[2] == const1_rtx
9819 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9820 return "<shiftrt>{l}\t%k0";
9821 else
9822 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9823 }
9824 [(set_attr "type" "ishift")
9825 (set (attr "length_immediate")
9826 (if_then_else
9827 (and (match_operand 2 "const1_operand" "")
9828 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9829 (const_int 0)))
9830 (const_string "0")
9831 (const_string "*")))
9832 (set_attr "mode" "SI")])
9833
9834 (define_insn "*<shiftrt_insn><mode>3_cconly"
9835 [(set (reg FLAGS_REG)
9836 (compare
9837 (any_shiftrt:SWI
9838 (match_operand:SWI 1 "register_operand" "0")
9839 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9840 (const_int 0)))
9841 (clobber (match_scratch:SWI 0 "=<r>"))]
9842 "(optimize_function_for_size_p (cfun)
9843 || !TARGET_PARTIAL_FLAG_REG_STALL
9844 || (operands[2] == const1_rtx
9845 && TARGET_SHIFT1))
9846 && ix86_match_ccmode (insn, CCGOCmode)"
9847 {
9848 if (operands[2] == const1_rtx
9849 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9850 return "<shiftrt>{<imodesuffix>}\t%0";
9851 else
9852 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9853 }
9854 [(set_attr "type" "ishift")
9855 (set (attr "length_immediate")
9856 (if_then_else
9857 (and (match_operand 2 "const1_operand" "")
9858 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9859 (const_int 0)))
9860 (const_string "0")
9861 (const_string "*")))
9862 (set_attr "mode" "<MODE>")])
9863 \f
9864 ;; Rotate instructions
9865
9866 (define_expand "<rotate_insn>ti3"
9867 [(set (match_operand:TI 0 "register_operand" "")
9868 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9869 (match_operand:QI 2 "nonmemory_operand" "")))]
9870 "TARGET_64BIT"
9871 {
9872 if (const_1_to_63_operand (operands[2], VOIDmode))
9873 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9874 (operands[0], operands[1], operands[2]));
9875 else
9876 FAIL;
9877
9878 DONE;
9879 })
9880
9881 (define_expand "<rotate_insn>di3"
9882 [(set (match_operand:DI 0 "shiftdi_operand" "")
9883 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9884 (match_operand:QI 2 "nonmemory_operand" "")))]
9885 ""
9886 {
9887 if (TARGET_64BIT)
9888 ix86_expand_binary_operator (<CODE>, DImode, operands);
9889 else if (const_1_to_31_operand (operands[2], VOIDmode))
9890 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9891 (operands[0], operands[1], operands[2]));
9892 else
9893 FAIL;
9894
9895 DONE;
9896 })
9897
9898 (define_expand "<rotate_insn><mode>3"
9899 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9900 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9901 (match_operand:QI 2 "nonmemory_operand" "")))]
9902 ""
9903 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9904
9905 ;; Avoid useless masking of count operand.
9906 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9907 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9908 (any_rotate:SWI48
9909 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9910 (subreg:QI
9911 (and:SI
9912 (match_operand:SI 2 "nonimmediate_operand" "c")
9913 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9914 (clobber (reg:CC FLAGS_REG))]
9915 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9916 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9917 == GET_MODE_BITSIZE (<MODE>mode)-1"
9918 "#"
9919 "&& 1"
9920 [(parallel [(set (match_dup 0)
9921 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9922 (clobber (reg:CC FLAGS_REG))])]
9923 {
9924 if (can_create_pseudo_p ())
9925 operands [2] = force_reg (SImode, operands[2]);
9926
9927 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9928 }
9929 [(set_attr "type" "rotate")
9930 (set_attr "mode" "<MODE>")])
9931
9932 ;; Implement rotation using two double-precision
9933 ;; shift instructions and a scratch register.
9934
9935 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9936 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9937 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9938 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9939 (clobber (reg:CC FLAGS_REG))
9940 (clobber (match_scratch:DWIH 3 "=&r"))]
9941 ""
9942 "#"
9943 "reload_completed"
9944 [(set (match_dup 3) (match_dup 4))
9945 (parallel
9946 [(set (match_dup 4)
9947 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9948 (lshiftrt:DWIH (match_dup 5)
9949 (minus:QI (match_dup 6) (match_dup 2)))))
9950 (clobber (reg:CC FLAGS_REG))])
9951 (parallel
9952 [(set (match_dup 5)
9953 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9954 (lshiftrt:DWIH (match_dup 3)
9955 (minus:QI (match_dup 6) (match_dup 2)))))
9956 (clobber (reg:CC FLAGS_REG))])]
9957 {
9958 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9959
9960 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9961 })
9962
9963 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
9964 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9965 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9966 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9967 (clobber (reg:CC FLAGS_REG))
9968 (clobber (match_scratch:DWIH 3 "=&r"))]
9969 ""
9970 "#"
9971 "reload_completed"
9972 [(set (match_dup 3) (match_dup 4))
9973 (parallel
9974 [(set (match_dup 4)
9975 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
9976 (ashift:DWIH (match_dup 5)
9977 (minus:QI (match_dup 6) (match_dup 2)))))
9978 (clobber (reg:CC FLAGS_REG))])
9979 (parallel
9980 [(set (match_dup 5)
9981 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
9982 (ashift:DWIH (match_dup 3)
9983 (minus:QI (match_dup 6) (match_dup 2)))))
9984 (clobber (reg:CC FLAGS_REG))])]
9985 {
9986 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9987
9988 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9989 })
9990
9991 (define_insn "*<rotate_insn><mode>3_1"
9992 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9993 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9994 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9995 (clobber (reg:CC FLAGS_REG))]
9996 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9997 {
9998 if (operands[2] == const1_rtx
9999 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10000 return "<rotate>{<imodesuffix>}\t%0";
10001 else
10002 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10003 }
10004 [(set_attr "type" "rotate")
10005 (set (attr "length_immediate")
10006 (if_then_else
10007 (and (match_operand 2 "const1_operand" "")
10008 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10009 (const_int 0)))
10010 (const_string "0")
10011 (const_string "*")))
10012 (set_attr "mode" "<MODE>")])
10013
10014 (define_insn "*<rotate_insn>si3_1_zext"
10015 [(set (match_operand:DI 0 "register_operand" "=r")
10016 (zero_extend:DI
10017 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10018 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10019 (clobber (reg:CC FLAGS_REG))]
10020 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10021 {
10022 if (operands[2] == const1_rtx
10023 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10024 return "<rotate>{l}\t%k0";
10025 else
10026 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10027 }
10028 [(set_attr "type" "rotate")
10029 (set (attr "length_immediate")
10030 (if_then_else
10031 (and (match_operand 2 "const1_operand" "")
10032 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10033 (const_int 0)))
10034 (const_string "0")
10035 (const_string "*")))
10036 (set_attr "mode" "SI")])
10037
10038 (define_insn "*<rotate_insn>qi3_1_slp"
10039 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10040 (any_rotate:QI (match_dup 0)
10041 (match_operand:QI 1 "nonmemory_operand" "cI")))
10042 (clobber (reg:CC FLAGS_REG))]
10043 "(optimize_function_for_size_p (cfun)
10044 || !TARGET_PARTIAL_REG_STALL
10045 || (operands[1] == const1_rtx
10046 && TARGET_SHIFT1))"
10047 {
10048 if (operands[1] == const1_rtx
10049 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10050 return "<rotate>{b}\t%0";
10051 else
10052 return "<rotate>{b}\t{%1, %0|%0, %1}";
10053 }
10054 [(set_attr "type" "rotate1")
10055 (set (attr "length_immediate")
10056 (if_then_else
10057 (and (match_operand 1 "const1_operand" "")
10058 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10059 (const_int 0)))
10060 (const_string "0")
10061 (const_string "*")))
10062 (set_attr "mode" "QI")])
10063
10064 (define_split
10065 [(set (match_operand:HI 0 "register_operand" "")
10066 (any_rotate:HI (match_dup 0) (const_int 8)))
10067 (clobber (reg:CC FLAGS_REG))]
10068 "reload_completed
10069 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10070 [(parallel [(set (strict_low_part (match_dup 0))
10071 (bswap:HI (match_dup 0)))
10072 (clobber (reg:CC FLAGS_REG))])])
10073 \f
10074 ;; Bit set / bit test instructions
10075
10076 (define_expand "extv"
10077 [(set (match_operand:SI 0 "register_operand" "")
10078 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10079 (match_operand:SI 2 "const8_operand" "")
10080 (match_operand:SI 3 "const8_operand" "")))]
10081 ""
10082 {
10083 /* Handle extractions from %ah et al. */
10084 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10085 FAIL;
10086
10087 /* From mips.md: extract_bit_field doesn't verify that our source
10088 matches the predicate, so check it again here. */
10089 if (! ext_register_operand (operands[1], VOIDmode))
10090 FAIL;
10091 })
10092
10093 (define_expand "extzv"
10094 [(set (match_operand:SI 0 "register_operand" "")
10095 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10096 (match_operand:SI 2 "const8_operand" "")
10097 (match_operand:SI 3 "const8_operand" "")))]
10098 ""
10099 {
10100 /* Handle extractions from %ah et al. */
10101 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10102 FAIL;
10103
10104 /* From mips.md: extract_bit_field doesn't verify that our source
10105 matches the predicate, so check it again here. */
10106 if (! ext_register_operand (operands[1], VOIDmode))
10107 FAIL;
10108 })
10109
10110 (define_expand "insv"
10111 [(set (zero_extract (match_operand 0 "register_operand" "")
10112 (match_operand 1 "const_int_operand" "")
10113 (match_operand 2 "const_int_operand" ""))
10114 (match_operand 3 "register_operand" ""))]
10115 ""
10116 {
10117 rtx (*gen_mov_insv_1) (rtx, rtx);
10118
10119 if (ix86_expand_pinsr (operands))
10120 DONE;
10121
10122 /* Handle insertions to %ah et al. */
10123 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10124 FAIL;
10125
10126 /* From mips.md: insert_bit_field doesn't verify that our source
10127 matches the predicate, so check it again here. */
10128 if (! ext_register_operand (operands[0], VOIDmode))
10129 FAIL;
10130
10131 gen_mov_insv_1 = (TARGET_64BIT
10132 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10133
10134 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10135 DONE;
10136 })
10137
10138 ;; %%% bts, btr, btc, bt.
10139 ;; In general these instructions are *slow* when applied to memory,
10140 ;; since they enforce atomic operation. When applied to registers,
10141 ;; it depends on the cpu implementation. They're never faster than
10142 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10143 ;; no point. But in 64-bit, we can't hold the relevant immediates
10144 ;; within the instruction itself, so operating on bits in the high
10145 ;; 32-bits of a register becomes easier.
10146 ;;
10147 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10148 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10149 ;; negdf respectively, so they can never be disabled entirely.
10150
10151 (define_insn "*btsq"
10152 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10153 (const_int 1)
10154 (match_operand:DI 1 "const_0_to_63_operand" ""))
10155 (const_int 1))
10156 (clobber (reg:CC FLAGS_REG))]
10157 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10158 "bts{q}\t{%1, %0|%0, %1}"
10159 [(set_attr "type" "alu1")
10160 (set_attr "prefix_0f" "1")
10161 (set_attr "mode" "DI")])
10162
10163 (define_insn "*btrq"
10164 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10165 (const_int 1)
10166 (match_operand:DI 1 "const_0_to_63_operand" ""))
10167 (const_int 0))
10168 (clobber (reg:CC FLAGS_REG))]
10169 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10170 "btr{q}\t{%1, %0|%0, %1}"
10171 [(set_attr "type" "alu1")
10172 (set_attr "prefix_0f" "1")
10173 (set_attr "mode" "DI")])
10174
10175 (define_insn "*btcq"
10176 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10177 (const_int 1)
10178 (match_operand:DI 1 "const_0_to_63_operand" ""))
10179 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10182 "btc{q}\t{%1, %0|%0, %1}"
10183 [(set_attr "type" "alu1")
10184 (set_attr "prefix_0f" "1")
10185 (set_attr "mode" "DI")])
10186
10187 ;; Allow Nocona to avoid these instructions if a register is available.
10188
10189 (define_peephole2
10190 [(match_scratch:DI 2 "r")
10191 (parallel [(set (zero_extract:DI
10192 (match_operand:DI 0 "register_operand" "")
10193 (const_int 1)
10194 (match_operand:DI 1 "const_0_to_63_operand" ""))
10195 (const_int 1))
10196 (clobber (reg:CC FLAGS_REG))])]
10197 "TARGET_64BIT && !TARGET_USE_BT"
10198 [(const_int 0)]
10199 {
10200 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10201 rtx op1;
10202
10203 if (HOST_BITS_PER_WIDE_INT >= 64)
10204 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10205 else if (i < HOST_BITS_PER_WIDE_INT)
10206 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10207 else
10208 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10209
10210 op1 = immed_double_const (lo, hi, DImode);
10211 if (i >= 31)
10212 {
10213 emit_move_insn (operands[2], op1);
10214 op1 = operands[2];
10215 }
10216
10217 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10218 DONE;
10219 })
10220
10221 (define_peephole2
10222 [(match_scratch:DI 2 "r")
10223 (parallel [(set (zero_extract:DI
10224 (match_operand:DI 0 "register_operand" "")
10225 (const_int 1)
10226 (match_operand:DI 1 "const_0_to_63_operand" ""))
10227 (const_int 0))
10228 (clobber (reg:CC FLAGS_REG))])]
10229 "TARGET_64BIT && !TARGET_USE_BT"
10230 [(const_int 0)]
10231 {
10232 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10233 rtx op1;
10234
10235 if (HOST_BITS_PER_WIDE_INT >= 64)
10236 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10237 else if (i < HOST_BITS_PER_WIDE_INT)
10238 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10239 else
10240 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10241
10242 op1 = immed_double_const (~lo, ~hi, DImode);
10243 if (i >= 32)
10244 {
10245 emit_move_insn (operands[2], op1);
10246 op1 = operands[2];
10247 }
10248
10249 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10250 DONE;
10251 })
10252
10253 (define_peephole2
10254 [(match_scratch:DI 2 "r")
10255 (parallel [(set (zero_extract:DI
10256 (match_operand:DI 0 "register_operand" "")
10257 (const_int 1)
10258 (match_operand:DI 1 "const_0_to_63_operand" ""))
10259 (not:DI (zero_extract:DI
10260 (match_dup 0) (const_int 1) (match_dup 1))))
10261 (clobber (reg:CC FLAGS_REG))])]
10262 "TARGET_64BIT && !TARGET_USE_BT"
10263 [(const_int 0)]
10264 {
10265 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10266 rtx op1;
10267
10268 if (HOST_BITS_PER_WIDE_INT >= 64)
10269 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10270 else if (i < HOST_BITS_PER_WIDE_INT)
10271 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10272 else
10273 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10274
10275 op1 = immed_double_const (lo, hi, DImode);
10276 if (i >= 31)
10277 {
10278 emit_move_insn (operands[2], op1);
10279 op1 = operands[2];
10280 }
10281
10282 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10283 DONE;
10284 })
10285
10286 (define_insn "*bt<mode>"
10287 [(set (reg:CCC FLAGS_REG)
10288 (compare:CCC
10289 (zero_extract:SWI48
10290 (match_operand:SWI48 0 "register_operand" "r")
10291 (const_int 1)
10292 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10293 (const_int 0)))]
10294 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10295 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10296 [(set_attr "type" "alu1")
10297 (set_attr "prefix_0f" "1")
10298 (set_attr "mode" "<MODE>")])
10299 \f
10300 ;; Store-flag instructions.
10301
10302 ;; For all sCOND expanders, also expand the compare or test insn that
10303 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10304
10305 (define_insn_and_split "*setcc_di_1"
10306 [(set (match_operand:DI 0 "register_operand" "=q")
10307 (match_operator:DI 1 "ix86_comparison_operator"
10308 [(reg FLAGS_REG) (const_int 0)]))]
10309 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10310 "#"
10311 "&& reload_completed"
10312 [(set (match_dup 2) (match_dup 1))
10313 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10314 {
10315 PUT_MODE (operands[1], QImode);
10316 operands[2] = gen_lowpart (QImode, operands[0]);
10317 })
10318
10319 (define_insn_and_split "*setcc_si_1_and"
10320 [(set (match_operand:SI 0 "register_operand" "=q")
10321 (match_operator:SI 1 "ix86_comparison_operator"
10322 [(reg FLAGS_REG) (const_int 0)]))
10323 (clobber (reg:CC FLAGS_REG))]
10324 "!TARGET_PARTIAL_REG_STALL
10325 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10326 "#"
10327 "&& reload_completed"
10328 [(set (match_dup 2) (match_dup 1))
10329 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10330 (clobber (reg:CC FLAGS_REG))])]
10331 {
10332 PUT_MODE (operands[1], QImode);
10333 operands[2] = gen_lowpart (QImode, operands[0]);
10334 })
10335
10336 (define_insn_and_split "*setcc_si_1_movzbl"
10337 [(set (match_operand:SI 0 "register_operand" "=q")
10338 (match_operator:SI 1 "ix86_comparison_operator"
10339 [(reg FLAGS_REG) (const_int 0)]))]
10340 "!TARGET_PARTIAL_REG_STALL
10341 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10342 "#"
10343 "&& reload_completed"
10344 [(set (match_dup 2) (match_dup 1))
10345 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10346 {
10347 PUT_MODE (operands[1], QImode);
10348 operands[2] = gen_lowpart (QImode, operands[0]);
10349 })
10350
10351 (define_insn "*setcc_qi"
10352 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10353 (match_operator:QI 1 "ix86_comparison_operator"
10354 [(reg FLAGS_REG) (const_int 0)]))]
10355 ""
10356 "set%C1\t%0"
10357 [(set_attr "type" "setcc")
10358 (set_attr "mode" "QI")])
10359
10360 (define_insn "*setcc_qi_slp"
10361 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10362 (match_operator:QI 1 "ix86_comparison_operator"
10363 [(reg FLAGS_REG) (const_int 0)]))]
10364 ""
10365 "set%C1\t%0"
10366 [(set_attr "type" "setcc")
10367 (set_attr "mode" "QI")])
10368
10369 ;; In general it is not safe to assume too much about CCmode registers,
10370 ;; so simplify-rtx stops when it sees a second one. Under certain
10371 ;; conditions this is safe on x86, so help combine not create
10372 ;;
10373 ;; seta %al
10374 ;; testb %al, %al
10375 ;; sete %al
10376
10377 (define_split
10378 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10379 (ne:QI (match_operator 1 "ix86_comparison_operator"
10380 [(reg FLAGS_REG) (const_int 0)])
10381 (const_int 0)))]
10382 ""
10383 [(set (match_dup 0) (match_dup 1))]
10384 "PUT_MODE (operands[1], QImode);")
10385
10386 (define_split
10387 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10388 (ne:QI (match_operator 1 "ix86_comparison_operator"
10389 [(reg FLAGS_REG) (const_int 0)])
10390 (const_int 0)))]
10391 ""
10392 [(set (match_dup 0) (match_dup 1))]
10393 "PUT_MODE (operands[1], QImode);")
10394
10395 (define_split
10396 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10397 (eq:QI (match_operator 1 "ix86_comparison_operator"
10398 [(reg FLAGS_REG) (const_int 0)])
10399 (const_int 0)))]
10400 ""
10401 [(set (match_dup 0) (match_dup 1))]
10402 {
10403 rtx new_op1 = copy_rtx (operands[1]);
10404 operands[1] = new_op1;
10405 PUT_MODE (new_op1, QImode);
10406 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10407 GET_MODE (XEXP (new_op1, 0))));
10408
10409 /* Make sure that (a) the CCmode we have for the flags is strong
10410 enough for the reversed compare or (b) we have a valid FP compare. */
10411 if (! ix86_comparison_operator (new_op1, VOIDmode))
10412 FAIL;
10413 })
10414
10415 (define_split
10416 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10417 (eq:QI (match_operator 1 "ix86_comparison_operator"
10418 [(reg FLAGS_REG) (const_int 0)])
10419 (const_int 0)))]
10420 ""
10421 [(set (match_dup 0) (match_dup 1))]
10422 {
10423 rtx new_op1 = copy_rtx (operands[1]);
10424 operands[1] = new_op1;
10425 PUT_MODE (new_op1, QImode);
10426 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10427 GET_MODE (XEXP (new_op1, 0))));
10428
10429 /* Make sure that (a) the CCmode we have for the flags is strong
10430 enough for the reversed compare or (b) we have a valid FP compare. */
10431 if (! ix86_comparison_operator (new_op1, VOIDmode))
10432 FAIL;
10433 })
10434
10435 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10436 ;; subsequent logical operations are used to imitate conditional moves.
10437 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10438 ;; it directly.
10439
10440 (define_insn "setcc_<mode>_sse"
10441 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10442 (match_operator:MODEF 3 "sse_comparison_operator"
10443 [(match_operand:MODEF 1 "register_operand" "0,x")
10444 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10445 "SSE_FLOAT_MODE_P (<MODE>mode)"
10446 "@
10447 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10448 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10449 [(set_attr "isa" "noavx,avx")
10450 (set_attr "type" "ssecmp")
10451 (set_attr "length_immediate" "1")
10452 (set_attr "prefix" "orig,vex")
10453 (set_attr "mode" "<MODE>")])
10454 \f
10455 ;; Basic conditional jump instructions.
10456 ;; We ignore the overflow flag for signed branch instructions.
10457
10458 (define_insn "*jcc_1"
10459 [(set (pc)
10460 (if_then_else (match_operator 1 "ix86_comparison_operator"
10461 [(reg FLAGS_REG) (const_int 0)])
10462 (label_ref (match_operand 0 "" ""))
10463 (pc)))]
10464 ""
10465 "%+j%C1\t%l0"
10466 [(set_attr "type" "ibr")
10467 (set_attr "modrm" "0")
10468 (set (attr "length")
10469 (if_then_else (and (ge (minus (match_dup 0) (pc))
10470 (const_int -126))
10471 (lt (minus (match_dup 0) (pc))
10472 (const_int 128)))
10473 (const_int 2)
10474 (const_int 6)))])
10475
10476 (define_insn "*jcc_2"
10477 [(set (pc)
10478 (if_then_else (match_operator 1 "ix86_comparison_operator"
10479 [(reg FLAGS_REG) (const_int 0)])
10480 (pc)
10481 (label_ref (match_operand 0 "" ""))))]
10482 ""
10483 "%+j%c1\t%l0"
10484 [(set_attr "type" "ibr")
10485 (set_attr "modrm" "0")
10486 (set (attr "length")
10487 (if_then_else (and (ge (minus (match_dup 0) (pc))
10488 (const_int -126))
10489 (lt (minus (match_dup 0) (pc))
10490 (const_int 128)))
10491 (const_int 2)
10492 (const_int 6)))])
10493
10494 ;; In general it is not safe to assume too much about CCmode registers,
10495 ;; so simplify-rtx stops when it sees a second one. Under certain
10496 ;; conditions this is safe on x86, so help combine not create
10497 ;;
10498 ;; seta %al
10499 ;; testb %al, %al
10500 ;; je Lfoo
10501
10502 (define_split
10503 [(set (pc)
10504 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10505 [(reg FLAGS_REG) (const_int 0)])
10506 (const_int 0))
10507 (label_ref (match_operand 1 "" ""))
10508 (pc)))]
10509 ""
10510 [(set (pc)
10511 (if_then_else (match_dup 0)
10512 (label_ref (match_dup 1))
10513 (pc)))]
10514 "PUT_MODE (operands[0], VOIDmode);")
10515
10516 (define_split
10517 [(set (pc)
10518 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10519 [(reg FLAGS_REG) (const_int 0)])
10520 (const_int 0))
10521 (label_ref (match_operand 1 "" ""))
10522 (pc)))]
10523 ""
10524 [(set (pc)
10525 (if_then_else (match_dup 0)
10526 (label_ref (match_dup 1))
10527 (pc)))]
10528 {
10529 rtx new_op0 = copy_rtx (operands[0]);
10530 operands[0] = new_op0;
10531 PUT_MODE (new_op0, VOIDmode);
10532 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10533 GET_MODE (XEXP (new_op0, 0))));
10534
10535 /* Make sure that (a) the CCmode we have for the flags is strong
10536 enough for the reversed compare or (b) we have a valid FP compare. */
10537 if (! ix86_comparison_operator (new_op0, VOIDmode))
10538 FAIL;
10539 })
10540
10541 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10542 ;; pass generates from shift insn with QImode operand. Actually, the mode
10543 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10544 ;; appropriate modulo of the bit offset value.
10545
10546 (define_insn_and_split "*jcc_bt<mode>"
10547 [(set (pc)
10548 (if_then_else (match_operator 0 "bt_comparison_operator"
10549 [(zero_extract:SWI48
10550 (match_operand:SWI48 1 "register_operand" "r")
10551 (const_int 1)
10552 (zero_extend:SI
10553 (match_operand:QI 2 "register_operand" "r")))
10554 (const_int 0)])
10555 (label_ref (match_operand 3 "" ""))
10556 (pc)))
10557 (clobber (reg:CC FLAGS_REG))]
10558 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10559 "#"
10560 "&& 1"
10561 [(set (reg:CCC FLAGS_REG)
10562 (compare:CCC
10563 (zero_extract:SWI48
10564 (match_dup 1)
10565 (const_int 1)
10566 (match_dup 2))
10567 (const_int 0)))
10568 (set (pc)
10569 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10570 (label_ref (match_dup 3))
10571 (pc)))]
10572 {
10573 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10574
10575 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10576 })
10577
10578 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10579 ;; also for DImode, this is what combine produces.
10580 (define_insn_and_split "*jcc_bt<mode>_mask"
10581 [(set (pc)
10582 (if_then_else (match_operator 0 "bt_comparison_operator"
10583 [(zero_extract:SWI48
10584 (match_operand:SWI48 1 "register_operand" "r")
10585 (const_int 1)
10586 (and:SI
10587 (match_operand:SI 2 "register_operand" "r")
10588 (match_operand:SI 3 "const_int_operand" "n")))])
10589 (label_ref (match_operand 4 "" ""))
10590 (pc)))
10591 (clobber (reg:CC FLAGS_REG))]
10592 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10593 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10594 == GET_MODE_BITSIZE (<MODE>mode)-1"
10595 "#"
10596 "&& 1"
10597 [(set (reg:CCC FLAGS_REG)
10598 (compare:CCC
10599 (zero_extract:SWI48
10600 (match_dup 1)
10601 (const_int 1)
10602 (match_dup 2))
10603 (const_int 0)))
10604 (set (pc)
10605 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10606 (label_ref (match_dup 4))
10607 (pc)))]
10608 {
10609 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10610
10611 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10612 })
10613
10614 (define_insn_and_split "*jcc_btsi_1"
10615 [(set (pc)
10616 (if_then_else (match_operator 0 "bt_comparison_operator"
10617 [(and:SI
10618 (lshiftrt:SI
10619 (match_operand:SI 1 "register_operand" "r")
10620 (match_operand:QI 2 "register_operand" "r"))
10621 (const_int 1))
10622 (const_int 0)])
10623 (label_ref (match_operand 3 "" ""))
10624 (pc)))
10625 (clobber (reg:CC FLAGS_REG))]
10626 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10627 "#"
10628 "&& 1"
10629 [(set (reg:CCC FLAGS_REG)
10630 (compare:CCC
10631 (zero_extract:SI
10632 (match_dup 1)
10633 (const_int 1)
10634 (match_dup 2))
10635 (const_int 0)))
10636 (set (pc)
10637 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10638 (label_ref (match_dup 3))
10639 (pc)))]
10640 {
10641 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10642
10643 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10644 })
10645
10646 ;; avoid useless masking of bit offset operand
10647 (define_insn_and_split "*jcc_btsi_mask_1"
10648 [(set (pc)
10649 (if_then_else
10650 (match_operator 0 "bt_comparison_operator"
10651 [(and:SI
10652 (lshiftrt:SI
10653 (match_operand:SI 1 "register_operand" "r")
10654 (subreg:QI
10655 (and:SI
10656 (match_operand:SI 2 "register_operand" "r")
10657 (match_operand:SI 3 "const_int_operand" "n")) 0))
10658 (const_int 1))
10659 (const_int 0)])
10660 (label_ref (match_operand 4 "" ""))
10661 (pc)))
10662 (clobber (reg:CC FLAGS_REG))]
10663 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10664 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10665 "#"
10666 "&& 1"
10667 [(set (reg:CCC FLAGS_REG)
10668 (compare:CCC
10669 (zero_extract:SI
10670 (match_dup 1)
10671 (const_int 1)
10672 (match_dup 2))
10673 (const_int 0)))
10674 (set (pc)
10675 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10676 (label_ref (match_dup 4))
10677 (pc)))]
10678 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10679
10680 ;; Define combination compare-and-branch fp compare instructions to help
10681 ;; combine.
10682
10683 (define_insn "*fp_jcc_1_387"
10684 [(set (pc)
10685 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10686 [(match_operand 1 "register_operand" "f")
10687 (match_operand 2 "nonimmediate_operand" "fm")])
10688 (label_ref (match_operand 3 "" ""))
10689 (pc)))
10690 (clobber (reg:CCFP FPSR_REG))
10691 (clobber (reg:CCFP FLAGS_REG))
10692 (clobber (match_scratch:HI 4 "=a"))]
10693 "TARGET_80387
10694 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10695 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10696 && SELECT_CC_MODE (GET_CODE (operands[0]),
10697 operands[1], operands[2]) == CCFPmode
10698 && !TARGET_CMOVE"
10699 "#")
10700
10701 (define_insn "*fp_jcc_1r_387"
10702 [(set (pc)
10703 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10704 [(match_operand 1 "register_operand" "f")
10705 (match_operand 2 "nonimmediate_operand" "fm")])
10706 (pc)
10707 (label_ref (match_operand 3 "" ""))))
10708 (clobber (reg:CCFP FPSR_REG))
10709 (clobber (reg:CCFP FLAGS_REG))
10710 (clobber (match_scratch:HI 4 "=a"))]
10711 "TARGET_80387
10712 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10713 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10714 && SELECT_CC_MODE (GET_CODE (operands[0]),
10715 operands[1], operands[2]) == CCFPmode
10716 && !TARGET_CMOVE"
10717 "#")
10718
10719 (define_insn "*fp_jcc_2_387"
10720 [(set (pc)
10721 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10722 [(match_operand 1 "register_operand" "f")
10723 (match_operand 2 "register_operand" "f")])
10724 (label_ref (match_operand 3 "" ""))
10725 (pc)))
10726 (clobber (reg:CCFP FPSR_REG))
10727 (clobber (reg:CCFP FLAGS_REG))
10728 (clobber (match_scratch:HI 4 "=a"))]
10729 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10730 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10731 && !TARGET_CMOVE"
10732 "#")
10733
10734 (define_insn "*fp_jcc_2r_387"
10735 [(set (pc)
10736 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10737 [(match_operand 1 "register_operand" "f")
10738 (match_operand 2 "register_operand" "f")])
10739 (pc)
10740 (label_ref (match_operand 3 "" ""))))
10741 (clobber (reg:CCFP FPSR_REG))
10742 (clobber (reg:CCFP FLAGS_REG))
10743 (clobber (match_scratch:HI 4 "=a"))]
10744 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10745 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10746 && !TARGET_CMOVE"
10747 "#")
10748
10749 (define_insn "*fp_jcc_3_387"
10750 [(set (pc)
10751 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10752 [(match_operand 1 "register_operand" "f")
10753 (match_operand 2 "const0_operand" "")])
10754 (label_ref (match_operand 3 "" ""))
10755 (pc)))
10756 (clobber (reg:CCFP FPSR_REG))
10757 (clobber (reg:CCFP FLAGS_REG))
10758 (clobber (match_scratch:HI 4 "=a"))]
10759 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10760 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10761 && SELECT_CC_MODE (GET_CODE (operands[0]),
10762 operands[1], operands[2]) == CCFPmode
10763 && !TARGET_CMOVE"
10764 "#")
10765
10766 (define_split
10767 [(set (pc)
10768 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10769 [(match_operand 1 "register_operand" "")
10770 (match_operand 2 "nonimmediate_operand" "")])
10771 (match_operand 3 "" "")
10772 (match_operand 4 "" "")))
10773 (clobber (reg:CCFP FPSR_REG))
10774 (clobber (reg:CCFP FLAGS_REG))]
10775 "reload_completed"
10776 [(const_int 0)]
10777 {
10778 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10779 operands[3], operands[4], NULL_RTX, NULL_RTX);
10780 DONE;
10781 })
10782
10783 (define_split
10784 [(set (pc)
10785 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10786 [(match_operand 1 "register_operand" "")
10787 (match_operand 2 "general_operand" "")])
10788 (match_operand 3 "" "")
10789 (match_operand 4 "" "")))
10790 (clobber (reg:CCFP FPSR_REG))
10791 (clobber (reg:CCFP FLAGS_REG))
10792 (clobber (match_scratch:HI 5 "=a"))]
10793 "reload_completed"
10794 [(const_int 0)]
10795 {
10796 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10797 operands[3], operands[4], operands[5], NULL_RTX);
10798 DONE;
10799 })
10800
10801 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10802 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10803 ;; with a precedence over other operators and is always put in the first
10804 ;; place. Swap condition and operands to match ficom instruction.
10805
10806 (define_insn "*fp_jcc_4_<mode>_387"
10807 [(set (pc)
10808 (if_then_else
10809 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10810 [(match_operator 1 "float_operator"
10811 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10812 (match_operand 3 "register_operand" "f,f")])
10813 (label_ref (match_operand 4 "" ""))
10814 (pc)))
10815 (clobber (reg:CCFP FPSR_REG))
10816 (clobber (reg:CCFP FLAGS_REG))
10817 (clobber (match_scratch:HI 5 "=a,a"))]
10818 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10819 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10820 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10821 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10822 && !TARGET_CMOVE"
10823 "#")
10824
10825 (define_split
10826 [(set (pc)
10827 (if_then_else
10828 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10829 [(match_operator 1 "float_operator"
10830 [(match_operand:SWI24 2 "memory_operand" "")])
10831 (match_operand 3 "register_operand" "")])
10832 (match_operand 4 "" "")
10833 (match_operand 5 "" "")))
10834 (clobber (reg:CCFP FPSR_REG))
10835 (clobber (reg:CCFP FLAGS_REG))
10836 (clobber (match_scratch:HI 6 "=a"))]
10837 "reload_completed"
10838 [(const_int 0)]
10839 {
10840 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10841
10842 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10843 operands[3], operands[7],
10844 operands[4], operands[5], operands[6], NULL_RTX);
10845 DONE;
10846 })
10847
10848 ;; %%% Kill this when reload knows how to do it.
10849 (define_split
10850 [(set (pc)
10851 (if_then_else
10852 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10853 [(match_operator 1 "float_operator"
10854 [(match_operand:SWI24 2 "register_operand" "")])
10855 (match_operand 3 "register_operand" "")])
10856 (match_operand 4 "" "")
10857 (match_operand 5 "" "")))
10858 (clobber (reg:CCFP FPSR_REG))
10859 (clobber (reg:CCFP FLAGS_REG))
10860 (clobber (match_scratch:HI 6 "=a"))]
10861 "reload_completed"
10862 [(const_int 0)]
10863 {
10864 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10865 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10866
10867 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10868 operands[3], operands[7],
10869 operands[4], operands[5], operands[6], operands[2]);
10870 DONE;
10871 })
10872 \f
10873 ;; Unconditional and other jump instructions
10874
10875 (define_insn "jump"
10876 [(set (pc)
10877 (label_ref (match_operand 0 "" "")))]
10878 ""
10879 "jmp\t%l0"
10880 [(set_attr "type" "ibr")
10881 (set (attr "length")
10882 (if_then_else (and (ge (minus (match_dup 0) (pc))
10883 (const_int -126))
10884 (lt (minus (match_dup 0) (pc))
10885 (const_int 128)))
10886 (const_int 2)
10887 (const_int 5)))
10888 (set_attr "modrm" "0")])
10889
10890 (define_expand "indirect_jump"
10891 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
10892
10893 (define_insn "*indirect_jump"
10894 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
10895 ""
10896 "jmp\t%A0"
10897 [(set_attr "type" "ibr")
10898 (set_attr "length_immediate" "0")])
10899
10900 (define_expand "tablejump"
10901 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
10902 (use (label_ref (match_operand 1 "" "")))])]
10903 ""
10904 {
10905 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10906 relative. Convert the relative address to an absolute address. */
10907 if (flag_pic)
10908 {
10909 rtx op0, op1;
10910 enum rtx_code code;
10911
10912 /* We can't use @GOTOFF for text labels on VxWorks;
10913 see gotoff_operand. */
10914 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10915 {
10916 code = PLUS;
10917 op0 = operands[0];
10918 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10919 }
10920 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10921 {
10922 code = PLUS;
10923 op0 = operands[0];
10924 op1 = pic_offset_table_rtx;
10925 }
10926 else
10927 {
10928 code = MINUS;
10929 op0 = pic_offset_table_rtx;
10930 op1 = operands[0];
10931 }
10932
10933 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10934 OPTAB_DIRECT);
10935 }
10936 else if (TARGET_X32)
10937 operands[0] = convert_memory_address (Pmode, operands[0]);
10938 })
10939
10940 (define_insn "*tablejump_1"
10941 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
10942 (use (label_ref (match_operand 1 "" "")))]
10943 ""
10944 "jmp\t%A0"
10945 [(set_attr "type" "ibr")
10946 (set_attr "length_immediate" "0")])
10947 \f
10948 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10949
10950 (define_peephole2
10951 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
10952 (set (match_operand:QI 1 "register_operand" "")
10953 (match_operator:QI 2 "ix86_comparison_operator"
10954 [(reg FLAGS_REG) (const_int 0)]))
10955 (set (match_operand 3 "q_regs_operand" "")
10956 (zero_extend (match_dup 1)))]
10957 "(peep2_reg_dead_p (3, operands[1])
10958 || operands_match_p (operands[1], operands[3]))
10959 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10960 [(set (match_dup 4) (match_dup 0))
10961 (set (strict_low_part (match_dup 5))
10962 (match_dup 2))]
10963 {
10964 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10965 operands[5] = gen_lowpart (QImode, operands[3]);
10966 ix86_expand_clear (operands[3]);
10967 })
10968
10969 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
10970
10971 (define_peephole2
10972 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
10973 (set (match_operand:QI 1 "register_operand" "")
10974 (match_operator:QI 2 "ix86_comparison_operator"
10975 [(reg FLAGS_REG) (const_int 0)]))
10976 (parallel [(set (match_operand 3 "q_regs_operand" "")
10977 (zero_extend (match_dup 1)))
10978 (clobber (reg:CC FLAGS_REG))])]
10979 "(peep2_reg_dead_p (3, operands[1])
10980 || operands_match_p (operands[1], operands[3]))
10981 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10982 [(set (match_dup 4) (match_dup 0))
10983 (set (strict_low_part (match_dup 5))
10984 (match_dup 2))]
10985 {
10986 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10987 operands[5] = gen_lowpart (QImode, operands[3]);
10988 ix86_expand_clear (operands[3]);
10989 })
10990 \f
10991 ;; Call instructions.
10992
10993 ;; The predicates normally associated with named expanders are not properly
10994 ;; checked for calls. This is a bug in the generic code, but it isn't that
10995 ;; easy to fix. Ignore it for now and be prepared to fix things up.
10996
10997 ;; P6 processors will jump to the address after the decrement when %esp
10998 ;; is used as a call operand, so they will execute return address as a code.
10999 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11000
11001 ;; Register constraint for call instruction.
11002 (define_mode_attr c [(SI "l") (DI "r")])
11003
11004 ;; Call subroutine returning no value.
11005
11006 (define_expand "call"
11007 [(call (match_operand:QI 0 "" "")
11008 (match_operand 1 "" ""))
11009 (use (match_operand 2 "" ""))]
11010 ""
11011 {
11012 ix86_expand_call (NULL, operands[0], operands[1],
11013 operands[2], NULL, false);
11014 DONE;
11015 })
11016
11017 (define_expand "sibcall"
11018 [(call (match_operand:QI 0 "" "")
11019 (match_operand 1 "" ""))
11020 (use (match_operand 2 "" ""))]
11021 ""
11022 {
11023 ix86_expand_call (NULL, operands[0], operands[1],
11024 operands[2], NULL, true);
11025 DONE;
11026 })
11027
11028 (define_insn_and_split "*call_vzeroupper"
11029 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11030 (match_operand 1 "" ""))
11031 (unspec [(match_operand 2 "const_int_operand" "")]
11032 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11033 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11034 "#"
11035 "&& reload_completed"
11036 [(const_int 0)]
11037 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11038 [(set_attr "type" "call")])
11039
11040 (define_insn "*call"
11041 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11042 (match_operand 1 "" ""))]
11043 "!SIBLING_CALL_P (insn)"
11044 "* return ix86_output_call_insn (insn, operands[0]);"
11045 [(set_attr "type" "call")])
11046
11047 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11048 [(parallel
11049 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11050 (match_operand 1 "" ""))
11051 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11052 (clobber (reg:TI XMM6_REG))
11053 (clobber (reg:TI XMM7_REG))
11054 (clobber (reg:TI XMM8_REG))
11055 (clobber (reg:TI XMM9_REG))
11056 (clobber (reg:TI XMM10_REG))
11057 (clobber (reg:TI XMM11_REG))
11058 (clobber (reg:TI XMM12_REG))
11059 (clobber (reg:TI XMM13_REG))
11060 (clobber (reg:TI XMM14_REG))
11061 (clobber (reg:TI XMM15_REG))
11062 (clobber (reg:DI SI_REG))
11063 (clobber (reg:DI DI_REG))])
11064 (unspec [(match_operand 2 "const_int_operand" "")]
11065 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11066 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11067 "#"
11068 "&& reload_completed"
11069 [(const_int 0)]
11070 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11071 [(set_attr "type" "call")])
11072
11073 (define_insn "*call_rex64_ms_sysv"
11074 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11075 (match_operand 1 "" ""))
11076 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11077 (clobber (reg:TI XMM6_REG))
11078 (clobber (reg:TI XMM7_REG))
11079 (clobber (reg:TI XMM8_REG))
11080 (clobber (reg:TI XMM9_REG))
11081 (clobber (reg:TI XMM10_REG))
11082 (clobber (reg:TI XMM11_REG))
11083 (clobber (reg:TI XMM12_REG))
11084 (clobber (reg:TI XMM13_REG))
11085 (clobber (reg:TI XMM14_REG))
11086 (clobber (reg:TI XMM15_REG))
11087 (clobber (reg:DI SI_REG))
11088 (clobber (reg:DI DI_REG))]
11089 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11090 "* return ix86_output_call_insn (insn, operands[0]);"
11091 [(set_attr "type" "call")])
11092
11093 (define_insn_and_split "*sibcall_vzeroupper"
11094 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11095 (match_operand 1 "" ""))
11096 (unspec [(match_operand 2 "const_int_operand" "")]
11097 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11098 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11099 "#"
11100 "&& reload_completed"
11101 [(const_int 0)]
11102 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11103 [(set_attr "type" "call")])
11104
11105 (define_insn "*sibcall"
11106 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11107 (match_operand 1 "" ""))]
11108 "SIBLING_CALL_P (insn)"
11109 "* return ix86_output_call_insn (insn, operands[0]);"
11110 [(set_attr "type" "call")])
11111
11112 (define_expand "call_pop"
11113 [(parallel [(call (match_operand:QI 0 "" "")
11114 (match_operand:SI 1 "" ""))
11115 (set (reg:SI SP_REG)
11116 (plus:SI (reg:SI SP_REG)
11117 (match_operand:SI 3 "" "")))])]
11118 "!TARGET_64BIT"
11119 {
11120 ix86_expand_call (NULL, operands[0], operands[1],
11121 operands[2], operands[3], false);
11122 DONE;
11123 })
11124
11125 (define_insn_and_split "*call_pop_vzeroupper"
11126 [(parallel
11127 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11128 (match_operand:SI 1 "" ""))
11129 (set (reg:SI SP_REG)
11130 (plus:SI (reg:SI SP_REG)
11131 (match_operand:SI 2 "immediate_operand" "i")))])
11132 (unspec [(match_operand 3 "const_int_operand" "")]
11133 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11134 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11135 "#"
11136 "&& reload_completed"
11137 [(const_int 0)]
11138 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11139 [(set_attr "type" "call")])
11140
11141 (define_insn "*call_pop"
11142 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11143 (match_operand 1 "" ""))
11144 (set (reg:SI SP_REG)
11145 (plus:SI (reg:SI SP_REG)
11146 (match_operand:SI 2 "immediate_operand" "i")))]
11147 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11148 "* return ix86_output_call_insn (insn, operands[0]);"
11149 [(set_attr "type" "call")])
11150
11151 (define_insn_and_split "*sibcall_pop_vzeroupper"
11152 [(parallel
11153 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11154 (match_operand 1 "" ""))
11155 (set (reg:SI SP_REG)
11156 (plus:SI (reg:SI SP_REG)
11157 (match_operand:SI 2 "immediate_operand" "i")))])
11158 (unspec [(match_operand 3 "const_int_operand" "")]
11159 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11160 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11161 "#"
11162 "&& reload_completed"
11163 [(const_int 0)]
11164 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11165 [(set_attr "type" "call")])
11166
11167 (define_insn "*sibcall_pop"
11168 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11169 (match_operand 1 "" ""))
11170 (set (reg:SI SP_REG)
11171 (plus:SI (reg:SI SP_REG)
11172 (match_operand:SI 2 "immediate_operand" "i")))]
11173 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11174 "* return ix86_output_call_insn (insn, operands[0]);"
11175 [(set_attr "type" "call")])
11176
11177 ;; Call subroutine, returning value in operand 0
11178
11179 (define_expand "call_value"
11180 [(set (match_operand 0 "" "")
11181 (call (match_operand:QI 1 "" "")
11182 (match_operand 2 "" "")))
11183 (use (match_operand 3 "" ""))]
11184 ""
11185 {
11186 ix86_expand_call (operands[0], operands[1], operands[2],
11187 operands[3], NULL, false);
11188 DONE;
11189 })
11190
11191 (define_expand "sibcall_value"
11192 [(set (match_operand 0 "" "")
11193 (call (match_operand:QI 1 "" "")
11194 (match_operand 2 "" "")))
11195 (use (match_operand 3 "" ""))]
11196 ""
11197 {
11198 ix86_expand_call (operands[0], operands[1], operands[2],
11199 operands[3], NULL, true);
11200 DONE;
11201 })
11202
11203 (define_insn_and_split "*call_value_vzeroupper"
11204 [(set (match_operand 0 "" "")
11205 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11206 (match_operand 2 "" "")))
11207 (unspec [(match_operand 3 "const_int_operand" "")]
11208 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11209 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11210 "#"
11211 "&& reload_completed"
11212 [(const_int 0)]
11213 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11214 [(set_attr "type" "callv")])
11215
11216 (define_insn "*call_value"
11217 [(set (match_operand 0 "" "")
11218 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11219 (match_operand 2 "" "")))]
11220 "!SIBLING_CALL_P (insn)"
11221 "* return ix86_output_call_insn (insn, operands[1]);"
11222 [(set_attr "type" "callv")])
11223
11224 (define_insn_and_split "*sibcall_value_vzeroupper"
11225 [(set (match_operand 0 "" "")
11226 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11227 (match_operand 2 "" "")))
11228 (unspec [(match_operand 3 "const_int_operand" "")]
11229 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11230 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11231 "#"
11232 "&& reload_completed"
11233 [(const_int 0)]
11234 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11235 [(set_attr "type" "callv")])
11236
11237 (define_insn "*sibcall_value"
11238 [(set (match_operand 0 "" "")
11239 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11240 (match_operand 2 "" "")))]
11241 "SIBLING_CALL_P (insn)"
11242 "* return ix86_output_call_insn (insn, operands[1]);"
11243 [(set_attr "type" "callv")])
11244
11245 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11246 [(parallel
11247 [(set (match_operand 0 "" "")
11248 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11249 (match_operand 2 "" "")))
11250 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11251 (clobber (reg:TI XMM6_REG))
11252 (clobber (reg:TI XMM7_REG))
11253 (clobber (reg:TI XMM8_REG))
11254 (clobber (reg:TI XMM9_REG))
11255 (clobber (reg:TI XMM10_REG))
11256 (clobber (reg:TI XMM11_REG))
11257 (clobber (reg:TI XMM12_REG))
11258 (clobber (reg:TI XMM13_REG))
11259 (clobber (reg:TI XMM14_REG))
11260 (clobber (reg:TI XMM15_REG))
11261 (clobber (reg:DI SI_REG))
11262 (clobber (reg:DI DI_REG))])
11263 (unspec [(match_operand 3 "const_int_operand" "")]
11264 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11265 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11266 "#"
11267 "&& reload_completed"
11268 [(const_int 0)]
11269 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11270 [(set_attr "type" "callv")])
11271
11272 (define_insn "*call_value_rex64_ms_sysv"
11273 [(set (match_operand 0 "" "")
11274 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11275 (match_operand 2 "" "")))
11276 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11277 (clobber (reg:TI XMM6_REG))
11278 (clobber (reg:TI XMM7_REG))
11279 (clobber (reg:TI XMM8_REG))
11280 (clobber (reg:TI XMM9_REG))
11281 (clobber (reg:TI XMM10_REG))
11282 (clobber (reg:TI XMM11_REG))
11283 (clobber (reg:TI XMM12_REG))
11284 (clobber (reg:TI XMM13_REG))
11285 (clobber (reg:TI XMM14_REG))
11286 (clobber (reg:TI XMM15_REG))
11287 (clobber (reg:DI SI_REG))
11288 (clobber (reg:DI DI_REG))]
11289 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11290 "* return ix86_output_call_insn (insn, operands[1]);"
11291 [(set_attr "type" "callv")])
11292
11293 (define_expand "call_value_pop"
11294 [(parallel [(set (match_operand 0 "" "")
11295 (call (match_operand:QI 1 "" "")
11296 (match_operand:SI 2 "" "")))
11297 (set (reg:SI SP_REG)
11298 (plus:SI (reg:SI SP_REG)
11299 (match_operand:SI 4 "" "")))])]
11300 "!TARGET_64BIT"
11301 {
11302 ix86_expand_call (operands[0], operands[1], operands[2],
11303 operands[3], operands[4], false);
11304 DONE;
11305 })
11306
11307 (define_insn_and_split "*call_value_pop_vzeroupper"
11308 [(parallel
11309 [(set (match_operand 0 "" "")
11310 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11311 (match_operand 2 "" "")))
11312 (set (reg:SI SP_REG)
11313 (plus:SI (reg:SI SP_REG)
11314 (match_operand:SI 3 "immediate_operand" "i")))])
11315 (unspec [(match_operand 4 "const_int_operand" "")]
11316 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11317 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11318 "#"
11319 "&& reload_completed"
11320 [(const_int 0)]
11321 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11322 [(set_attr "type" "callv")])
11323
11324 (define_insn "*call_value_pop"
11325 [(set (match_operand 0 "" "")
11326 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11327 (match_operand 2 "" "")))
11328 (set (reg:SI SP_REG)
11329 (plus:SI (reg:SI SP_REG)
11330 (match_operand:SI 3 "immediate_operand" "i")))]
11331 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11332 "* return ix86_output_call_insn (insn, operands[1]);"
11333 [(set_attr "type" "callv")])
11334
11335 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11336 [(parallel
11337 [(set (match_operand 0 "" "")
11338 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11339 (match_operand 2 "" "")))
11340 (set (reg:SI SP_REG)
11341 (plus:SI (reg:SI SP_REG)
11342 (match_operand:SI 3 "immediate_operand" "i")))])
11343 (unspec [(match_operand 4 "const_int_operand" "")]
11344 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11345 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11346 "#"
11347 "&& reload_completed"
11348 [(const_int 0)]
11349 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11350 [(set_attr "type" "callv")])
11351
11352 (define_insn "*sibcall_value_pop"
11353 [(set (match_operand 0 "" "")
11354 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11355 (match_operand 2 "" "")))
11356 (set (reg:SI SP_REG)
11357 (plus:SI (reg:SI SP_REG)
11358 (match_operand:SI 3 "immediate_operand" "i")))]
11359 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11360 "* return ix86_output_call_insn (insn, operands[1]);"
11361 [(set_attr "type" "callv")])
11362
11363 ;; Call subroutine returning any type.
11364
11365 (define_expand "untyped_call"
11366 [(parallel [(call (match_operand 0 "" "")
11367 (const_int 0))
11368 (match_operand 1 "" "")
11369 (match_operand 2 "" "")])]
11370 ""
11371 {
11372 int i;
11373
11374 /* In order to give reg-stack an easier job in validating two
11375 coprocessor registers as containing a possible return value,
11376 simply pretend the untyped call returns a complex long double
11377 value.
11378
11379 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11380 and should have the default ABI. */
11381
11382 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11383 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11384 operands[0], const0_rtx,
11385 GEN_INT ((TARGET_64BIT
11386 ? (ix86_abi == SYSV_ABI
11387 ? X86_64_SSE_REGPARM_MAX
11388 : X86_64_MS_SSE_REGPARM_MAX)
11389 : X86_32_SSE_REGPARM_MAX)
11390 - 1),
11391 NULL, false);
11392
11393 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11394 {
11395 rtx set = XVECEXP (operands[2], 0, i);
11396 emit_move_insn (SET_DEST (set), SET_SRC (set));
11397 }
11398
11399 /* The optimizer does not know that the call sets the function value
11400 registers we stored in the result block. We avoid problems by
11401 claiming that all hard registers are used and clobbered at this
11402 point. */
11403 emit_insn (gen_blockage ());
11404
11405 DONE;
11406 })
11407 \f
11408 ;; Prologue and epilogue instructions
11409
11410 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11411 ;; all of memory. This blocks insns from being moved across this point.
11412
11413 (define_insn "blockage"
11414 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11415 ""
11416 ""
11417 [(set_attr "length" "0")])
11418
11419 ;; Do not schedule instructions accessing memory across this point.
11420
11421 (define_expand "memory_blockage"
11422 [(set (match_dup 0)
11423 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11424 ""
11425 {
11426 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11427 MEM_VOLATILE_P (operands[0]) = 1;
11428 })
11429
11430 (define_insn "*memory_blockage"
11431 [(set (match_operand:BLK 0 "" "")
11432 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11433 ""
11434 ""
11435 [(set_attr "length" "0")])
11436
11437 ;; As USE insns aren't meaningful after reload, this is used instead
11438 ;; to prevent deleting instructions setting registers for PIC code
11439 (define_insn "prologue_use"
11440 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11441 ""
11442 ""
11443 [(set_attr "length" "0")])
11444
11445 ;; Insn emitted into the body of a function to return from a function.
11446 ;; This is only done if the function's epilogue is known to be simple.
11447 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11448
11449 (define_expand "return"
11450 [(return)]
11451 "ix86_can_use_return_insn_p ()"
11452 {
11453 if (crtl->args.pops_args)
11454 {
11455 rtx popc = GEN_INT (crtl->args.pops_args);
11456 emit_jump_insn (gen_return_pop_internal (popc));
11457 DONE;
11458 }
11459 })
11460
11461 (define_insn "return_internal"
11462 [(return)]
11463 "reload_completed"
11464 "ret"
11465 [(set_attr "length" "1")
11466 (set_attr "atom_unit" "jeu")
11467 (set_attr "length_immediate" "0")
11468 (set_attr "modrm" "0")])
11469
11470 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11471 ;; instruction Athlon and K8 have.
11472
11473 (define_insn "return_internal_long"
11474 [(return)
11475 (unspec [(const_int 0)] UNSPEC_REP)]
11476 "reload_completed"
11477 "rep\;ret"
11478 [(set_attr "length" "2")
11479 (set_attr "atom_unit" "jeu")
11480 (set_attr "length_immediate" "0")
11481 (set_attr "prefix_rep" "1")
11482 (set_attr "modrm" "0")])
11483
11484 (define_insn "return_pop_internal"
11485 [(return)
11486 (use (match_operand:SI 0 "const_int_operand" ""))]
11487 "reload_completed"
11488 "ret\t%0"
11489 [(set_attr "length" "3")
11490 (set_attr "atom_unit" "jeu")
11491 (set_attr "length_immediate" "2")
11492 (set_attr "modrm" "0")])
11493
11494 (define_insn "return_indirect_internal"
11495 [(return)
11496 (use (match_operand:SI 0 "register_operand" "r"))]
11497 "reload_completed"
11498 "jmp\t%A0"
11499 [(set_attr "type" "ibr")
11500 (set_attr "length_immediate" "0")])
11501
11502 (define_insn "nop"
11503 [(const_int 0)]
11504 ""
11505 "nop"
11506 [(set_attr "length" "1")
11507 (set_attr "length_immediate" "0")
11508 (set_attr "modrm" "0")])
11509
11510 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11511 (define_insn "nops"
11512 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11513 UNSPECV_NOPS)]
11514 "reload_completed"
11515 {
11516 int num = INTVAL (operands[0]);
11517
11518 gcc_assert (num >= 1 && num <= 8);
11519
11520 while (num--)
11521 fputs ("\tnop\n", asm_out_file);
11522
11523 return "";
11524 }
11525 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11526 (set_attr "length_immediate" "0")
11527 (set_attr "modrm" "0")])
11528
11529 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11530 ;; branch prediction penalty for the third jump in a 16-byte
11531 ;; block on K8.
11532
11533 (define_insn "pad"
11534 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11535 ""
11536 {
11537 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11538 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11539 #else
11540 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11541 The align insn is used to avoid 3 jump instructions in the row to improve
11542 branch prediction and the benefits hardly outweigh the cost of extra 8
11543 nops on the average inserted by full alignment pseudo operation. */
11544 #endif
11545 return "";
11546 }
11547 [(set_attr "length" "16")])
11548
11549 (define_expand "prologue"
11550 [(const_int 0)]
11551 ""
11552 "ix86_expand_prologue (); DONE;")
11553
11554 (define_insn "set_got"
11555 [(set (match_operand:SI 0 "register_operand" "=r")
11556 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11557 (clobber (reg:CC FLAGS_REG))]
11558 "!TARGET_64BIT"
11559 "* return output_set_got (operands[0], NULL_RTX);"
11560 [(set_attr "type" "multi")
11561 (set_attr "length" "12")])
11562
11563 (define_insn "set_got_labelled"
11564 [(set (match_operand:SI 0 "register_operand" "=r")
11565 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11566 UNSPEC_SET_GOT))
11567 (clobber (reg:CC FLAGS_REG))]
11568 "!TARGET_64BIT"
11569 "* return output_set_got (operands[0], operands[1]);"
11570 [(set_attr "type" "multi")
11571 (set_attr "length" "12")])
11572
11573 (define_insn "set_got_rex64"
11574 [(set (match_operand:DI 0 "register_operand" "=r")
11575 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11576 "TARGET_64BIT"
11577 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11578 [(set_attr "type" "lea")
11579 (set_attr "length_address" "4")
11580 (set_attr "mode" "DI")])
11581
11582 (define_insn "set_rip_rex64"
11583 [(set (match_operand:DI 0 "register_operand" "=r")
11584 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11585 "TARGET_64BIT"
11586 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11587 [(set_attr "type" "lea")
11588 (set_attr "length_address" "4")
11589 (set_attr "mode" "DI")])
11590
11591 (define_insn "set_got_offset_rex64"
11592 [(set (match_operand:DI 0 "register_operand" "=r")
11593 (unspec:DI
11594 [(label_ref (match_operand 1 "" ""))]
11595 UNSPEC_SET_GOT_OFFSET))]
11596 "TARGET_LP64"
11597 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11598 [(set_attr "type" "imov")
11599 (set_attr "length_immediate" "0")
11600 (set_attr "length_address" "8")
11601 (set_attr "mode" "DI")])
11602
11603 (define_expand "epilogue"
11604 [(const_int 0)]
11605 ""
11606 "ix86_expand_epilogue (1); DONE;")
11607
11608 (define_expand "sibcall_epilogue"
11609 [(const_int 0)]
11610 ""
11611 "ix86_expand_epilogue (0); DONE;")
11612
11613 (define_expand "eh_return"
11614 [(use (match_operand 0 "register_operand" ""))]
11615 ""
11616 {
11617 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11618
11619 /* Tricky bit: we write the address of the handler to which we will
11620 be returning into someone else's stack frame, one word below the
11621 stack address we wish to restore. */
11622 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11623 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11624 tmp = gen_rtx_MEM (Pmode, tmp);
11625 emit_move_insn (tmp, ra);
11626
11627 emit_jump_insn (gen_eh_return_internal ());
11628 emit_barrier ();
11629 DONE;
11630 })
11631
11632 (define_insn_and_split "eh_return_internal"
11633 [(eh_return)]
11634 ""
11635 "#"
11636 "epilogue_completed"
11637 [(const_int 0)]
11638 "ix86_expand_epilogue (2); DONE;")
11639
11640 (define_insn "leave"
11641 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11642 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11643 (clobber (mem:BLK (scratch)))]
11644 "!TARGET_64BIT"
11645 "leave"
11646 [(set_attr "type" "leave")])
11647
11648 (define_insn "leave_rex64"
11649 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11650 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11651 (clobber (mem:BLK (scratch)))]
11652 "TARGET_64BIT"
11653 "leave"
11654 [(set_attr "type" "leave")])
11655 \f
11656 ;; Handle -fsplit-stack.
11657
11658 (define_expand "split_stack_prologue"
11659 [(const_int 0)]
11660 ""
11661 {
11662 ix86_expand_split_stack_prologue ();
11663 DONE;
11664 })
11665
11666 ;; In order to support the call/return predictor, we use a return
11667 ;; instruction which the middle-end doesn't see.
11668 (define_insn "split_stack_return"
11669 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11670 UNSPECV_SPLIT_STACK_RETURN)]
11671 ""
11672 {
11673 if (operands[0] == const0_rtx)
11674 return "ret";
11675 else
11676 return "ret\t%0";
11677 }
11678 [(set_attr "atom_unit" "jeu")
11679 (set_attr "modrm" "0")
11680 (set (attr "length")
11681 (if_then_else (match_operand:SI 0 "const0_operand" "")
11682 (const_int 1)
11683 (const_int 3)))
11684 (set (attr "length_immediate")
11685 (if_then_else (match_operand:SI 0 "const0_operand" "")
11686 (const_int 0)
11687 (const_int 2)))])
11688
11689 ;; If there are operand 0 bytes available on the stack, jump to
11690 ;; operand 1.
11691
11692 (define_expand "split_stack_space_check"
11693 [(set (pc) (if_then_else
11694 (ltu (minus (reg SP_REG)
11695 (match_operand 0 "register_operand" ""))
11696 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11697 (label_ref (match_operand 1 "" ""))
11698 (pc)))]
11699 ""
11700 {
11701 rtx reg, size, limit;
11702
11703 reg = gen_reg_rtx (Pmode);
11704 size = force_reg (Pmode, operands[0]);
11705 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11706 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11707 UNSPEC_STACK_CHECK);
11708 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11709 ix86_expand_branch (GEU, reg, limit, operands[1]);
11710
11711 DONE;
11712 })
11713 \f
11714 ;; Bit manipulation instructions.
11715
11716 (define_expand "ffs<mode>2"
11717 [(set (match_dup 2) (const_int -1))
11718 (parallel [(set (reg:CCZ FLAGS_REG)
11719 (compare:CCZ
11720 (match_operand:SWI48 1 "nonimmediate_operand" "")
11721 (const_int 0)))
11722 (set (match_operand:SWI48 0 "register_operand" "")
11723 (ctz:SWI48 (match_dup 1)))])
11724 (set (match_dup 0) (if_then_else:SWI48
11725 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11726 (match_dup 2)
11727 (match_dup 0)))
11728 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11729 (clobber (reg:CC FLAGS_REG))])]
11730 ""
11731 {
11732 if (<MODE>mode == SImode && !TARGET_CMOVE)
11733 {
11734 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11735 DONE;
11736 }
11737 operands[2] = gen_reg_rtx (<MODE>mode);
11738 })
11739
11740 (define_insn_and_split "ffssi2_no_cmove"
11741 [(set (match_operand:SI 0 "register_operand" "=r")
11742 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11743 (clobber (match_scratch:SI 2 "=&q"))
11744 (clobber (reg:CC FLAGS_REG))]
11745 "!TARGET_CMOVE"
11746 "#"
11747 "&& reload_completed"
11748 [(parallel [(set (reg:CCZ FLAGS_REG)
11749 (compare:CCZ (match_dup 1) (const_int 0)))
11750 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11751 (set (strict_low_part (match_dup 3))
11752 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11753 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11754 (clobber (reg:CC FLAGS_REG))])
11755 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11756 (clobber (reg:CC FLAGS_REG))])
11757 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11758 (clobber (reg:CC FLAGS_REG))])]
11759 {
11760 operands[3] = gen_lowpart (QImode, operands[2]);
11761 ix86_expand_clear (operands[2]);
11762 })
11763
11764 (define_insn "*ffs<mode>_1"
11765 [(set (reg:CCZ FLAGS_REG)
11766 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11767 (const_int 0)))
11768 (set (match_operand:SWI48 0 "register_operand" "=r")
11769 (ctz:SWI48 (match_dup 1)))]
11770 ""
11771 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11772 [(set_attr "type" "alu1")
11773 (set_attr "prefix_0f" "1")
11774 (set_attr "mode" "<MODE>")])
11775
11776 (define_insn "ctz<mode>2"
11777 [(set (match_operand:SWI248 0 "register_operand" "=r")
11778 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11779 (clobber (reg:CC FLAGS_REG))]
11780 ""
11781 {
11782 if (TARGET_BMI)
11783 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11784 else
11785 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11786 }
11787 [(set_attr "type" "alu1")
11788 (set_attr "prefix_0f" "1")
11789 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11790 (set_attr "mode" "<MODE>")])
11791
11792 (define_expand "clz<mode>2"
11793 [(parallel
11794 [(set (match_operand:SWI248 0 "register_operand" "")
11795 (minus:SWI248
11796 (match_dup 2)
11797 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11798 (clobber (reg:CC FLAGS_REG))])
11799 (parallel
11800 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11801 (clobber (reg:CC FLAGS_REG))])]
11802 ""
11803 {
11804 if (TARGET_ABM)
11805 {
11806 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11807 DONE;
11808 }
11809 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11810 })
11811
11812 (define_insn "clz<mode>2_abm"
11813 [(set (match_operand:SWI248 0 "register_operand" "=r")
11814 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11815 (clobber (reg:CC FLAGS_REG))]
11816 "TARGET_ABM || TARGET_BMI"
11817 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11818 [(set_attr "prefix_rep" "1")
11819 (set_attr "type" "bitmanip")
11820 (set_attr "mode" "<MODE>")])
11821
11822 ;; BMI instructions.
11823 (define_insn "*bmi_andn_<mode>"
11824 [(set (match_operand:SWI48 0 "register_operand" "=r")
11825 (and:SWI48
11826 (not:SWI48
11827 (match_operand:SWI48 1 "register_operand" "r"))
11828 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11829 (clobber (reg:CC FLAGS_REG))]
11830 "TARGET_BMI"
11831 "andn\t{%2, %1, %0|%0, %1, %2}"
11832 [(set_attr "type" "bitmanip")
11833 (set_attr "mode" "<MODE>")])
11834
11835 (define_insn "bmi_bextr_<mode>"
11836 [(set (match_operand:SWI48 0 "register_operand" "=r")
11837 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11838 (match_operand:SWI48 2 "register_operand" "r")]
11839 UNSPEC_BEXTR))
11840 (clobber (reg:CC FLAGS_REG))]
11841 "TARGET_BMI"
11842 "bextr\t{%2, %1, %0|%0, %1, %2}"
11843 [(set_attr "type" "bitmanip")
11844 (set_attr "mode" "<MODE>")])
11845
11846 (define_insn "*bmi_blsi_<mode>"
11847 [(set (match_operand:SWI48 0 "register_operand" "=r")
11848 (and:SWI48
11849 (neg:SWI48
11850 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11851 (match_dup 1)))
11852 (clobber (reg:CC FLAGS_REG))]
11853 "TARGET_BMI"
11854 "blsi\t{%1, %0|%0, %1}"
11855 [(set_attr "type" "bitmanip")
11856 (set_attr "mode" "<MODE>")])
11857
11858 (define_insn "*bmi_blsmsk_<mode>"
11859 [(set (match_operand:SWI48 0 "register_operand" "=r")
11860 (xor:SWI48
11861 (plus:SWI48
11862 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11863 (const_int -1))
11864 (match_dup 1)))
11865 (clobber (reg:CC FLAGS_REG))]
11866 "TARGET_BMI"
11867 "blsmsk\t{%1, %0|%0, %1}"
11868 [(set_attr "type" "bitmanip")
11869 (set_attr "mode" "<MODE>")])
11870
11871 (define_insn "*bmi_blsr_<mode>"
11872 [(set (match_operand:SWI48 0 "register_operand" "=r")
11873 (and:SWI48
11874 (plus:SWI48
11875 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11876 (const_int -1))
11877 (match_dup 1)))
11878 (clobber (reg:CC FLAGS_REG))]
11879 "TARGET_BMI"
11880 "blsr\t{%1, %0|%0, %1}"
11881 [(set_attr "type" "bitmanip")
11882 (set_attr "mode" "<MODE>")])
11883
11884 ;; TBM instructions.
11885 (define_insn "tbm_bextri_<mode>"
11886 [(set (match_operand:SWI48 0 "register_operand" "=r")
11887 (zero_extract:SWI48
11888 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11889 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11890 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11891 (clobber (reg:CC FLAGS_REG))]
11892 "TARGET_TBM"
11893 {
11894 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11895 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11896 }
11897 [(set_attr "type" "bitmanip")
11898 (set_attr "mode" "<MODE>")])
11899
11900 (define_insn "*tbm_blcfill_<mode>"
11901 [(set (match_operand:SWI48 0 "register_operand" "=r")
11902 (and:SWI48
11903 (plus:SWI48
11904 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11905 (const_int 1))
11906 (match_dup 1)))
11907 (clobber (reg:CC FLAGS_REG))]
11908 "TARGET_TBM"
11909 "blcfill\t{%1, %0|%0, %1}"
11910 [(set_attr "type" "bitmanip")
11911 (set_attr "mode" "<MODE>")])
11912
11913 (define_insn "*tbm_blci_<mode>"
11914 [(set (match_operand:SWI48 0 "register_operand" "=r")
11915 (ior:SWI48
11916 (not:SWI48
11917 (plus:SWI48
11918 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11919 (const_int 1)))
11920 (match_dup 1)))
11921 (clobber (reg:CC FLAGS_REG))]
11922 "TARGET_TBM"
11923 "blci\t{%1, %0|%0, %1}"
11924 [(set_attr "type" "bitmanip")
11925 (set_attr "mode" "<MODE>")])
11926
11927 (define_insn "*tbm_blcic_<mode>"
11928 [(set (match_operand:SWI48 0 "register_operand" "=r")
11929 (and:SWI48
11930 (plus:SWI48
11931 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11932 (const_int 1))
11933 (not:SWI48
11934 (match_dup 1))))
11935 (clobber (reg:CC FLAGS_REG))]
11936 "TARGET_TBM"
11937 "blcic\t{%1, %0|%0, %1}"
11938 [(set_attr "type" "bitmanip")
11939 (set_attr "mode" "<MODE>")])
11940
11941 (define_insn "*tbm_blcmsk_<mode>"
11942 [(set (match_operand:SWI48 0 "register_operand" "=r")
11943 (xor:SWI48
11944 (plus:SWI48
11945 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11946 (const_int 1))
11947 (match_dup 1)))
11948 (clobber (reg:CC FLAGS_REG))]
11949 "TARGET_TBM"
11950 "blcmsk\t{%1, %0|%0, %1}"
11951 [(set_attr "type" "bitmanip")
11952 (set_attr "mode" "<MODE>")])
11953
11954 (define_insn "*tbm_blcs_<mode>"
11955 [(set (match_operand:SWI48 0 "register_operand" "=r")
11956 (ior:SWI48
11957 (plus:SWI48
11958 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11959 (const_int 1))
11960 (match_dup 1)))
11961 (clobber (reg:CC FLAGS_REG))]
11962 "TARGET_TBM"
11963 "blcs\t{%1, %0|%0, %1}"
11964 [(set_attr "type" "bitmanip")
11965 (set_attr "mode" "<MODE>")])
11966
11967 (define_insn "*tbm_blsfill_<mode>"
11968 [(set (match_operand:SWI48 0 "register_operand" "=r")
11969 (ior:SWI48
11970 (plus:SWI48
11971 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11972 (const_int -1))
11973 (match_dup 1)))
11974 (clobber (reg:CC FLAGS_REG))]
11975 "TARGET_TBM"
11976 "blsfill\t{%1, %0|%0, %1}"
11977 [(set_attr "type" "bitmanip")
11978 (set_attr "mode" "<MODE>")])
11979
11980 (define_insn "*tbm_blsic_<mode>"
11981 [(set (match_operand:SWI48 0 "register_operand" "=r")
11982 (ior:SWI48
11983 (plus:SWI48
11984 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11985 (const_int -1))
11986 (not:SWI48
11987 (match_dup 1))))
11988 (clobber (reg:CC FLAGS_REG))]
11989 "TARGET_TBM"
11990 "blsic\t{%1, %0|%0, %1}"
11991 [(set_attr "type" "bitmanip")
11992 (set_attr "mode" "<MODE>")])
11993
11994 (define_insn "*tbm_t1mskc_<mode>"
11995 [(set (match_operand:SWI48 0 "register_operand" "=r")
11996 (ior:SWI48
11997 (plus:SWI48
11998 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11999 (const_int 1))
12000 (not:SWI48
12001 (match_dup 1))))
12002 (clobber (reg:CC FLAGS_REG))]
12003 "TARGET_TBM"
12004 "t1mskc\t{%1, %0|%0, %1}"
12005 [(set_attr "type" "bitmanip")
12006 (set_attr "mode" "<MODE>")])
12007
12008 (define_insn "*tbm_tzmsk_<mode>"
12009 [(set (match_operand:SWI48 0 "register_operand" "=r")
12010 (and:SWI48
12011 (plus:SWI48
12012 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12013 (const_int -1))
12014 (not:SWI48
12015 (match_dup 1))))
12016 (clobber (reg:CC FLAGS_REG))]
12017 "TARGET_TBM"
12018 "tzmsk\t{%1, %0|%0, %1}"
12019 [(set_attr "type" "bitmanip")
12020 (set_attr "mode" "<MODE>")])
12021
12022 (define_insn "bsr_rex64"
12023 [(set (match_operand:DI 0 "register_operand" "=r")
12024 (minus:DI (const_int 63)
12025 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12026 (clobber (reg:CC FLAGS_REG))]
12027 "TARGET_64BIT"
12028 "bsr{q}\t{%1, %0|%0, %1}"
12029 [(set_attr "type" "alu1")
12030 (set_attr "prefix_0f" "1")
12031 (set_attr "mode" "DI")])
12032
12033 (define_insn "bsr"
12034 [(set (match_operand:SI 0 "register_operand" "=r")
12035 (minus:SI (const_int 31)
12036 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12037 (clobber (reg:CC FLAGS_REG))]
12038 ""
12039 "bsr{l}\t{%1, %0|%0, %1}"
12040 [(set_attr "type" "alu1")
12041 (set_attr "prefix_0f" "1")
12042 (set_attr "mode" "SI")])
12043
12044 (define_insn "*bsrhi"
12045 [(set (match_operand:HI 0 "register_operand" "=r")
12046 (minus:HI (const_int 15)
12047 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12048 (clobber (reg:CC FLAGS_REG))]
12049 ""
12050 "bsr{w}\t{%1, %0|%0, %1}"
12051 [(set_attr "type" "alu1")
12052 (set_attr "prefix_0f" "1")
12053 (set_attr "mode" "HI")])
12054
12055 (define_insn "popcount<mode>2"
12056 [(set (match_operand:SWI248 0 "register_operand" "=r")
12057 (popcount:SWI248
12058 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12059 (clobber (reg:CC FLAGS_REG))]
12060 "TARGET_POPCNT"
12061 {
12062 #if TARGET_MACHO
12063 return "popcnt\t{%1, %0|%0, %1}";
12064 #else
12065 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12066 #endif
12067 }
12068 [(set_attr "prefix_rep" "1")
12069 (set_attr "type" "bitmanip")
12070 (set_attr "mode" "<MODE>")])
12071
12072 (define_insn "*popcount<mode>2_cmp"
12073 [(set (reg FLAGS_REG)
12074 (compare
12075 (popcount:SWI248
12076 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12077 (const_int 0)))
12078 (set (match_operand:SWI248 0 "register_operand" "=r")
12079 (popcount:SWI248 (match_dup 1)))]
12080 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12081 {
12082 #if TARGET_MACHO
12083 return "popcnt\t{%1, %0|%0, %1}";
12084 #else
12085 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12086 #endif
12087 }
12088 [(set_attr "prefix_rep" "1")
12089 (set_attr "type" "bitmanip")
12090 (set_attr "mode" "<MODE>")])
12091
12092 (define_insn "*popcountsi2_cmp_zext"
12093 [(set (reg FLAGS_REG)
12094 (compare
12095 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12096 (const_int 0)))
12097 (set (match_operand:DI 0 "register_operand" "=r")
12098 (zero_extend:DI(popcount:SI (match_dup 1))))]
12099 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12100 {
12101 #if TARGET_MACHO
12102 return "popcnt\t{%1, %0|%0, %1}";
12103 #else
12104 return "popcnt{l}\t{%1, %0|%0, %1}";
12105 #endif
12106 }
12107 [(set_attr "prefix_rep" "1")
12108 (set_attr "type" "bitmanip")
12109 (set_attr "mode" "SI")])
12110
12111 (define_expand "bswap<mode>2"
12112 [(set (match_operand:SWI48 0 "register_operand" "")
12113 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12114 ""
12115 {
12116 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12117 {
12118 rtx x = operands[0];
12119
12120 emit_move_insn (x, operands[1]);
12121 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12122 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12123 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12124 DONE;
12125 }
12126 })
12127
12128 (define_insn "*bswap<mode>2_movbe"
12129 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12130 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12131 "TARGET_MOVBE
12132 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12133 "@
12134 bswap\t%0
12135 movbe\t{%1, %0|%0, %1}
12136 movbe\t{%1, %0|%0, %1}"
12137 [(set_attr "type" "bitmanip,imov,imov")
12138 (set_attr "modrm" "0,1,1")
12139 (set_attr "prefix_0f" "*,1,1")
12140 (set_attr "prefix_extra" "*,1,1")
12141 (set_attr "mode" "<MODE>")])
12142
12143 (define_insn "*bswap<mode>2_1"
12144 [(set (match_operand:SWI48 0 "register_operand" "=r")
12145 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12146 "TARGET_BSWAP"
12147 "bswap\t%0"
12148 [(set_attr "type" "bitmanip")
12149 (set_attr "modrm" "0")
12150 (set_attr "mode" "<MODE>")])
12151
12152 (define_insn "*bswaphi_lowpart_1"
12153 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12154 (bswap:HI (match_dup 0)))
12155 (clobber (reg:CC FLAGS_REG))]
12156 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12157 "@
12158 xchg{b}\t{%h0, %b0|%b0, %h0}
12159 rol{w}\t{$8, %0|%0, 8}"
12160 [(set_attr "length" "2,4")
12161 (set_attr "mode" "QI,HI")])
12162
12163 (define_insn "bswaphi_lowpart"
12164 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12165 (bswap:HI (match_dup 0)))
12166 (clobber (reg:CC FLAGS_REG))]
12167 ""
12168 "rol{w}\t{$8, %0|%0, 8}"
12169 [(set_attr "length" "4")
12170 (set_attr "mode" "HI")])
12171
12172 (define_expand "paritydi2"
12173 [(set (match_operand:DI 0 "register_operand" "")
12174 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12175 "! TARGET_POPCNT"
12176 {
12177 rtx scratch = gen_reg_rtx (QImode);
12178 rtx cond;
12179
12180 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12181 NULL_RTX, operands[1]));
12182
12183 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12184 gen_rtx_REG (CCmode, FLAGS_REG),
12185 const0_rtx);
12186 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12187
12188 if (TARGET_64BIT)
12189 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12190 else
12191 {
12192 rtx tmp = gen_reg_rtx (SImode);
12193
12194 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12195 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12196 }
12197 DONE;
12198 })
12199
12200 (define_expand "paritysi2"
12201 [(set (match_operand:SI 0 "register_operand" "")
12202 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12203 "! TARGET_POPCNT"
12204 {
12205 rtx scratch = gen_reg_rtx (QImode);
12206 rtx cond;
12207
12208 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12209
12210 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12211 gen_rtx_REG (CCmode, FLAGS_REG),
12212 const0_rtx);
12213 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12214
12215 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12216 DONE;
12217 })
12218
12219 (define_insn_and_split "paritydi2_cmp"
12220 [(set (reg:CC FLAGS_REG)
12221 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12222 UNSPEC_PARITY))
12223 (clobber (match_scratch:DI 0 "=r"))
12224 (clobber (match_scratch:SI 1 "=&r"))
12225 (clobber (match_scratch:HI 2 "=Q"))]
12226 "! TARGET_POPCNT"
12227 "#"
12228 "&& reload_completed"
12229 [(parallel
12230 [(set (match_dup 1)
12231 (xor:SI (match_dup 1) (match_dup 4)))
12232 (clobber (reg:CC FLAGS_REG))])
12233 (parallel
12234 [(set (reg:CC FLAGS_REG)
12235 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12236 (clobber (match_dup 1))
12237 (clobber (match_dup 2))])]
12238 {
12239 operands[4] = gen_lowpart (SImode, operands[3]);
12240
12241 if (TARGET_64BIT)
12242 {
12243 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12244 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12245 }
12246 else
12247 operands[1] = gen_highpart (SImode, operands[3]);
12248 })
12249
12250 (define_insn_and_split "paritysi2_cmp"
12251 [(set (reg:CC FLAGS_REG)
12252 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12253 UNSPEC_PARITY))
12254 (clobber (match_scratch:SI 0 "=r"))
12255 (clobber (match_scratch:HI 1 "=&Q"))]
12256 "! TARGET_POPCNT"
12257 "#"
12258 "&& reload_completed"
12259 [(parallel
12260 [(set (match_dup 1)
12261 (xor:HI (match_dup 1) (match_dup 3)))
12262 (clobber (reg:CC FLAGS_REG))])
12263 (parallel
12264 [(set (reg:CC FLAGS_REG)
12265 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12266 (clobber (match_dup 1))])]
12267 {
12268 operands[3] = gen_lowpart (HImode, operands[2]);
12269
12270 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12271 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12272 })
12273
12274 (define_insn "*parityhi2_cmp"
12275 [(set (reg:CC FLAGS_REG)
12276 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12277 UNSPEC_PARITY))
12278 (clobber (match_scratch:HI 0 "=Q"))]
12279 "! TARGET_POPCNT"
12280 "xor{b}\t{%h0, %b0|%b0, %h0}"
12281 [(set_attr "length" "2")
12282 (set_attr "mode" "HI")])
12283 \f
12284 ;; Thread-local storage patterns for ELF.
12285 ;;
12286 ;; Note that these code sequences must appear exactly as shown
12287 ;; in order to allow linker relaxation.
12288
12289 (define_insn "*tls_global_dynamic_32_gnu"
12290 [(set (match_operand:SI 0 "register_operand" "=a")
12291 (unspec:SI
12292 [(match_operand:SI 1 "register_operand" "b")
12293 (match_operand:SI 2 "tls_symbolic_operand" "")
12294 (match_operand:SI 3 "constant_call_address_operand" "z")]
12295 UNSPEC_TLS_GD))
12296 (clobber (match_scratch:SI 4 "=d"))
12297 (clobber (match_scratch:SI 5 "=c"))
12298 (clobber (reg:CC FLAGS_REG))]
12299 "!TARGET_64BIT && TARGET_GNU_TLS"
12300 {
12301 output_asm_insn
12302 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12303 if (TARGET_SUN_TLS)
12304 #ifdef HAVE_AS_IX86_TLSGDPLT
12305 return "call\t%a2@tlsgdplt";
12306 #else
12307 return "call\t%p3@plt";
12308 #endif
12309 return "call\t%P3";
12310 }
12311 [(set_attr "type" "multi")
12312 (set_attr "length" "12")])
12313
12314 (define_expand "tls_global_dynamic_32"
12315 [(parallel
12316 [(set (match_operand:SI 0 "register_operand" "")
12317 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12318 (match_operand:SI 1 "tls_symbolic_operand" "")
12319 (match_operand:SI 3 "constant_call_address_operand" "")]
12320 UNSPEC_TLS_GD))
12321 (clobber (match_scratch:SI 4 ""))
12322 (clobber (match_scratch:SI 5 ""))
12323 (clobber (reg:CC FLAGS_REG))])])
12324
12325 (define_insn "*tls_global_dynamic_64"
12326 [(set (match_operand:DI 0 "register_operand" "=a")
12327 (call:DI
12328 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12329 (match_operand:DI 3 "" "")))
12330 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12331 UNSPEC_TLS_GD)]
12332 "TARGET_64BIT"
12333 {
12334 fputs (ASM_BYTE "0x66\n", asm_out_file);
12335 output_asm_insn
12336 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12337 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12338 fputs ("\trex64\n", asm_out_file);
12339 if (TARGET_SUN_TLS)
12340 return "call\t%p2@plt";
12341 return "call\t%P2";
12342 }
12343 [(set_attr "type" "multi")
12344 (set_attr "length" "16")])
12345
12346 (define_expand "tls_global_dynamic_64"
12347 [(parallel
12348 [(set (match_operand:DI 0 "register_operand" "")
12349 (call:DI
12350 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12351 (const_int 0)))
12352 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12353 UNSPEC_TLS_GD)])])
12354
12355 (define_insn "*tls_local_dynamic_base_32_gnu"
12356 [(set (match_operand:SI 0 "register_operand" "=a")
12357 (unspec:SI
12358 [(match_operand:SI 1 "register_operand" "b")
12359 (match_operand:SI 2 "constant_call_address_operand" "z")]
12360 UNSPEC_TLS_LD_BASE))
12361 (clobber (match_scratch:SI 3 "=d"))
12362 (clobber (match_scratch:SI 4 "=c"))
12363 (clobber (reg:CC FLAGS_REG))]
12364 "!TARGET_64BIT && TARGET_GNU_TLS"
12365 {
12366 output_asm_insn
12367 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12368 if (TARGET_SUN_TLS)
12369 #ifdef HAVE_AS_IX86_TLSLDMPLT
12370 return "call\t%&@tlsldmplt";
12371 #else
12372 return "call\t%p2@plt";
12373 #endif
12374 return "call\t%P2";
12375 }
12376 [(set_attr "type" "multi")
12377 (set_attr "length" "11")])
12378
12379 (define_expand "tls_local_dynamic_base_32"
12380 [(parallel
12381 [(set (match_operand:SI 0 "register_operand" "")
12382 (unspec:SI
12383 [(match_operand:SI 1 "register_operand" "")
12384 (match_operand:SI 2 "constant_call_address_operand" "")]
12385 UNSPEC_TLS_LD_BASE))
12386 (clobber (match_scratch:SI 3 ""))
12387 (clobber (match_scratch:SI 4 ""))
12388 (clobber (reg:CC FLAGS_REG))])])
12389
12390 (define_insn "*tls_local_dynamic_base_64"
12391 [(set (match_operand:DI 0 "register_operand" "=a")
12392 (call:DI
12393 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12394 (match_operand:DI 2 "" "")))
12395 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12396 "TARGET_64BIT"
12397 {
12398 output_asm_insn
12399 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12400 if (TARGET_SUN_TLS)
12401 return "call\t%p1@plt";
12402 return "call\t%P1";
12403 }
12404 [(set_attr "type" "multi")
12405 (set_attr "length" "12")])
12406
12407 (define_expand "tls_local_dynamic_base_64"
12408 [(parallel
12409 [(set (match_operand:DI 0 "register_operand" "")
12410 (call:DI
12411 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12412 (const_int 0)))
12413 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12414
12415 ;; Local dynamic of a single variable is a lose. Show combine how
12416 ;; to convert that back to global dynamic.
12417
12418 (define_insn_and_split "*tls_local_dynamic_32_once"
12419 [(set (match_operand:SI 0 "register_operand" "=a")
12420 (plus:SI
12421 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12422 (match_operand:SI 2 "constant_call_address_operand" "z")]
12423 UNSPEC_TLS_LD_BASE)
12424 (const:SI (unspec:SI
12425 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12426 UNSPEC_DTPOFF))))
12427 (clobber (match_scratch:SI 4 "=d"))
12428 (clobber (match_scratch:SI 5 "=c"))
12429 (clobber (reg:CC FLAGS_REG))]
12430 ""
12431 "#"
12432 ""
12433 [(parallel
12434 [(set (match_dup 0)
12435 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12436 UNSPEC_TLS_GD))
12437 (clobber (match_dup 4))
12438 (clobber (match_dup 5))
12439 (clobber (reg:CC FLAGS_REG))])])
12440
12441 ;; Segment register for the thread base ptr load
12442 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12443
12444 ;; Load and add the thread base pointer from %<tp_seg>:0.
12445 (define_insn "*load_tp_<mode>"
12446 [(set (match_operand:P 0 "register_operand" "=r")
12447 (unspec:P [(const_int 0)] UNSPEC_TP))]
12448 ""
12449 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12450 [(set_attr "type" "imov")
12451 (set_attr "modrm" "0")
12452 (set_attr "length" "7")
12453 (set_attr "memory" "load")
12454 (set_attr "imm_disp" "false")])
12455
12456 (define_insn "*add_tp_<mode>"
12457 [(set (match_operand:P 0 "register_operand" "=r")
12458 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12459 (match_operand:P 1 "register_operand" "0")))
12460 (clobber (reg:CC FLAGS_REG))]
12461 ""
12462 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12463 [(set_attr "type" "alu")
12464 (set_attr "modrm" "0")
12465 (set_attr "length" "7")
12466 (set_attr "memory" "load")
12467 (set_attr "imm_disp" "false")])
12468
12469 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12470 ;; %rax as destination of the initial executable code sequence.
12471 (define_insn "tls_initial_exec_64_sun"
12472 [(set (match_operand:DI 0 "register_operand" "=a")
12473 (unspec:DI
12474 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12475 UNSPEC_TLS_IE_SUN))
12476 (clobber (reg:CC FLAGS_REG))]
12477 "TARGET_64BIT && TARGET_SUN_TLS"
12478 {
12479 output_asm_insn
12480 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12481 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12482 }
12483 [(set_attr "type" "multi")])
12484
12485 ;; GNU2 TLS patterns can be split.
12486
12487 (define_expand "tls_dynamic_gnu2_32"
12488 [(set (match_dup 3)
12489 (plus:SI (match_operand:SI 2 "register_operand" "")
12490 (const:SI
12491 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12492 UNSPEC_TLSDESC))))
12493 (parallel
12494 [(set (match_operand:SI 0 "register_operand" "")
12495 (unspec:SI [(match_dup 1) (match_dup 3)
12496 (match_dup 2) (reg:SI SP_REG)]
12497 UNSPEC_TLSDESC))
12498 (clobber (reg:CC FLAGS_REG))])]
12499 "!TARGET_64BIT && TARGET_GNU2_TLS"
12500 {
12501 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12502 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12503 })
12504
12505 (define_insn "*tls_dynamic_lea_32"
12506 [(set (match_operand:SI 0 "register_operand" "=r")
12507 (plus:SI (match_operand:SI 1 "register_operand" "b")
12508 (const:SI
12509 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12510 UNSPEC_TLSDESC))))]
12511 "!TARGET_64BIT && TARGET_GNU2_TLS"
12512 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12513 [(set_attr "type" "lea")
12514 (set_attr "mode" "SI")
12515 (set_attr "length" "6")
12516 (set_attr "length_address" "4")])
12517
12518 (define_insn "*tls_dynamic_call_32"
12519 [(set (match_operand:SI 0 "register_operand" "=a")
12520 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12521 (match_operand:SI 2 "register_operand" "0")
12522 ;; we have to make sure %ebx still points to the GOT
12523 (match_operand:SI 3 "register_operand" "b")
12524 (reg:SI SP_REG)]
12525 UNSPEC_TLSDESC))
12526 (clobber (reg:CC FLAGS_REG))]
12527 "!TARGET_64BIT && TARGET_GNU2_TLS"
12528 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12529 [(set_attr "type" "call")
12530 (set_attr "length" "2")
12531 (set_attr "length_address" "0")])
12532
12533 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12534 [(set (match_operand:SI 0 "register_operand" "=&a")
12535 (plus:SI
12536 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12537 (match_operand:SI 4 "" "")
12538 (match_operand:SI 2 "register_operand" "b")
12539 (reg:SI SP_REG)]
12540 UNSPEC_TLSDESC)
12541 (const:SI (unspec:SI
12542 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12543 UNSPEC_DTPOFF))))
12544 (clobber (reg:CC FLAGS_REG))]
12545 "!TARGET_64BIT && TARGET_GNU2_TLS"
12546 "#"
12547 ""
12548 [(set (match_dup 0) (match_dup 5))]
12549 {
12550 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12551 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12552 })
12553
12554 (define_expand "tls_dynamic_gnu2_64"
12555 [(set (match_dup 2)
12556 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12557 UNSPEC_TLSDESC))
12558 (parallel
12559 [(set (match_operand:DI 0 "register_operand" "")
12560 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12561 UNSPEC_TLSDESC))
12562 (clobber (reg:CC FLAGS_REG))])]
12563 "TARGET_64BIT && TARGET_GNU2_TLS"
12564 {
12565 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12566 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12567 })
12568
12569 (define_insn "*tls_dynamic_lea_64"
12570 [(set (match_operand:DI 0 "register_operand" "=r")
12571 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12572 UNSPEC_TLSDESC))]
12573 "TARGET_64BIT && TARGET_GNU2_TLS"
12574 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12575 [(set_attr "type" "lea")
12576 (set_attr "mode" "DI")
12577 (set_attr "length" "7")
12578 (set_attr "length_address" "4")])
12579
12580 (define_insn "*tls_dynamic_call_64"
12581 [(set (match_operand:DI 0 "register_operand" "=a")
12582 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12583 (match_operand:DI 2 "register_operand" "0")
12584 (reg:DI SP_REG)]
12585 UNSPEC_TLSDESC))
12586 (clobber (reg:CC FLAGS_REG))]
12587 "TARGET_64BIT && TARGET_GNU2_TLS"
12588 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12589 [(set_attr "type" "call")
12590 (set_attr "length" "2")
12591 (set_attr "length_address" "0")])
12592
12593 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12594 [(set (match_operand:DI 0 "register_operand" "=&a")
12595 (plus:DI
12596 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12597 (match_operand:DI 3 "" "")
12598 (reg:DI SP_REG)]
12599 UNSPEC_TLSDESC)
12600 (const:DI (unspec:DI
12601 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12602 UNSPEC_DTPOFF))))
12603 (clobber (reg:CC FLAGS_REG))]
12604 "TARGET_64BIT && TARGET_GNU2_TLS"
12605 "#"
12606 ""
12607 [(set (match_dup 0) (match_dup 4))]
12608 {
12609 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12610 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12611 })
12612 \f
12613 ;; These patterns match the binary 387 instructions for addM3, subM3,
12614 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12615 ;; SFmode. The first is the normal insn, the second the same insn but
12616 ;; with one operand a conversion, and the third the same insn but with
12617 ;; the other operand a conversion. The conversion may be SFmode or
12618 ;; SImode if the target mode DFmode, but only SImode if the target mode
12619 ;; is SFmode.
12620
12621 ;; Gcc is slightly more smart about handling normal two address instructions
12622 ;; so use special patterns for add and mull.
12623
12624 (define_insn "*fop_<mode>_comm_mixed"
12625 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12626 (match_operator:MODEF 3 "binary_fp_operator"
12627 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12628 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12629 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12630 && COMMUTATIVE_ARITH_P (operands[3])
12631 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12632 "* return output_387_binary_op (insn, operands);"
12633 [(set (attr "type")
12634 (if_then_else (eq_attr "alternative" "1,2")
12635 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12636 (const_string "ssemul")
12637 (const_string "sseadd"))
12638 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12639 (const_string "fmul")
12640 (const_string "fop"))))
12641 (set_attr "isa" "*,noavx,avx")
12642 (set_attr "prefix" "orig,orig,vex")
12643 (set_attr "mode" "<MODE>")])
12644
12645 (define_insn "*fop_<mode>_comm_sse"
12646 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12647 (match_operator:MODEF 3 "binary_fp_operator"
12648 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12649 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12650 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12651 && COMMUTATIVE_ARITH_P (operands[3])
12652 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12653 "* return output_387_binary_op (insn, operands);"
12654 [(set (attr "type")
12655 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12656 (const_string "ssemul")
12657 (const_string "sseadd")))
12658 (set_attr "isa" "noavx,avx")
12659 (set_attr "prefix" "orig,vex")
12660 (set_attr "mode" "<MODE>")])
12661
12662 (define_insn "*fop_<mode>_comm_i387"
12663 [(set (match_operand:MODEF 0 "register_operand" "=f")
12664 (match_operator:MODEF 3 "binary_fp_operator"
12665 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12666 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12667 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12668 && COMMUTATIVE_ARITH_P (operands[3])
12669 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12670 "* return output_387_binary_op (insn, operands);"
12671 [(set (attr "type")
12672 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12673 (const_string "fmul")
12674 (const_string "fop")))
12675 (set_attr "mode" "<MODE>")])
12676
12677 (define_insn "*fop_<mode>_1_mixed"
12678 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12679 (match_operator:MODEF 3 "binary_fp_operator"
12680 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12681 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12682 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12683 && !COMMUTATIVE_ARITH_P (operands[3])
12684 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12685 "* return output_387_binary_op (insn, operands);"
12686 [(set (attr "type")
12687 (cond [(and (eq_attr "alternative" "2,3")
12688 (match_operand:MODEF 3 "mult_operator" ""))
12689 (const_string "ssemul")
12690 (and (eq_attr "alternative" "2,3")
12691 (match_operand:MODEF 3 "div_operator" ""))
12692 (const_string "ssediv")
12693 (eq_attr "alternative" "2,3")
12694 (const_string "sseadd")
12695 (match_operand:MODEF 3 "mult_operator" "")
12696 (const_string "fmul")
12697 (match_operand:MODEF 3 "div_operator" "")
12698 (const_string "fdiv")
12699 ]
12700 (const_string "fop")))
12701 (set_attr "isa" "*,*,noavx,avx")
12702 (set_attr "prefix" "orig,orig,orig,vex")
12703 (set_attr "mode" "<MODE>")])
12704
12705 (define_insn "*rcpsf2_sse"
12706 [(set (match_operand:SF 0 "register_operand" "=x")
12707 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12708 UNSPEC_RCP))]
12709 "TARGET_SSE_MATH"
12710 "%vrcpss\t{%1, %d0|%d0, %1}"
12711 [(set_attr "type" "sse")
12712 (set_attr "atom_sse_attr" "rcp")
12713 (set_attr "prefix" "maybe_vex")
12714 (set_attr "mode" "SF")])
12715
12716 (define_insn "*fop_<mode>_1_sse"
12717 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12718 (match_operator:MODEF 3 "binary_fp_operator"
12719 [(match_operand:MODEF 1 "register_operand" "0,x")
12720 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12721 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12722 && !COMMUTATIVE_ARITH_P (operands[3])"
12723 "* return output_387_binary_op (insn, operands);"
12724 [(set (attr "type")
12725 (cond [(match_operand:MODEF 3 "mult_operator" "")
12726 (const_string "ssemul")
12727 (match_operand:MODEF 3 "div_operator" "")
12728 (const_string "ssediv")
12729 ]
12730 (const_string "sseadd")))
12731 (set_attr "isa" "noavx,avx")
12732 (set_attr "prefix" "orig,vex")
12733 (set_attr "mode" "<MODE>")])
12734
12735 ;; This pattern is not fully shadowed by the pattern above.
12736 (define_insn "*fop_<mode>_1_i387"
12737 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12738 (match_operator:MODEF 3 "binary_fp_operator"
12739 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12740 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12741 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12742 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12743 && !COMMUTATIVE_ARITH_P (operands[3])
12744 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12745 "* return output_387_binary_op (insn, operands);"
12746 [(set (attr "type")
12747 (cond [(match_operand:MODEF 3 "mult_operator" "")
12748 (const_string "fmul")
12749 (match_operand:MODEF 3 "div_operator" "")
12750 (const_string "fdiv")
12751 ]
12752 (const_string "fop")))
12753 (set_attr "mode" "<MODE>")])
12754
12755 ;; ??? Add SSE splitters for these!
12756 (define_insn "*fop_<MODEF:mode>_2_i387"
12757 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12758 (match_operator:MODEF 3 "binary_fp_operator"
12759 [(float:MODEF
12760 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12761 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12762 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12763 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12764 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12765 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12766 [(set (attr "type")
12767 (cond [(match_operand:MODEF 3 "mult_operator" "")
12768 (const_string "fmul")
12769 (match_operand:MODEF 3 "div_operator" "")
12770 (const_string "fdiv")
12771 ]
12772 (const_string "fop")))
12773 (set_attr "fp_int_src" "true")
12774 (set_attr "mode" "<SWI24:MODE>")])
12775
12776 (define_insn "*fop_<MODEF:mode>_3_i387"
12777 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12778 (match_operator:MODEF 3 "binary_fp_operator"
12779 [(match_operand:MODEF 1 "register_operand" "0,0")
12780 (float:MODEF
12781 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12782 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12783 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12784 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12785 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12786 [(set (attr "type")
12787 (cond [(match_operand:MODEF 3 "mult_operator" "")
12788 (const_string "fmul")
12789 (match_operand:MODEF 3 "div_operator" "")
12790 (const_string "fdiv")
12791 ]
12792 (const_string "fop")))
12793 (set_attr "fp_int_src" "true")
12794 (set_attr "mode" "<MODE>")])
12795
12796 (define_insn "*fop_df_4_i387"
12797 [(set (match_operand:DF 0 "register_operand" "=f,f")
12798 (match_operator:DF 3 "binary_fp_operator"
12799 [(float_extend:DF
12800 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12801 (match_operand:DF 2 "register_operand" "0,f")]))]
12802 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12803 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12804 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12805 "* return output_387_binary_op (insn, operands);"
12806 [(set (attr "type")
12807 (cond [(match_operand:DF 3 "mult_operator" "")
12808 (const_string "fmul")
12809 (match_operand:DF 3 "div_operator" "")
12810 (const_string "fdiv")
12811 ]
12812 (const_string "fop")))
12813 (set_attr "mode" "SF")])
12814
12815 (define_insn "*fop_df_5_i387"
12816 [(set (match_operand:DF 0 "register_operand" "=f,f")
12817 (match_operator:DF 3 "binary_fp_operator"
12818 [(match_operand:DF 1 "register_operand" "0,f")
12819 (float_extend:DF
12820 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12821 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12822 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12823 "* return output_387_binary_op (insn, operands);"
12824 [(set (attr "type")
12825 (cond [(match_operand:DF 3 "mult_operator" "")
12826 (const_string "fmul")
12827 (match_operand:DF 3 "div_operator" "")
12828 (const_string "fdiv")
12829 ]
12830 (const_string "fop")))
12831 (set_attr "mode" "SF")])
12832
12833 (define_insn "*fop_df_6_i387"
12834 [(set (match_operand:DF 0 "register_operand" "=f,f")
12835 (match_operator:DF 3 "binary_fp_operator"
12836 [(float_extend:DF
12837 (match_operand:SF 1 "register_operand" "0,f"))
12838 (float_extend:DF
12839 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12840 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12841 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12842 "* return output_387_binary_op (insn, operands);"
12843 [(set (attr "type")
12844 (cond [(match_operand:DF 3 "mult_operator" "")
12845 (const_string "fmul")
12846 (match_operand:DF 3 "div_operator" "")
12847 (const_string "fdiv")
12848 ]
12849 (const_string "fop")))
12850 (set_attr "mode" "SF")])
12851
12852 (define_insn "*fop_xf_comm_i387"
12853 [(set (match_operand:XF 0 "register_operand" "=f")
12854 (match_operator:XF 3 "binary_fp_operator"
12855 [(match_operand:XF 1 "register_operand" "%0")
12856 (match_operand:XF 2 "register_operand" "f")]))]
12857 "TARGET_80387
12858 && COMMUTATIVE_ARITH_P (operands[3])"
12859 "* return output_387_binary_op (insn, operands);"
12860 [(set (attr "type")
12861 (if_then_else (match_operand:XF 3 "mult_operator" "")
12862 (const_string "fmul")
12863 (const_string "fop")))
12864 (set_attr "mode" "XF")])
12865
12866 (define_insn "*fop_xf_1_i387"
12867 [(set (match_operand:XF 0 "register_operand" "=f,f")
12868 (match_operator:XF 3 "binary_fp_operator"
12869 [(match_operand:XF 1 "register_operand" "0,f")
12870 (match_operand:XF 2 "register_operand" "f,0")]))]
12871 "TARGET_80387
12872 && !COMMUTATIVE_ARITH_P (operands[3])"
12873 "* return output_387_binary_op (insn, operands);"
12874 [(set (attr "type")
12875 (cond [(match_operand:XF 3 "mult_operator" "")
12876 (const_string "fmul")
12877 (match_operand:XF 3 "div_operator" "")
12878 (const_string "fdiv")
12879 ]
12880 (const_string "fop")))
12881 (set_attr "mode" "XF")])
12882
12883 (define_insn "*fop_xf_2_i387"
12884 [(set (match_operand:XF 0 "register_operand" "=f,f")
12885 (match_operator:XF 3 "binary_fp_operator"
12886 [(float:XF
12887 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12888 (match_operand:XF 2 "register_operand" "0,0")]))]
12889 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12890 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12891 [(set (attr "type")
12892 (cond [(match_operand:XF 3 "mult_operator" "")
12893 (const_string "fmul")
12894 (match_operand:XF 3 "div_operator" "")
12895 (const_string "fdiv")
12896 ]
12897 (const_string "fop")))
12898 (set_attr "fp_int_src" "true")
12899 (set_attr "mode" "<MODE>")])
12900
12901 (define_insn "*fop_xf_3_i387"
12902 [(set (match_operand:XF 0 "register_operand" "=f,f")
12903 (match_operator:XF 3 "binary_fp_operator"
12904 [(match_operand:XF 1 "register_operand" "0,0")
12905 (float:XF
12906 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12907 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12908 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12909 [(set (attr "type")
12910 (cond [(match_operand:XF 3 "mult_operator" "")
12911 (const_string "fmul")
12912 (match_operand:XF 3 "div_operator" "")
12913 (const_string "fdiv")
12914 ]
12915 (const_string "fop")))
12916 (set_attr "fp_int_src" "true")
12917 (set_attr "mode" "<MODE>")])
12918
12919 (define_insn "*fop_xf_4_i387"
12920 [(set (match_operand:XF 0 "register_operand" "=f,f")
12921 (match_operator:XF 3 "binary_fp_operator"
12922 [(float_extend:XF
12923 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12924 (match_operand:XF 2 "register_operand" "0,f")]))]
12925 "TARGET_80387"
12926 "* return output_387_binary_op (insn, operands);"
12927 [(set (attr "type")
12928 (cond [(match_operand:XF 3 "mult_operator" "")
12929 (const_string "fmul")
12930 (match_operand:XF 3 "div_operator" "")
12931 (const_string "fdiv")
12932 ]
12933 (const_string "fop")))
12934 (set_attr "mode" "<MODE>")])
12935
12936 (define_insn "*fop_xf_5_i387"
12937 [(set (match_operand:XF 0 "register_operand" "=f,f")
12938 (match_operator:XF 3 "binary_fp_operator"
12939 [(match_operand:XF 1 "register_operand" "0,f")
12940 (float_extend:XF
12941 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12942 "TARGET_80387"
12943 "* return output_387_binary_op (insn, operands);"
12944 [(set (attr "type")
12945 (cond [(match_operand:XF 3 "mult_operator" "")
12946 (const_string "fmul")
12947 (match_operand:XF 3 "div_operator" "")
12948 (const_string "fdiv")
12949 ]
12950 (const_string "fop")))
12951 (set_attr "mode" "<MODE>")])
12952
12953 (define_insn "*fop_xf_6_i387"
12954 [(set (match_operand:XF 0 "register_operand" "=f,f")
12955 (match_operator:XF 3 "binary_fp_operator"
12956 [(float_extend:XF
12957 (match_operand:MODEF 1 "register_operand" "0,f"))
12958 (float_extend:XF
12959 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12960 "TARGET_80387"
12961 "* return output_387_binary_op (insn, operands);"
12962 [(set (attr "type")
12963 (cond [(match_operand:XF 3 "mult_operator" "")
12964 (const_string "fmul")
12965 (match_operand:XF 3 "div_operator" "")
12966 (const_string "fdiv")
12967 ]
12968 (const_string "fop")))
12969 (set_attr "mode" "<MODE>")])
12970
12971 (define_split
12972 [(set (match_operand 0 "register_operand" "")
12973 (match_operator 3 "binary_fp_operator"
12974 [(float (match_operand:SWI24 1 "register_operand" ""))
12975 (match_operand 2 "register_operand" "")]))]
12976 "reload_completed
12977 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12978 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12979 [(const_int 0)]
12980 {
12981 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12982 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12983 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12984 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12985 GET_MODE (operands[3]),
12986 operands[4],
12987 operands[2])));
12988 ix86_free_from_memory (GET_MODE (operands[1]));
12989 DONE;
12990 })
12991
12992 (define_split
12993 [(set (match_operand 0 "register_operand" "")
12994 (match_operator 3 "binary_fp_operator"
12995 [(match_operand 1 "register_operand" "")
12996 (float (match_operand:SWI24 2 "register_operand" ""))]))]
12997 "reload_completed
12998 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12999 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13000 [(const_int 0)]
13001 {
13002 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13003 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13004 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13005 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13006 GET_MODE (operands[3]),
13007 operands[1],
13008 operands[4])));
13009 ix86_free_from_memory (GET_MODE (operands[2]));
13010 DONE;
13011 })
13012 \f
13013 ;; FPU special functions.
13014
13015 ;; This pattern implements a no-op XFmode truncation for
13016 ;; all fancy i386 XFmode math functions.
13017
13018 (define_insn "truncxf<mode>2_i387_noop_unspec"
13019 [(set (match_operand:MODEF 0 "register_operand" "=f")
13020 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13021 UNSPEC_TRUNC_NOOP))]
13022 "TARGET_USE_FANCY_MATH_387"
13023 "* return output_387_reg_move (insn, operands);"
13024 [(set_attr "type" "fmov")
13025 (set_attr "mode" "<MODE>")])
13026
13027 (define_insn "sqrtxf2"
13028 [(set (match_operand:XF 0 "register_operand" "=f")
13029 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13030 "TARGET_USE_FANCY_MATH_387"
13031 "fsqrt"
13032 [(set_attr "type" "fpspc")
13033 (set_attr "mode" "XF")
13034 (set_attr "athlon_decode" "direct")
13035 (set_attr "amdfam10_decode" "direct")
13036 (set_attr "bdver1_decode" "direct")])
13037
13038 (define_insn "sqrt_extend<mode>xf2_i387"
13039 [(set (match_operand:XF 0 "register_operand" "=f")
13040 (sqrt:XF
13041 (float_extend:XF
13042 (match_operand:MODEF 1 "register_operand" "0"))))]
13043 "TARGET_USE_FANCY_MATH_387"
13044 "fsqrt"
13045 [(set_attr "type" "fpspc")
13046 (set_attr "mode" "XF")
13047 (set_attr "athlon_decode" "direct")
13048 (set_attr "amdfam10_decode" "direct")
13049 (set_attr "bdver1_decode" "direct")])
13050
13051 (define_insn "*rsqrtsf2_sse"
13052 [(set (match_operand:SF 0 "register_operand" "=x")
13053 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13054 UNSPEC_RSQRT))]
13055 "TARGET_SSE_MATH"
13056 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13057 [(set_attr "type" "sse")
13058 (set_attr "atom_sse_attr" "rcp")
13059 (set_attr "prefix" "maybe_vex")
13060 (set_attr "mode" "SF")])
13061
13062 (define_expand "rsqrtsf2"
13063 [(set (match_operand:SF 0 "register_operand" "")
13064 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13065 UNSPEC_RSQRT))]
13066 "TARGET_SSE_MATH"
13067 {
13068 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13069 DONE;
13070 })
13071
13072 (define_insn "*sqrt<mode>2_sse"
13073 [(set (match_operand:MODEF 0 "register_operand" "=x")
13074 (sqrt:MODEF
13075 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13076 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13077 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13078 [(set_attr "type" "sse")
13079 (set_attr "atom_sse_attr" "sqrt")
13080 (set_attr "prefix" "maybe_vex")
13081 (set_attr "mode" "<MODE>")
13082 (set_attr "athlon_decode" "*")
13083 (set_attr "amdfam10_decode" "*")
13084 (set_attr "bdver1_decode" "*")])
13085
13086 (define_expand "sqrt<mode>2"
13087 [(set (match_operand:MODEF 0 "register_operand" "")
13088 (sqrt:MODEF
13089 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13090 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13091 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13092 {
13093 if (<MODE>mode == SFmode
13094 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13095 && flag_finite_math_only && !flag_trapping_math
13096 && flag_unsafe_math_optimizations)
13097 {
13098 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13099 DONE;
13100 }
13101
13102 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13103 {
13104 rtx op0 = gen_reg_rtx (XFmode);
13105 rtx op1 = force_reg (<MODE>mode, operands[1]);
13106
13107 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13108 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13109 DONE;
13110 }
13111 })
13112
13113 (define_insn "fpremxf4_i387"
13114 [(set (match_operand:XF 0 "register_operand" "=f")
13115 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13116 (match_operand:XF 3 "register_operand" "1")]
13117 UNSPEC_FPREM_F))
13118 (set (match_operand:XF 1 "register_operand" "=u")
13119 (unspec:XF [(match_dup 2) (match_dup 3)]
13120 UNSPEC_FPREM_U))
13121 (set (reg:CCFP FPSR_REG)
13122 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13123 UNSPEC_C2_FLAG))]
13124 "TARGET_USE_FANCY_MATH_387"
13125 "fprem"
13126 [(set_attr "type" "fpspc")
13127 (set_attr "mode" "XF")])
13128
13129 (define_expand "fmodxf3"
13130 [(use (match_operand:XF 0 "register_operand" ""))
13131 (use (match_operand:XF 1 "general_operand" ""))
13132 (use (match_operand:XF 2 "general_operand" ""))]
13133 "TARGET_USE_FANCY_MATH_387"
13134 {
13135 rtx label = gen_label_rtx ();
13136
13137 rtx op1 = gen_reg_rtx (XFmode);
13138 rtx op2 = gen_reg_rtx (XFmode);
13139
13140 emit_move_insn (op2, operands[2]);
13141 emit_move_insn (op1, operands[1]);
13142
13143 emit_label (label);
13144 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13145 ix86_emit_fp_unordered_jump (label);
13146 LABEL_NUSES (label) = 1;
13147
13148 emit_move_insn (operands[0], op1);
13149 DONE;
13150 })
13151
13152 (define_expand "fmod<mode>3"
13153 [(use (match_operand:MODEF 0 "register_operand" ""))
13154 (use (match_operand:MODEF 1 "general_operand" ""))
13155 (use (match_operand:MODEF 2 "general_operand" ""))]
13156 "TARGET_USE_FANCY_MATH_387"
13157 {
13158 rtx (*gen_truncxf) (rtx, rtx);
13159
13160 rtx label = gen_label_rtx ();
13161
13162 rtx op1 = gen_reg_rtx (XFmode);
13163 rtx op2 = gen_reg_rtx (XFmode);
13164
13165 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13166 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13167
13168 emit_label (label);
13169 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13170 ix86_emit_fp_unordered_jump (label);
13171 LABEL_NUSES (label) = 1;
13172
13173 /* Truncate the result properly for strict SSE math. */
13174 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13175 && !TARGET_MIX_SSE_I387)
13176 gen_truncxf = gen_truncxf<mode>2;
13177 else
13178 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13179
13180 emit_insn (gen_truncxf (operands[0], op1));
13181 DONE;
13182 })
13183
13184 (define_insn "fprem1xf4_i387"
13185 [(set (match_operand:XF 0 "register_operand" "=f")
13186 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13187 (match_operand:XF 3 "register_operand" "1")]
13188 UNSPEC_FPREM1_F))
13189 (set (match_operand:XF 1 "register_operand" "=u")
13190 (unspec:XF [(match_dup 2) (match_dup 3)]
13191 UNSPEC_FPREM1_U))
13192 (set (reg:CCFP FPSR_REG)
13193 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13194 UNSPEC_C2_FLAG))]
13195 "TARGET_USE_FANCY_MATH_387"
13196 "fprem1"
13197 [(set_attr "type" "fpspc")
13198 (set_attr "mode" "XF")])
13199
13200 (define_expand "remainderxf3"
13201 [(use (match_operand:XF 0 "register_operand" ""))
13202 (use (match_operand:XF 1 "general_operand" ""))
13203 (use (match_operand:XF 2 "general_operand" ""))]
13204 "TARGET_USE_FANCY_MATH_387"
13205 {
13206 rtx label = gen_label_rtx ();
13207
13208 rtx op1 = gen_reg_rtx (XFmode);
13209 rtx op2 = gen_reg_rtx (XFmode);
13210
13211 emit_move_insn (op2, operands[2]);
13212 emit_move_insn (op1, operands[1]);
13213
13214 emit_label (label);
13215 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13216 ix86_emit_fp_unordered_jump (label);
13217 LABEL_NUSES (label) = 1;
13218
13219 emit_move_insn (operands[0], op1);
13220 DONE;
13221 })
13222
13223 (define_expand "remainder<mode>3"
13224 [(use (match_operand:MODEF 0 "register_operand" ""))
13225 (use (match_operand:MODEF 1 "general_operand" ""))
13226 (use (match_operand:MODEF 2 "general_operand" ""))]
13227 "TARGET_USE_FANCY_MATH_387"
13228 {
13229 rtx (*gen_truncxf) (rtx, rtx);
13230
13231 rtx label = gen_label_rtx ();
13232
13233 rtx op1 = gen_reg_rtx (XFmode);
13234 rtx op2 = gen_reg_rtx (XFmode);
13235
13236 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13237 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13238
13239 emit_label (label);
13240
13241 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13242 ix86_emit_fp_unordered_jump (label);
13243 LABEL_NUSES (label) = 1;
13244
13245 /* Truncate the result properly for strict SSE math. */
13246 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13247 && !TARGET_MIX_SSE_I387)
13248 gen_truncxf = gen_truncxf<mode>2;
13249 else
13250 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13251
13252 emit_insn (gen_truncxf (operands[0], op1));
13253 DONE;
13254 })
13255
13256 (define_insn "*sinxf2_i387"
13257 [(set (match_operand:XF 0 "register_operand" "=f")
13258 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13259 "TARGET_USE_FANCY_MATH_387
13260 && flag_unsafe_math_optimizations"
13261 "fsin"
13262 [(set_attr "type" "fpspc")
13263 (set_attr "mode" "XF")])
13264
13265 (define_insn "*sin_extend<mode>xf2_i387"
13266 [(set (match_operand:XF 0 "register_operand" "=f")
13267 (unspec:XF [(float_extend:XF
13268 (match_operand:MODEF 1 "register_operand" "0"))]
13269 UNSPEC_SIN))]
13270 "TARGET_USE_FANCY_MATH_387
13271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13272 || TARGET_MIX_SSE_I387)
13273 && flag_unsafe_math_optimizations"
13274 "fsin"
13275 [(set_attr "type" "fpspc")
13276 (set_attr "mode" "XF")])
13277
13278 (define_insn "*cosxf2_i387"
13279 [(set (match_operand:XF 0 "register_operand" "=f")
13280 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13281 "TARGET_USE_FANCY_MATH_387
13282 && flag_unsafe_math_optimizations"
13283 "fcos"
13284 [(set_attr "type" "fpspc")
13285 (set_attr "mode" "XF")])
13286
13287 (define_insn "*cos_extend<mode>xf2_i387"
13288 [(set (match_operand:XF 0 "register_operand" "=f")
13289 (unspec:XF [(float_extend:XF
13290 (match_operand:MODEF 1 "register_operand" "0"))]
13291 UNSPEC_COS))]
13292 "TARGET_USE_FANCY_MATH_387
13293 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13294 || TARGET_MIX_SSE_I387)
13295 && flag_unsafe_math_optimizations"
13296 "fcos"
13297 [(set_attr "type" "fpspc")
13298 (set_attr "mode" "XF")])
13299
13300 ;; When sincos pattern is defined, sin and cos builtin functions will be
13301 ;; expanded to sincos pattern with one of its outputs left unused.
13302 ;; CSE pass will figure out if two sincos patterns can be combined,
13303 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13304 ;; depending on the unused output.
13305
13306 (define_insn "sincosxf3"
13307 [(set (match_operand:XF 0 "register_operand" "=f")
13308 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13309 UNSPEC_SINCOS_COS))
13310 (set (match_operand:XF 1 "register_operand" "=u")
13311 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13312 "TARGET_USE_FANCY_MATH_387
13313 && flag_unsafe_math_optimizations"
13314 "fsincos"
13315 [(set_attr "type" "fpspc")
13316 (set_attr "mode" "XF")])
13317
13318 (define_split
13319 [(set (match_operand:XF 0 "register_operand" "")
13320 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13321 UNSPEC_SINCOS_COS))
13322 (set (match_operand:XF 1 "register_operand" "")
13323 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13324 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13325 && can_create_pseudo_p ()"
13326 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13327
13328 (define_split
13329 [(set (match_operand:XF 0 "register_operand" "")
13330 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13331 UNSPEC_SINCOS_COS))
13332 (set (match_operand:XF 1 "register_operand" "")
13333 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13334 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13335 && can_create_pseudo_p ()"
13336 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13337
13338 (define_insn "sincos_extend<mode>xf3_i387"
13339 [(set (match_operand:XF 0 "register_operand" "=f")
13340 (unspec:XF [(float_extend:XF
13341 (match_operand:MODEF 2 "register_operand" "0"))]
13342 UNSPEC_SINCOS_COS))
13343 (set (match_operand:XF 1 "register_operand" "=u")
13344 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13345 "TARGET_USE_FANCY_MATH_387
13346 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13347 || TARGET_MIX_SSE_I387)
13348 && flag_unsafe_math_optimizations"
13349 "fsincos"
13350 [(set_attr "type" "fpspc")
13351 (set_attr "mode" "XF")])
13352
13353 (define_split
13354 [(set (match_operand:XF 0 "register_operand" "")
13355 (unspec:XF [(float_extend:XF
13356 (match_operand:MODEF 2 "register_operand" ""))]
13357 UNSPEC_SINCOS_COS))
13358 (set (match_operand:XF 1 "register_operand" "")
13359 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13360 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13361 && can_create_pseudo_p ()"
13362 [(set (match_dup 1)
13363 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13364
13365 (define_split
13366 [(set (match_operand:XF 0 "register_operand" "")
13367 (unspec:XF [(float_extend:XF
13368 (match_operand:MODEF 2 "register_operand" ""))]
13369 UNSPEC_SINCOS_COS))
13370 (set (match_operand:XF 1 "register_operand" "")
13371 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13372 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13373 && can_create_pseudo_p ()"
13374 [(set (match_dup 0)
13375 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13376
13377 (define_expand "sincos<mode>3"
13378 [(use (match_operand:MODEF 0 "register_operand" ""))
13379 (use (match_operand:MODEF 1 "register_operand" ""))
13380 (use (match_operand:MODEF 2 "register_operand" ""))]
13381 "TARGET_USE_FANCY_MATH_387
13382 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13383 || TARGET_MIX_SSE_I387)
13384 && flag_unsafe_math_optimizations"
13385 {
13386 rtx op0 = gen_reg_rtx (XFmode);
13387 rtx op1 = gen_reg_rtx (XFmode);
13388
13389 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13390 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13391 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13392 DONE;
13393 })
13394
13395 (define_insn "fptanxf4_i387"
13396 [(set (match_operand:XF 0 "register_operand" "=f")
13397 (match_operand:XF 3 "const_double_operand" "F"))
13398 (set (match_operand:XF 1 "register_operand" "=u")
13399 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13400 UNSPEC_TAN))]
13401 "TARGET_USE_FANCY_MATH_387
13402 && flag_unsafe_math_optimizations
13403 && standard_80387_constant_p (operands[3]) == 2"
13404 "fptan"
13405 [(set_attr "type" "fpspc")
13406 (set_attr "mode" "XF")])
13407
13408 (define_insn "fptan_extend<mode>xf4_i387"
13409 [(set (match_operand:MODEF 0 "register_operand" "=f")
13410 (match_operand:MODEF 3 "const_double_operand" "F"))
13411 (set (match_operand:XF 1 "register_operand" "=u")
13412 (unspec:XF [(float_extend:XF
13413 (match_operand:MODEF 2 "register_operand" "0"))]
13414 UNSPEC_TAN))]
13415 "TARGET_USE_FANCY_MATH_387
13416 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13417 || TARGET_MIX_SSE_I387)
13418 && flag_unsafe_math_optimizations
13419 && standard_80387_constant_p (operands[3]) == 2"
13420 "fptan"
13421 [(set_attr "type" "fpspc")
13422 (set_attr "mode" "XF")])
13423
13424 (define_expand "tanxf2"
13425 [(use (match_operand:XF 0 "register_operand" ""))
13426 (use (match_operand:XF 1 "register_operand" ""))]
13427 "TARGET_USE_FANCY_MATH_387
13428 && flag_unsafe_math_optimizations"
13429 {
13430 rtx one = gen_reg_rtx (XFmode);
13431 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13432
13433 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13434 DONE;
13435 })
13436
13437 (define_expand "tan<mode>2"
13438 [(use (match_operand:MODEF 0 "register_operand" ""))
13439 (use (match_operand:MODEF 1 "register_operand" ""))]
13440 "TARGET_USE_FANCY_MATH_387
13441 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13442 || TARGET_MIX_SSE_I387)
13443 && flag_unsafe_math_optimizations"
13444 {
13445 rtx op0 = gen_reg_rtx (XFmode);
13446
13447 rtx one = gen_reg_rtx (<MODE>mode);
13448 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13449
13450 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13451 operands[1], op2));
13452 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13453 DONE;
13454 })
13455
13456 (define_insn "*fpatanxf3_i387"
13457 [(set (match_operand:XF 0 "register_operand" "=f")
13458 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13459 (match_operand:XF 2 "register_operand" "u")]
13460 UNSPEC_FPATAN))
13461 (clobber (match_scratch:XF 3 "=2"))]
13462 "TARGET_USE_FANCY_MATH_387
13463 && flag_unsafe_math_optimizations"
13464 "fpatan"
13465 [(set_attr "type" "fpspc")
13466 (set_attr "mode" "XF")])
13467
13468 (define_insn "fpatan_extend<mode>xf3_i387"
13469 [(set (match_operand:XF 0 "register_operand" "=f")
13470 (unspec:XF [(float_extend:XF
13471 (match_operand:MODEF 1 "register_operand" "0"))
13472 (float_extend:XF
13473 (match_operand:MODEF 2 "register_operand" "u"))]
13474 UNSPEC_FPATAN))
13475 (clobber (match_scratch:XF 3 "=2"))]
13476 "TARGET_USE_FANCY_MATH_387
13477 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13478 || TARGET_MIX_SSE_I387)
13479 && flag_unsafe_math_optimizations"
13480 "fpatan"
13481 [(set_attr "type" "fpspc")
13482 (set_attr "mode" "XF")])
13483
13484 (define_expand "atan2xf3"
13485 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13486 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13487 (match_operand:XF 1 "register_operand" "")]
13488 UNSPEC_FPATAN))
13489 (clobber (match_scratch:XF 3 ""))])]
13490 "TARGET_USE_FANCY_MATH_387
13491 && flag_unsafe_math_optimizations")
13492
13493 (define_expand "atan2<mode>3"
13494 [(use (match_operand:MODEF 0 "register_operand" ""))
13495 (use (match_operand:MODEF 1 "register_operand" ""))
13496 (use (match_operand:MODEF 2 "register_operand" ""))]
13497 "TARGET_USE_FANCY_MATH_387
13498 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13499 || TARGET_MIX_SSE_I387)
13500 && flag_unsafe_math_optimizations"
13501 {
13502 rtx op0 = gen_reg_rtx (XFmode);
13503
13504 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13505 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13506 DONE;
13507 })
13508
13509 (define_expand "atanxf2"
13510 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13511 (unspec:XF [(match_dup 2)
13512 (match_operand:XF 1 "register_operand" "")]
13513 UNSPEC_FPATAN))
13514 (clobber (match_scratch:XF 3 ""))])]
13515 "TARGET_USE_FANCY_MATH_387
13516 && flag_unsafe_math_optimizations"
13517 {
13518 operands[2] = gen_reg_rtx (XFmode);
13519 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13520 })
13521
13522 (define_expand "atan<mode>2"
13523 [(use (match_operand:MODEF 0 "register_operand" ""))
13524 (use (match_operand:MODEF 1 "register_operand" ""))]
13525 "TARGET_USE_FANCY_MATH_387
13526 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13527 || TARGET_MIX_SSE_I387)
13528 && flag_unsafe_math_optimizations"
13529 {
13530 rtx op0 = gen_reg_rtx (XFmode);
13531
13532 rtx op2 = gen_reg_rtx (<MODE>mode);
13533 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13534
13535 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13536 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13537 DONE;
13538 })
13539
13540 (define_expand "asinxf2"
13541 [(set (match_dup 2)
13542 (mult:XF (match_operand:XF 1 "register_operand" "")
13543 (match_dup 1)))
13544 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13545 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13546 (parallel [(set (match_operand:XF 0 "register_operand" "")
13547 (unspec:XF [(match_dup 5) (match_dup 1)]
13548 UNSPEC_FPATAN))
13549 (clobber (match_scratch:XF 6 ""))])]
13550 "TARGET_USE_FANCY_MATH_387
13551 && flag_unsafe_math_optimizations"
13552 {
13553 int i;
13554
13555 if (optimize_insn_for_size_p ())
13556 FAIL;
13557
13558 for (i = 2; i < 6; i++)
13559 operands[i] = gen_reg_rtx (XFmode);
13560
13561 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13562 })
13563
13564 (define_expand "asin<mode>2"
13565 [(use (match_operand:MODEF 0 "register_operand" ""))
13566 (use (match_operand:MODEF 1 "general_operand" ""))]
13567 "TARGET_USE_FANCY_MATH_387
13568 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13569 || TARGET_MIX_SSE_I387)
13570 && flag_unsafe_math_optimizations"
13571 {
13572 rtx op0 = gen_reg_rtx (XFmode);
13573 rtx op1 = gen_reg_rtx (XFmode);
13574
13575 if (optimize_insn_for_size_p ())
13576 FAIL;
13577
13578 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13579 emit_insn (gen_asinxf2 (op0, op1));
13580 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13581 DONE;
13582 })
13583
13584 (define_expand "acosxf2"
13585 [(set (match_dup 2)
13586 (mult:XF (match_operand:XF 1 "register_operand" "")
13587 (match_dup 1)))
13588 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13589 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13590 (parallel [(set (match_operand:XF 0 "register_operand" "")
13591 (unspec:XF [(match_dup 1) (match_dup 5)]
13592 UNSPEC_FPATAN))
13593 (clobber (match_scratch:XF 6 ""))])]
13594 "TARGET_USE_FANCY_MATH_387
13595 && flag_unsafe_math_optimizations"
13596 {
13597 int i;
13598
13599 if (optimize_insn_for_size_p ())
13600 FAIL;
13601
13602 for (i = 2; i < 6; i++)
13603 operands[i] = gen_reg_rtx (XFmode);
13604
13605 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13606 })
13607
13608 (define_expand "acos<mode>2"
13609 [(use (match_operand:MODEF 0 "register_operand" ""))
13610 (use (match_operand:MODEF 1 "general_operand" ""))]
13611 "TARGET_USE_FANCY_MATH_387
13612 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13613 || TARGET_MIX_SSE_I387)
13614 && flag_unsafe_math_optimizations"
13615 {
13616 rtx op0 = gen_reg_rtx (XFmode);
13617 rtx op1 = gen_reg_rtx (XFmode);
13618
13619 if (optimize_insn_for_size_p ())
13620 FAIL;
13621
13622 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13623 emit_insn (gen_acosxf2 (op0, op1));
13624 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13625 DONE;
13626 })
13627
13628 (define_insn "fyl2xxf3_i387"
13629 [(set (match_operand:XF 0 "register_operand" "=f")
13630 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13631 (match_operand:XF 2 "register_operand" "u")]
13632 UNSPEC_FYL2X))
13633 (clobber (match_scratch:XF 3 "=2"))]
13634 "TARGET_USE_FANCY_MATH_387
13635 && flag_unsafe_math_optimizations"
13636 "fyl2x"
13637 [(set_attr "type" "fpspc")
13638 (set_attr "mode" "XF")])
13639
13640 (define_insn "fyl2x_extend<mode>xf3_i387"
13641 [(set (match_operand:XF 0 "register_operand" "=f")
13642 (unspec:XF [(float_extend:XF
13643 (match_operand:MODEF 1 "register_operand" "0"))
13644 (match_operand:XF 2 "register_operand" "u")]
13645 UNSPEC_FYL2X))
13646 (clobber (match_scratch:XF 3 "=2"))]
13647 "TARGET_USE_FANCY_MATH_387
13648 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13649 || TARGET_MIX_SSE_I387)
13650 && flag_unsafe_math_optimizations"
13651 "fyl2x"
13652 [(set_attr "type" "fpspc")
13653 (set_attr "mode" "XF")])
13654
13655 (define_expand "logxf2"
13656 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13657 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13658 (match_dup 2)] UNSPEC_FYL2X))
13659 (clobber (match_scratch:XF 3 ""))])]
13660 "TARGET_USE_FANCY_MATH_387
13661 && flag_unsafe_math_optimizations"
13662 {
13663 operands[2] = gen_reg_rtx (XFmode);
13664 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13665 })
13666
13667 (define_expand "log<mode>2"
13668 [(use (match_operand:MODEF 0 "register_operand" ""))
13669 (use (match_operand:MODEF 1 "register_operand" ""))]
13670 "TARGET_USE_FANCY_MATH_387
13671 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13672 || TARGET_MIX_SSE_I387)
13673 && flag_unsafe_math_optimizations"
13674 {
13675 rtx op0 = gen_reg_rtx (XFmode);
13676
13677 rtx op2 = gen_reg_rtx (XFmode);
13678 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13679
13680 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13682 DONE;
13683 })
13684
13685 (define_expand "log10xf2"
13686 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13687 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13688 (match_dup 2)] UNSPEC_FYL2X))
13689 (clobber (match_scratch:XF 3 ""))])]
13690 "TARGET_USE_FANCY_MATH_387
13691 && flag_unsafe_math_optimizations"
13692 {
13693 operands[2] = gen_reg_rtx (XFmode);
13694 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13695 })
13696
13697 (define_expand "log10<mode>2"
13698 [(use (match_operand:MODEF 0 "register_operand" ""))
13699 (use (match_operand:MODEF 1 "register_operand" ""))]
13700 "TARGET_USE_FANCY_MATH_387
13701 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13702 || TARGET_MIX_SSE_I387)
13703 && flag_unsafe_math_optimizations"
13704 {
13705 rtx op0 = gen_reg_rtx (XFmode);
13706
13707 rtx op2 = gen_reg_rtx (XFmode);
13708 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13709
13710 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13711 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13712 DONE;
13713 })
13714
13715 (define_expand "log2xf2"
13716 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13717 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13718 (match_dup 2)] UNSPEC_FYL2X))
13719 (clobber (match_scratch:XF 3 ""))])]
13720 "TARGET_USE_FANCY_MATH_387
13721 && flag_unsafe_math_optimizations"
13722 {
13723 operands[2] = gen_reg_rtx (XFmode);
13724 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13725 })
13726
13727 (define_expand "log2<mode>2"
13728 [(use (match_operand:MODEF 0 "register_operand" ""))
13729 (use (match_operand:MODEF 1 "register_operand" ""))]
13730 "TARGET_USE_FANCY_MATH_387
13731 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13732 || TARGET_MIX_SSE_I387)
13733 && flag_unsafe_math_optimizations"
13734 {
13735 rtx op0 = gen_reg_rtx (XFmode);
13736
13737 rtx op2 = gen_reg_rtx (XFmode);
13738 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13739
13740 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13741 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13742 DONE;
13743 })
13744
13745 (define_insn "fyl2xp1xf3_i387"
13746 [(set (match_operand:XF 0 "register_operand" "=f")
13747 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13748 (match_operand:XF 2 "register_operand" "u")]
13749 UNSPEC_FYL2XP1))
13750 (clobber (match_scratch:XF 3 "=2"))]
13751 "TARGET_USE_FANCY_MATH_387
13752 && flag_unsafe_math_optimizations"
13753 "fyl2xp1"
13754 [(set_attr "type" "fpspc")
13755 (set_attr "mode" "XF")])
13756
13757 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13758 [(set (match_operand:XF 0 "register_operand" "=f")
13759 (unspec:XF [(float_extend:XF
13760 (match_operand:MODEF 1 "register_operand" "0"))
13761 (match_operand:XF 2 "register_operand" "u")]
13762 UNSPEC_FYL2XP1))
13763 (clobber (match_scratch:XF 3 "=2"))]
13764 "TARGET_USE_FANCY_MATH_387
13765 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13766 || TARGET_MIX_SSE_I387)
13767 && flag_unsafe_math_optimizations"
13768 "fyl2xp1"
13769 [(set_attr "type" "fpspc")
13770 (set_attr "mode" "XF")])
13771
13772 (define_expand "log1pxf2"
13773 [(use (match_operand:XF 0 "register_operand" ""))
13774 (use (match_operand:XF 1 "register_operand" ""))]
13775 "TARGET_USE_FANCY_MATH_387
13776 && flag_unsafe_math_optimizations"
13777 {
13778 if (optimize_insn_for_size_p ())
13779 FAIL;
13780
13781 ix86_emit_i387_log1p (operands[0], operands[1]);
13782 DONE;
13783 })
13784
13785 (define_expand "log1p<mode>2"
13786 [(use (match_operand:MODEF 0 "register_operand" ""))
13787 (use (match_operand:MODEF 1 "register_operand" ""))]
13788 "TARGET_USE_FANCY_MATH_387
13789 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13790 || TARGET_MIX_SSE_I387)
13791 && flag_unsafe_math_optimizations"
13792 {
13793 rtx op0;
13794
13795 if (optimize_insn_for_size_p ())
13796 FAIL;
13797
13798 op0 = gen_reg_rtx (XFmode);
13799
13800 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13801
13802 ix86_emit_i387_log1p (op0, operands[1]);
13803 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13804 DONE;
13805 })
13806
13807 (define_insn "fxtractxf3_i387"
13808 [(set (match_operand:XF 0 "register_operand" "=f")
13809 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13810 UNSPEC_XTRACT_FRACT))
13811 (set (match_operand:XF 1 "register_operand" "=u")
13812 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13813 "TARGET_USE_FANCY_MATH_387
13814 && flag_unsafe_math_optimizations"
13815 "fxtract"
13816 [(set_attr "type" "fpspc")
13817 (set_attr "mode" "XF")])
13818
13819 (define_insn "fxtract_extend<mode>xf3_i387"
13820 [(set (match_operand:XF 0 "register_operand" "=f")
13821 (unspec:XF [(float_extend:XF
13822 (match_operand:MODEF 2 "register_operand" "0"))]
13823 UNSPEC_XTRACT_FRACT))
13824 (set (match_operand:XF 1 "register_operand" "=u")
13825 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13826 "TARGET_USE_FANCY_MATH_387
13827 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13828 || TARGET_MIX_SSE_I387)
13829 && flag_unsafe_math_optimizations"
13830 "fxtract"
13831 [(set_attr "type" "fpspc")
13832 (set_attr "mode" "XF")])
13833
13834 (define_expand "logbxf2"
13835 [(parallel [(set (match_dup 2)
13836 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13837 UNSPEC_XTRACT_FRACT))
13838 (set (match_operand:XF 0 "register_operand" "")
13839 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13840 "TARGET_USE_FANCY_MATH_387
13841 && flag_unsafe_math_optimizations"
13842 "operands[2] = gen_reg_rtx (XFmode);")
13843
13844 (define_expand "logb<mode>2"
13845 [(use (match_operand:MODEF 0 "register_operand" ""))
13846 (use (match_operand:MODEF 1 "register_operand" ""))]
13847 "TARGET_USE_FANCY_MATH_387
13848 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13849 || TARGET_MIX_SSE_I387)
13850 && flag_unsafe_math_optimizations"
13851 {
13852 rtx op0 = gen_reg_rtx (XFmode);
13853 rtx op1 = gen_reg_rtx (XFmode);
13854
13855 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13856 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13857 DONE;
13858 })
13859
13860 (define_expand "ilogbxf2"
13861 [(use (match_operand:SI 0 "register_operand" ""))
13862 (use (match_operand:XF 1 "register_operand" ""))]
13863 "TARGET_USE_FANCY_MATH_387
13864 && flag_unsafe_math_optimizations"
13865 {
13866 rtx op0, op1;
13867
13868 if (optimize_insn_for_size_p ())
13869 FAIL;
13870
13871 op0 = gen_reg_rtx (XFmode);
13872 op1 = gen_reg_rtx (XFmode);
13873
13874 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13875 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13876 DONE;
13877 })
13878
13879 (define_expand "ilogb<mode>2"
13880 [(use (match_operand:SI 0 "register_operand" ""))
13881 (use (match_operand:MODEF 1 "register_operand" ""))]
13882 "TARGET_USE_FANCY_MATH_387
13883 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13884 || TARGET_MIX_SSE_I387)
13885 && flag_unsafe_math_optimizations"
13886 {
13887 rtx op0, op1;
13888
13889 if (optimize_insn_for_size_p ())
13890 FAIL;
13891
13892 op0 = gen_reg_rtx (XFmode);
13893 op1 = gen_reg_rtx (XFmode);
13894
13895 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13896 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13897 DONE;
13898 })
13899
13900 (define_insn "*f2xm1xf2_i387"
13901 [(set (match_operand:XF 0 "register_operand" "=f")
13902 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13903 UNSPEC_F2XM1))]
13904 "TARGET_USE_FANCY_MATH_387
13905 && flag_unsafe_math_optimizations"
13906 "f2xm1"
13907 [(set_attr "type" "fpspc")
13908 (set_attr "mode" "XF")])
13909
13910 (define_insn "*fscalexf4_i387"
13911 [(set (match_operand:XF 0 "register_operand" "=f")
13912 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13913 (match_operand:XF 3 "register_operand" "1")]
13914 UNSPEC_FSCALE_FRACT))
13915 (set (match_operand:XF 1 "register_operand" "=u")
13916 (unspec:XF [(match_dup 2) (match_dup 3)]
13917 UNSPEC_FSCALE_EXP))]
13918 "TARGET_USE_FANCY_MATH_387
13919 && flag_unsafe_math_optimizations"
13920 "fscale"
13921 [(set_attr "type" "fpspc")
13922 (set_attr "mode" "XF")])
13923
13924 (define_expand "expNcorexf3"
13925 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13926 (match_operand:XF 2 "register_operand" "")))
13927 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13928 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13929 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13930 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13931 (parallel [(set (match_operand:XF 0 "register_operand" "")
13932 (unspec:XF [(match_dup 8) (match_dup 4)]
13933 UNSPEC_FSCALE_FRACT))
13934 (set (match_dup 9)
13935 (unspec:XF [(match_dup 8) (match_dup 4)]
13936 UNSPEC_FSCALE_EXP))])]
13937 "TARGET_USE_FANCY_MATH_387
13938 && flag_unsafe_math_optimizations"
13939 {
13940 int i;
13941
13942 if (optimize_insn_for_size_p ())
13943 FAIL;
13944
13945 for (i = 3; i < 10; i++)
13946 operands[i] = gen_reg_rtx (XFmode);
13947
13948 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13949 })
13950
13951 (define_expand "expxf2"
13952 [(use (match_operand:XF 0 "register_operand" ""))
13953 (use (match_operand:XF 1 "register_operand" ""))]
13954 "TARGET_USE_FANCY_MATH_387
13955 && flag_unsafe_math_optimizations"
13956 {
13957 rtx op2;
13958
13959 if (optimize_insn_for_size_p ())
13960 FAIL;
13961
13962 op2 = gen_reg_rtx (XFmode);
13963 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13964
13965 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13966 DONE;
13967 })
13968
13969 (define_expand "exp<mode>2"
13970 [(use (match_operand:MODEF 0 "register_operand" ""))
13971 (use (match_operand:MODEF 1 "general_operand" ""))]
13972 "TARGET_USE_FANCY_MATH_387
13973 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13974 || TARGET_MIX_SSE_I387)
13975 && flag_unsafe_math_optimizations"
13976 {
13977 rtx op0, op1;
13978
13979 if (optimize_insn_for_size_p ())
13980 FAIL;
13981
13982 op0 = gen_reg_rtx (XFmode);
13983 op1 = gen_reg_rtx (XFmode);
13984
13985 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13986 emit_insn (gen_expxf2 (op0, op1));
13987 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13988 DONE;
13989 })
13990
13991 (define_expand "exp10xf2"
13992 [(use (match_operand:XF 0 "register_operand" ""))
13993 (use (match_operand:XF 1 "register_operand" ""))]
13994 "TARGET_USE_FANCY_MATH_387
13995 && flag_unsafe_math_optimizations"
13996 {
13997 rtx op2;
13998
13999 if (optimize_insn_for_size_p ())
14000 FAIL;
14001
14002 op2 = gen_reg_rtx (XFmode);
14003 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14004
14005 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14006 DONE;
14007 })
14008
14009 (define_expand "exp10<mode>2"
14010 [(use (match_operand:MODEF 0 "register_operand" ""))
14011 (use (match_operand:MODEF 1 "general_operand" ""))]
14012 "TARGET_USE_FANCY_MATH_387
14013 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14014 || TARGET_MIX_SSE_I387)
14015 && flag_unsafe_math_optimizations"
14016 {
14017 rtx op0, op1;
14018
14019 if (optimize_insn_for_size_p ())
14020 FAIL;
14021
14022 op0 = gen_reg_rtx (XFmode);
14023 op1 = gen_reg_rtx (XFmode);
14024
14025 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14026 emit_insn (gen_exp10xf2 (op0, op1));
14027 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14028 DONE;
14029 })
14030
14031 (define_expand "exp2xf2"
14032 [(use (match_operand:XF 0 "register_operand" ""))
14033 (use (match_operand:XF 1 "register_operand" ""))]
14034 "TARGET_USE_FANCY_MATH_387
14035 && flag_unsafe_math_optimizations"
14036 {
14037 rtx op2;
14038
14039 if (optimize_insn_for_size_p ())
14040 FAIL;
14041
14042 op2 = gen_reg_rtx (XFmode);
14043 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14044
14045 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14046 DONE;
14047 })
14048
14049 (define_expand "exp2<mode>2"
14050 [(use (match_operand:MODEF 0 "register_operand" ""))
14051 (use (match_operand:MODEF 1 "general_operand" ""))]
14052 "TARGET_USE_FANCY_MATH_387
14053 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14054 || TARGET_MIX_SSE_I387)
14055 && flag_unsafe_math_optimizations"
14056 {
14057 rtx op0, op1;
14058
14059 if (optimize_insn_for_size_p ())
14060 FAIL;
14061
14062 op0 = gen_reg_rtx (XFmode);
14063 op1 = gen_reg_rtx (XFmode);
14064
14065 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14066 emit_insn (gen_exp2xf2 (op0, op1));
14067 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14068 DONE;
14069 })
14070
14071 (define_expand "expm1xf2"
14072 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14073 (match_dup 2)))
14074 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14075 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14076 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14077 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14078 (parallel [(set (match_dup 7)
14079 (unspec:XF [(match_dup 6) (match_dup 4)]
14080 UNSPEC_FSCALE_FRACT))
14081 (set (match_dup 8)
14082 (unspec:XF [(match_dup 6) (match_dup 4)]
14083 UNSPEC_FSCALE_EXP))])
14084 (parallel [(set (match_dup 10)
14085 (unspec:XF [(match_dup 9) (match_dup 8)]
14086 UNSPEC_FSCALE_FRACT))
14087 (set (match_dup 11)
14088 (unspec:XF [(match_dup 9) (match_dup 8)]
14089 UNSPEC_FSCALE_EXP))])
14090 (set (match_dup 12) (minus:XF (match_dup 10)
14091 (float_extend:XF (match_dup 13))))
14092 (set (match_operand:XF 0 "register_operand" "")
14093 (plus:XF (match_dup 12) (match_dup 7)))]
14094 "TARGET_USE_FANCY_MATH_387
14095 && flag_unsafe_math_optimizations"
14096 {
14097 int i;
14098
14099 if (optimize_insn_for_size_p ())
14100 FAIL;
14101
14102 for (i = 2; i < 13; i++)
14103 operands[i] = gen_reg_rtx (XFmode);
14104
14105 operands[13]
14106 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14107
14108 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14109 })
14110
14111 (define_expand "expm1<mode>2"
14112 [(use (match_operand:MODEF 0 "register_operand" ""))
14113 (use (match_operand:MODEF 1 "general_operand" ""))]
14114 "TARGET_USE_FANCY_MATH_387
14115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14116 || TARGET_MIX_SSE_I387)
14117 && flag_unsafe_math_optimizations"
14118 {
14119 rtx op0, op1;
14120
14121 if (optimize_insn_for_size_p ())
14122 FAIL;
14123
14124 op0 = gen_reg_rtx (XFmode);
14125 op1 = gen_reg_rtx (XFmode);
14126
14127 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14128 emit_insn (gen_expm1xf2 (op0, op1));
14129 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14130 DONE;
14131 })
14132
14133 (define_expand "ldexpxf3"
14134 [(set (match_dup 3)
14135 (float:XF (match_operand:SI 2 "register_operand" "")))
14136 (parallel [(set (match_operand:XF 0 " register_operand" "")
14137 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14138 (match_dup 3)]
14139 UNSPEC_FSCALE_FRACT))
14140 (set (match_dup 4)
14141 (unspec:XF [(match_dup 1) (match_dup 3)]
14142 UNSPEC_FSCALE_EXP))])]
14143 "TARGET_USE_FANCY_MATH_387
14144 && flag_unsafe_math_optimizations"
14145 {
14146 if (optimize_insn_for_size_p ())
14147 FAIL;
14148
14149 operands[3] = gen_reg_rtx (XFmode);
14150 operands[4] = gen_reg_rtx (XFmode);
14151 })
14152
14153 (define_expand "ldexp<mode>3"
14154 [(use (match_operand:MODEF 0 "register_operand" ""))
14155 (use (match_operand:MODEF 1 "general_operand" ""))
14156 (use (match_operand:SI 2 "register_operand" ""))]
14157 "TARGET_USE_FANCY_MATH_387
14158 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14159 || TARGET_MIX_SSE_I387)
14160 && flag_unsafe_math_optimizations"
14161 {
14162 rtx op0, op1;
14163
14164 if (optimize_insn_for_size_p ())
14165 FAIL;
14166
14167 op0 = gen_reg_rtx (XFmode);
14168 op1 = gen_reg_rtx (XFmode);
14169
14170 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14171 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14172 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14173 DONE;
14174 })
14175
14176 (define_expand "scalbxf3"
14177 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14178 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14179 (match_operand:XF 2 "register_operand" "")]
14180 UNSPEC_FSCALE_FRACT))
14181 (set (match_dup 3)
14182 (unspec:XF [(match_dup 1) (match_dup 2)]
14183 UNSPEC_FSCALE_EXP))])]
14184 "TARGET_USE_FANCY_MATH_387
14185 && flag_unsafe_math_optimizations"
14186 {
14187 if (optimize_insn_for_size_p ())
14188 FAIL;
14189
14190 operands[3] = gen_reg_rtx (XFmode);
14191 })
14192
14193 (define_expand "scalb<mode>3"
14194 [(use (match_operand:MODEF 0 "register_operand" ""))
14195 (use (match_operand:MODEF 1 "general_operand" ""))
14196 (use (match_operand:MODEF 2 "general_operand" ""))]
14197 "TARGET_USE_FANCY_MATH_387
14198 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14199 || TARGET_MIX_SSE_I387)
14200 && flag_unsafe_math_optimizations"
14201 {
14202 rtx op0, op1, op2;
14203
14204 if (optimize_insn_for_size_p ())
14205 FAIL;
14206
14207 op0 = gen_reg_rtx (XFmode);
14208 op1 = gen_reg_rtx (XFmode);
14209 op2 = gen_reg_rtx (XFmode);
14210
14211 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14212 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14213 emit_insn (gen_scalbxf3 (op0, op1, op2));
14214 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14215 DONE;
14216 })
14217
14218 (define_expand "significandxf2"
14219 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14220 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14221 UNSPEC_XTRACT_FRACT))
14222 (set (match_dup 2)
14223 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14224 "TARGET_USE_FANCY_MATH_387
14225 && flag_unsafe_math_optimizations"
14226 "operands[2] = gen_reg_rtx (XFmode);")
14227
14228 (define_expand "significand<mode>2"
14229 [(use (match_operand:MODEF 0 "register_operand" ""))
14230 (use (match_operand:MODEF 1 "register_operand" ""))]
14231 "TARGET_USE_FANCY_MATH_387
14232 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14233 || TARGET_MIX_SSE_I387)
14234 && flag_unsafe_math_optimizations"
14235 {
14236 rtx op0 = gen_reg_rtx (XFmode);
14237 rtx op1 = gen_reg_rtx (XFmode);
14238
14239 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14240 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14241 DONE;
14242 })
14243 \f
14244
14245 (define_insn "sse4_1_round<mode>2"
14246 [(set (match_operand:MODEF 0 "register_operand" "=x")
14247 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14248 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14249 UNSPEC_ROUND))]
14250 "TARGET_ROUND"
14251 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14252 [(set_attr "type" "ssecvt")
14253 (set_attr "prefix_extra" "1")
14254 (set_attr "prefix" "maybe_vex")
14255 (set_attr "mode" "<MODE>")])
14256
14257 (define_insn "rintxf2"
14258 [(set (match_operand:XF 0 "register_operand" "=f")
14259 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14260 UNSPEC_FRNDINT))]
14261 "TARGET_USE_FANCY_MATH_387
14262 && flag_unsafe_math_optimizations"
14263 "frndint"
14264 [(set_attr "type" "fpspc")
14265 (set_attr "mode" "XF")])
14266
14267 (define_expand "rint<mode>2"
14268 [(use (match_operand:MODEF 0 "register_operand" ""))
14269 (use (match_operand:MODEF 1 "register_operand" ""))]
14270 "(TARGET_USE_FANCY_MATH_387
14271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14272 || TARGET_MIX_SSE_I387)
14273 && flag_unsafe_math_optimizations)
14274 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14275 && !flag_trapping_math)"
14276 {
14277 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14278 && !flag_trapping_math)
14279 {
14280 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14281 FAIL;
14282 if (TARGET_ROUND)
14283 emit_insn (gen_sse4_1_round<mode>2
14284 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14285 else
14286 ix86_expand_rint (operand0, operand1);
14287 }
14288 else
14289 {
14290 rtx op0 = gen_reg_rtx (XFmode);
14291 rtx op1 = gen_reg_rtx (XFmode);
14292
14293 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14294 emit_insn (gen_rintxf2 (op0, op1));
14295
14296 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14297 }
14298 DONE;
14299 })
14300
14301 (define_expand "round<mode>2"
14302 [(match_operand:MODEF 0 "register_operand" "")
14303 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14304 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14305 && !flag_trapping_math && !flag_rounding_math"
14306 {
14307 if (optimize_insn_for_size_p ())
14308 FAIL;
14309 if (TARGET_64BIT || (<MODE>mode != DFmode))
14310 ix86_expand_round (operand0, operand1);
14311 else
14312 ix86_expand_rounddf_32 (operand0, operand1);
14313 DONE;
14314 })
14315
14316 (define_insn_and_split "*fistdi2_1"
14317 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14318 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14319 UNSPEC_FIST))]
14320 "TARGET_USE_FANCY_MATH_387
14321 && can_create_pseudo_p ()"
14322 "#"
14323 "&& 1"
14324 [(const_int 0)]
14325 {
14326 if (memory_operand (operands[0], VOIDmode))
14327 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14328 else
14329 {
14330 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14331 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14332 operands[2]));
14333 }
14334 DONE;
14335 }
14336 [(set_attr "type" "fpspc")
14337 (set_attr "mode" "DI")])
14338
14339 (define_insn "fistdi2"
14340 [(set (match_operand:DI 0 "memory_operand" "=m")
14341 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14342 UNSPEC_FIST))
14343 (clobber (match_scratch:XF 2 "=&1f"))]
14344 "TARGET_USE_FANCY_MATH_387"
14345 "* return output_fix_trunc (insn, operands, false);"
14346 [(set_attr "type" "fpspc")
14347 (set_attr "mode" "DI")])
14348
14349 (define_insn "fistdi2_with_temp"
14350 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14351 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14352 UNSPEC_FIST))
14353 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14354 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14355 "TARGET_USE_FANCY_MATH_387"
14356 "#"
14357 [(set_attr "type" "fpspc")
14358 (set_attr "mode" "DI")])
14359
14360 (define_split
14361 [(set (match_operand:DI 0 "register_operand" "")
14362 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14363 UNSPEC_FIST))
14364 (clobber (match_operand:DI 2 "memory_operand" ""))
14365 (clobber (match_scratch 3 ""))]
14366 "reload_completed"
14367 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14368 (clobber (match_dup 3))])
14369 (set (match_dup 0) (match_dup 2))])
14370
14371 (define_split
14372 [(set (match_operand:DI 0 "memory_operand" "")
14373 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14374 UNSPEC_FIST))
14375 (clobber (match_operand:DI 2 "memory_operand" ""))
14376 (clobber (match_scratch 3 ""))]
14377 "reload_completed"
14378 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14379 (clobber (match_dup 3))])])
14380
14381 (define_insn_and_split "*fist<mode>2_1"
14382 [(set (match_operand:SWI24 0 "register_operand" "")
14383 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14384 UNSPEC_FIST))]
14385 "TARGET_USE_FANCY_MATH_387
14386 && can_create_pseudo_p ()"
14387 "#"
14388 "&& 1"
14389 [(const_int 0)]
14390 {
14391 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14392 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14393 operands[2]));
14394 DONE;
14395 }
14396 [(set_attr "type" "fpspc")
14397 (set_attr "mode" "<MODE>")])
14398
14399 (define_insn "fist<mode>2"
14400 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14401 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14402 UNSPEC_FIST))]
14403 "TARGET_USE_FANCY_MATH_387"
14404 "* return output_fix_trunc (insn, operands, false);"
14405 [(set_attr "type" "fpspc")
14406 (set_attr "mode" "<MODE>")])
14407
14408 (define_insn "fist<mode>2_with_temp"
14409 [(set (match_operand:SWI24 0 "register_operand" "=r")
14410 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14411 UNSPEC_FIST))
14412 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14413 "TARGET_USE_FANCY_MATH_387"
14414 "#"
14415 [(set_attr "type" "fpspc")
14416 (set_attr "mode" "<MODE>")])
14417
14418 (define_split
14419 [(set (match_operand:SWI24 0 "register_operand" "")
14420 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14421 UNSPEC_FIST))
14422 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14423 "reload_completed"
14424 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14425 (set (match_dup 0) (match_dup 2))])
14426
14427 (define_split
14428 [(set (match_operand:SWI24 0 "memory_operand" "")
14429 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14430 UNSPEC_FIST))
14431 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14432 "reload_completed"
14433 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14434
14435 (define_expand "lrintxf<mode>2"
14436 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14437 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14438 UNSPEC_FIST))]
14439 "TARGET_USE_FANCY_MATH_387")
14440
14441 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14442 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14443 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14444 UNSPEC_FIX_NOTRUNC))]
14445 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14446 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14447
14448 (define_expand "lround<MODEF:mode><SWI48x:mode>2"
14449 [(match_operand:SWI48x 0 "nonimmediate_operand" "")
14450 (match_operand:MODEF 1 "register_operand" "")]
14451 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14452 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)
14453 && !flag_trapping_math && !flag_rounding_math"
14454 {
14455 if (optimize_insn_for_size_p ())
14456 FAIL;
14457 ix86_expand_lround (operand0, operand1);
14458 DONE;
14459 })
14460
14461 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14462 (define_insn_and_split "frndintxf2_floor"
14463 [(set (match_operand:XF 0 "register_operand" "")
14464 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14465 UNSPEC_FRNDINT_FLOOR))
14466 (clobber (reg:CC FLAGS_REG))]
14467 "TARGET_USE_FANCY_MATH_387
14468 && flag_unsafe_math_optimizations
14469 && can_create_pseudo_p ()"
14470 "#"
14471 "&& 1"
14472 [(const_int 0)]
14473 {
14474 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14475
14476 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14477 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14478
14479 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14480 operands[2], operands[3]));
14481 DONE;
14482 }
14483 [(set_attr "type" "frndint")
14484 (set_attr "i387_cw" "floor")
14485 (set_attr "mode" "XF")])
14486
14487 (define_insn "frndintxf2_floor_i387"
14488 [(set (match_operand:XF 0 "register_operand" "=f")
14489 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14490 UNSPEC_FRNDINT_FLOOR))
14491 (use (match_operand:HI 2 "memory_operand" "m"))
14492 (use (match_operand:HI 3 "memory_operand" "m"))]
14493 "TARGET_USE_FANCY_MATH_387
14494 && flag_unsafe_math_optimizations"
14495 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14496 [(set_attr "type" "frndint")
14497 (set_attr "i387_cw" "floor")
14498 (set_attr "mode" "XF")])
14499
14500 (define_expand "floorxf2"
14501 [(use (match_operand:XF 0 "register_operand" ""))
14502 (use (match_operand:XF 1 "register_operand" ""))]
14503 "TARGET_USE_FANCY_MATH_387
14504 && flag_unsafe_math_optimizations"
14505 {
14506 if (optimize_insn_for_size_p ())
14507 FAIL;
14508 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14509 DONE;
14510 })
14511
14512 (define_expand "floor<mode>2"
14513 [(use (match_operand:MODEF 0 "register_operand" ""))
14514 (use (match_operand:MODEF 1 "register_operand" ""))]
14515 "(TARGET_USE_FANCY_MATH_387
14516 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14517 || TARGET_MIX_SSE_I387)
14518 && flag_unsafe_math_optimizations)
14519 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14520 && !flag_trapping_math)"
14521 {
14522 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14523 && !flag_trapping_math
14524 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14525 {
14526 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14527 FAIL;
14528 if (TARGET_ROUND)
14529 emit_insn (gen_sse4_1_round<mode>2
14530 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14531 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14532 ix86_expand_floorceil (operand0, operand1, true);
14533 else
14534 ix86_expand_floorceildf_32 (operand0, operand1, true);
14535 }
14536 else
14537 {
14538 rtx op0, op1;
14539
14540 if (optimize_insn_for_size_p ())
14541 FAIL;
14542
14543 op0 = gen_reg_rtx (XFmode);
14544 op1 = gen_reg_rtx (XFmode);
14545 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14546 emit_insn (gen_frndintxf2_floor (op0, op1));
14547
14548 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14549 }
14550 DONE;
14551 })
14552
14553 (define_insn_and_split "*fist<mode>2_floor_1"
14554 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14555 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14556 UNSPEC_FIST_FLOOR))
14557 (clobber (reg:CC FLAGS_REG))]
14558 "TARGET_USE_FANCY_MATH_387
14559 && flag_unsafe_math_optimizations
14560 && can_create_pseudo_p ()"
14561 "#"
14562 "&& 1"
14563 [(const_int 0)]
14564 {
14565 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14566
14567 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14568 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14569 if (memory_operand (operands[0], VOIDmode))
14570 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14571 operands[2], operands[3]));
14572 else
14573 {
14574 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14575 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14576 operands[2], operands[3],
14577 operands[4]));
14578 }
14579 DONE;
14580 }
14581 [(set_attr "type" "fistp")
14582 (set_attr "i387_cw" "floor")
14583 (set_attr "mode" "<MODE>")])
14584
14585 (define_insn "fistdi2_floor"
14586 [(set (match_operand:DI 0 "memory_operand" "=m")
14587 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14588 UNSPEC_FIST_FLOOR))
14589 (use (match_operand:HI 2 "memory_operand" "m"))
14590 (use (match_operand:HI 3 "memory_operand" "m"))
14591 (clobber (match_scratch:XF 4 "=&1f"))]
14592 "TARGET_USE_FANCY_MATH_387
14593 && flag_unsafe_math_optimizations"
14594 "* return output_fix_trunc (insn, operands, false);"
14595 [(set_attr "type" "fistp")
14596 (set_attr "i387_cw" "floor")
14597 (set_attr "mode" "DI")])
14598
14599 (define_insn "fistdi2_floor_with_temp"
14600 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14601 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14602 UNSPEC_FIST_FLOOR))
14603 (use (match_operand:HI 2 "memory_operand" "m,m"))
14604 (use (match_operand:HI 3 "memory_operand" "m,m"))
14605 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14606 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14607 "TARGET_USE_FANCY_MATH_387
14608 && flag_unsafe_math_optimizations"
14609 "#"
14610 [(set_attr "type" "fistp")
14611 (set_attr "i387_cw" "floor")
14612 (set_attr "mode" "DI")])
14613
14614 (define_split
14615 [(set (match_operand:DI 0 "register_operand" "")
14616 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14617 UNSPEC_FIST_FLOOR))
14618 (use (match_operand:HI 2 "memory_operand" ""))
14619 (use (match_operand:HI 3 "memory_operand" ""))
14620 (clobber (match_operand:DI 4 "memory_operand" ""))
14621 (clobber (match_scratch 5 ""))]
14622 "reload_completed"
14623 [(parallel [(set (match_dup 4)
14624 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14625 (use (match_dup 2))
14626 (use (match_dup 3))
14627 (clobber (match_dup 5))])
14628 (set (match_dup 0) (match_dup 4))])
14629
14630 (define_split
14631 [(set (match_operand:DI 0 "memory_operand" "")
14632 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14633 UNSPEC_FIST_FLOOR))
14634 (use (match_operand:HI 2 "memory_operand" ""))
14635 (use (match_operand:HI 3 "memory_operand" ""))
14636 (clobber (match_operand:DI 4 "memory_operand" ""))
14637 (clobber (match_scratch 5 ""))]
14638 "reload_completed"
14639 [(parallel [(set (match_dup 0)
14640 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14641 (use (match_dup 2))
14642 (use (match_dup 3))
14643 (clobber (match_dup 5))])])
14644
14645 (define_insn "fist<mode>2_floor"
14646 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14647 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14648 UNSPEC_FIST_FLOOR))
14649 (use (match_operand:HI 2 "memory_operand" "m"))
14650 (use (match_operand:HI 3 "memory_operand" "m"))]
14651 "TARGET_USE_FANCY_MATH_387
14652 && flag_unsafe_math_optimizations"
14653 "* return output_fix_trunc (insn, operands, false);"
14654 [(set_attr "type" "fistp")
14655 (set_attr "i387_cw" "floor")
14656 (set_attr "mode" "<MODE>")])
14657
14658 (define_insn "fist<mode>2_floor_with_temp"
14659 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14660 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14661 UNSPEC_FIST_FLOOR))
14662 (use (match_operand:HI 2 "memory_operand" "m,m"))
14663 (use (match_operand:HI 3 "memory_operand" "m,m"))
14664 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14665 "TARGET_USE_FANCY_MATH_387
14666 && flag_unsafe_math_optimizations"
14667 "#"
14668 [(set_attr "type" "fistp")
14669 (set_attr "i387_cw" "floor")
14670 (set_attr "mode" "<MODE>")])
14671
14672 (define_split
14673 [(set (match_operand:SWI24 0 "register_operand" "")
14674 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14675 UNSPEC_FIST_FLOOR))
14676 (use (match_operand:HI 2 "memory_operand" ""))
14677 (use (match_operand:HI 3 "memory_operand" ""))
14678 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14679 "reload_completed"
14680 [(parallel [(set (match_dup 4)
14681 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14682 (use (match_dup 2))
14683 (use (match_dup 3))])
14684 (set (match_dup 0) (match_dup 4))])
14685
14686 (define_split
14687 [(set (match_operand:SWI24 0 "memory_operand" "")
14688 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14689 UNSPEC_FIST_FLOOR))
14690 (use (match_operand:HI 2 "memory_operand" ""))
14691 (use (match_operand:HI 3 "memory_operand" ""))
14692 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14693 "reload_completed"
14694 [(parallel [(set (match_dup 0)
14695 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14696 (use (match_dup 2))
14697 (use (match_dup 3))])])
14698
14699 (define_expand "lfloorxf<mode>2"
14700 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14701 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14702 UNSPEC_FIST_FLOOR))
14703 (clobber (reg:CC FLAGS_REG))])]
14704 "TARGET_USE_FANCY_MATH_387
14705 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14706 && flag_unsafe_math_optimizations")
14707
14708 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14709 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14710 (match_operand:MODEF 1 "register_operand" "")]
14711 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14712 && !flag_trapping_math"
14713 {
14714 if (TARGET_64BIT && optimize_insn_for_size_p ())
14715 FAIL;
14716 ix86_expand_lfloorceil (operand0, operand1, true);
14717 DONE;
14718 })
14719
14720 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14721 (define_insn_and_split "frndintxf2_ceil"
14722 [(set (match_operand:XF 0 "register_operand" "")
14723 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14724 UNSPEC_FRNDINT_CEIL))
14725 (clobber (reg:CC FLAGS_REG))]
14726 "TARGET_USE_FANCY_MATH_387
14727 && flag_unsafe_math_optimizations
14728 && can_create_pseudo_p ()"
14729 "#"
14730 "&& 1"
14731 [(const_int 0)]
14732 {
14733 ix86_optimize_mode_switching[I387_CEIL] = 1;
14734
14735 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14736 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14737
14738 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14739 operands[2], operands[3]));
14740 DONE;
14741 }
14742 [(set_attr "type" "frndint")
14743 (set_attr "i387_cw" "ceil")
14744 (set_attr "mode" "XF")])
14745
14746 (define_insn "frndintxf2_ceil_i387"
14747 [(set (match_operand:XF 0 "register_operand" "=f")
14748 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14749 UNSPEC_FRNDINT_CEIL))
14750 (use (match_operand:HI 2 "memory_operand" "m"))
14751 (use (match_operand:HI 3 "memory_operand" "m"))]
14752 "TARGET_USE_FANCY_MATH_387
14753 && flag_unsafe_math_optimizations"
14754 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14755 [(set_attr "type" "frndint")
14756 (set_attr "i387_cw" "ceil")
14757 (set_attr "mode" "XF")])
14758
14759 (define_expand "ceilxf2"
14760 [(use (match_operand:XF 0 "register_operand" ""))
14761 (use (match_operand:XF 1 "register_operand" ""))]
14762 "TARGET_USE_FANCY_MATH_387
14763 && flag_unsafe_math_optimizations"
14764 {
14765 if (optimize_insn_for_size_p ())
14766 FAIL;
14767 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14768 DONE;
14769 })
14770
14771 (define_expand "ceil<mode>2"
14772 [(use (match_operand:MODEF 0 "register_operand" ""))
14773 (use (match_operand:MODEF 1 "register_operand" ""))]
14774 "(TARGET_USE_FANCY_MATH_387
14775 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14776 || TARGET_MIX_SSE_I387)
14777 && flag_unsafe_math_optimizations)
14778 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14779 && !flag_trapping_math)"
14780 {
14781 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14782 && !flag_trapping_math
14783 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14784 {
14785 if (TARGET_ROUND)
14786 emit_insn (gen_sse4_1_round<mode>2
14787 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14788 else if (optimize_insn_for_size_p ())
14789 FAIL;
14790 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14791 ix86_expand_floorceil (operand0, operand1, false);
14792 else
14793 ix86_expand_floorceildf_32 (operand0, operand1, false);
14794 }
14795 else
14796 {
14797 rtx op0, op1;
14798
14799 if (optimize_insn_for_size_p ())
14800 FAIL;
14801
14802 op0 = gen_reg_rtx (XFmode);
14803 op1 = gen_reg_rtx (XFmode);
14804 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14805 emit_insn (gen_frndintxf2_ceil (op0, op1));
14806
14807 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14808 }
14809 DONE;
14810 })
14811
14812 (define_insn_and_split "*fist<mode>2_ceil_1"
14813 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14814 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14815 UNSPEC_FIST_CEIL))
14816 (clobber (reg:CC FLAGS_REG))]
14817 "TARGET_USE_FANCY_MATH_387
14818 && flag_unsafe_math_optimizations
14819 && can_create_pseudo_p ()"
14820 "#"
14821 "&& 1"
14822 [(const_int 0)]
14823 {
14824 ix86_optimize_mode_switching[I387_CEIL] = 1;
14825
14826 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14827 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14828 if (memory_operand (operands[0], VOIDmode))
14829 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14830 operands[2], operands[3]));
14831 else
14832 {
14833 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14834 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14835 operands[2], operands[3],
14836 operands[4]));
14837 }
14838 DONE;
14839 }
14840 [(set_attr "type" "fistp")
14841 (set_attr "i387_cw" "ceil")
14842 (set_attr "mode" "<MODE>")])
14843
14844 (define_insn "fistdi2_ceil"
14845 [(set (match_operand:DI 0 "memory_operand" "=m")
14846 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14847 UNSPEC_FIST_CEIL))
14848 (use (match_operand:HI 2 "memory_operand" "m"))
14849 (use (match_operand:HI 3 "memory_operand" "m"))
14850 (clobber (match_scratch:XF 4 "=&1f"))]
14851 "TARGET_USE_FANCY_MATH_387
14852 && flag_unsafe_math_optimizations"
14853 "* return output_fix_trunc (insn, operands, false);"
14854 [(set_attr "type" "fistp")
14855 (set_attr "i387_cw" "ceil")
14856 (set_attr "mode" "DI")])
14857
14858 (define_insn "fistdi2_ceil_with_temp"
14859 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14860 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14861 UNSPEC_FIST_CEIL))
14862 (use (match_operand:HI 2 "memory_operand" "m,m"))
14863 (use (match_operand:HI 3 "memory_operand" "m,m"))
14864 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14865 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14866 "TARGET_USE_FANCY_MATH_387
14867 && flag_unsafe_math_optimizations"
14868 "#"
14869 [(set_attr "type" "fistp")
14870 (set_attr "i387_cw" "ceil")
14871 (set_attr "mode" "DI")])
14872
14873 (define_split
14874 [(set (match_operand:DI 0 "register_operand" "")
14875 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14876 UNSPEC_FIST_CEIL))
14877 (use (match_operand:HI 2 "memory_operand" ""))
14878 (use (match_operand:HI 3 "memory_operand" ""))
14879 (clobber (match_operand:DI 4 "memory_operand" ""))
14880 (clobber (match_scratch 5 ""))]
14881 "reload_completed"
14882 [(parallel [(set (match_dup 4)
14883 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14884 (use (match_dup 2))
14885 (use (match_dup 3))
14886 (clobber (match_dup 5))])
14887 (set (match_dup 0) (match_dup 4))])
14888
14889 (define_split
14890 [(set (match_operand:DI 0 "memory_operand" "")
14891 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14892 UNSPEC_FIST_CEIL))
14893 (use (match_operand:HI 2 "memory_operand" ""))
14894 (use (match_operand:HI 3 "memory_operand" ""))
14895 (clobber (match_operand:DI 4 "memory_operand" ""))
14896 (clobber (match_scratch 5 ""))]
14897 "reload_completed"
14898 [(parallel [(set (match_dup 0)
14899 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14900 (use (match_dup 2))
14901 (use (match_dup 3))
14902 (clobber (match_dup 5))])])
14903
14904 (define_insn "fist<mode>2_ceil"
14905 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14906 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14907 UNSPEC_FIST_CEIL))
14908 (use (match_operand:HI 2 "memory_operand" "m"))
14909 (use (match_operand:HI 3 "memory_operand" "m"))]
14910 "TARGET_USE_FANCY_MATH_387
14911 && flag_unsafe_math_optimizations"
14912 "* return output_fix_trunc (insn, operands, false);"
14913 [(set_attr "type" "fistp")
14914 (set_attr "i387_cw" "ceil")
14915 (set_attr "mode" "<MODE>")])
14916
14917 (define_insn "fist<mode>2_ceil_with_temp"
14918 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14919 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14920 UNSPEC_FIST_CEIL))
14921 (use (match_operand:HI 2 "memory_operand" "m,m"))
14922 (use (match_operand:HI 3 "memory_operand" "m,m"))
14923 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14924 "TARGET_USE_FANCY_MATH_387
14925 && flag_unsafe_math_optimizations"
14926 "#"
14927 [(set_attr "type" "fistp")
14928 (set_attr "i387_cw" "ceil")
14929 (set_attr "mode" "<MODE>")])
14930
14931 (define_split
14932 [(set (match_operand:SWI24 0 "register_operand" "")
14933 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14934 UNSPEC_FIST_CEIL))
14935 (use (match_operand:HI 2 "memory_operand" ""))
14936 (use (match_operand:HI 3 "memory_operand" ""))
14937 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14938 "reload_completed"
14939 [(parallel [(set (match_dup 4)
14940 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
14941 (use (match_dup 2))
14942 (use (match_dup 3))])
14943 (set (match_dup 0) (match_dup 4))])
14944
14945 (define_split
14946 [(set (match_operand:SWI24 0 "memory_operand" "")
14947 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14948 UNSPEC_FIST_CEIL))
14949 (use (match_operand:HI 2 "memory_operand" ""))
14950 (use (match_operand:HI 3 "memory_operand" ""))
14951 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14952 "reload_completed"
14953 [(parallel [(set (match_dup 0)
14954 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
14955 (use (match_dup 2))
14956 (use (match_dup 3))])])
14957
14958 (define_expand "lceilxf<mode>2"
14959 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14960 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14961 UNSPEC_FIST_CEIL))
14962 (clobber (reg:CC FLAGS_REG))])]
14963 "TARGET_USE_FANCY_MATH_387
14964 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14965 && flag_unsafe_math_optimizations")
14966
14967 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14968 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14969 (match_operand:MODEF 1 "register_operand" "")]
14970 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14971 && !flag_trapping_math"
14972 {
14973 ix86_expand_lfloorceil (operand0, operand1, false);
14974 DONE;
14975 })
14976
14977 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14978 (define_insn_and_split "frndintxf2_trunc"
14979 [(set (match_operand:XF 0 "register_operand" "")
14980 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14981 UNSPEC_FRNDINT_TRUNC))
14982 (clobber (reg:CC FLAGS_REG))]
14983 "TARGET_USE_FANCY_MATH_387
14984 && flag_unsafe_math_optimizations
14985 && can_create_pseudo_p ()"
14986 "#"
14987 "&& 1"
14988 [(const_int 0)]
14989 {
14990 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14991
14992 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14993 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14994
14995 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14996 operands[2], operands[3]));
14997 DONE;
14998 }
14999 [(set_attr "type" "frndint")
15000 (set_attr "i387_cw" "trunc")
15001 (set_attr "mode" "XF")])
15002
15003 (define_insn "frndintxf2_trunc_i387"
15004 [(set (match_operand:XF 0 "register_operand" "=f")
15005 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15006 UNSPEC_FRNDINT_TRUNC))
15007 (use (match_operand:HI 2 "memory_operand" "m"))
15008 (use (match_operand:HI 3 "memory_operand" "m"))]
15009 "TARGET_USE_FANCY_MATH_387
15010 && flag_unsafe_math_optimizations"
15011 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15012 [(set_attr "type" "frndint")
15013 (set_attr "i387_cw" "trunc")
15014 (set_attr "mode" "XF")])
15015
15016 (define_expand "btruncxf2"
15017 [(use (match_operand:XF 0 "register_operand" ""))
15018 (use (match_operand:XF 1 "register_operand" ""))]
15019 "TARGET_USE_FANCY_MATH_387
15020 && flag_unsafe_math_optimizations"
15021 {
15022 if (optimize_insn_for_size_p ())
15023 FAIL;
15024 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15025 DONE;
15026 })
15027
15028 (define_expand "btrunc<mode>2"
15029 [(use (match_operand:MODEF 0 "register_operand" ""))
15030 (use (match_operand:MODEF 1 "register_operand" ""))]
15031 "(TARGET_USE_FANCY_MATH_387
15032 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15033 || TARGET_MIX_SSE_I387)
15034 && flag_unsafe_math_optimizations)
15035 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15036 && !flag_trapping_math)"
15037 {
15038 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15039 && !flag_trapping_math
15040 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15041 {
15042 if (TARGET_ROUND)
15043 emit_insn (gen_sse4_1_round<mode>2
15044 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15045 else if (optimize_insn_for_size_p ())
15046 FAIL;
15047 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15048 ix86_expand_trunc (operand0, operand1);
15049 else
15050 ix86_expand_truncdf_32 (operand0, operand1);
15051 }
15052 else
15053 {
15054 rtx op0, op1;
15055
15056 if (optimize_insn_for_size_p ())
15057 FAIL;
15058
15059 op0 = gen_reg_rtx (XFmode);
15060 op1 = gen_reg_rtx (XFmode);
15061 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15062 emit_insn (gen_frndintxf2_trunc (op0, op1));
15063
15064 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15065 }
15066 DONE;
15067 })
15068
15069 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15070 (define_insn_and_split "frndintxf2_mask_pm"
15071 [(set (match_operand:XF 0 "register_operand" "")
15072 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15073 UNSPEC_FRNDINT_MASK_PM))
15074 (clobber (reg:CC FLAGS_REG))]
15075 "TARGET_USE_FANCY_MATH_387
15076 && flag_unsafe_math_optimizations
15077 && can_create_pseudo_p ()"
15078 "#"
15079 "&& 1"
15080 [(const_int 0)]
15081 {
15082 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15083
15084 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15085 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15086
15087 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15088 operands[2], operands[3]));
15089 DONE;
15090 }
15091 [(set_attr "type" "frndint")
15092 (set_attr "i387_cw" "mask_pm")
15093 (set_attr "mode" "XF")])
15094
15095 (define_insn "frndintxf2_mask_pm_i387"
15096 [(set (match_operand:XF 0 "register_operand" "=f")
15097 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15098 UNSPEC_FRNDINT_MASK_PM))
15099 (use (match_operand:HI 2 "memory_operand" "m"))
15100 (use (match_operand:HI 3 "memory_operand" "m"))]
15101 "TARGET_USE_FANCY_MATH_387
15102 && flag_unsafe_math_optimizations"
15103 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15104 [(set_attr "type" "frndint")
15105 (set_attr "i387_cw" "mask_pm")
15106 (set_attr "mode" "XF")])
15107
15108 (define_expand "nearbyintxf2"
15109 [(use (match_operand:XF 0 "register_operand" ""))
15110 (use (match_operand:XF 1 "register_operand" ""))]
15111 "TARGET_USE_FANCY_MATH_387
15112 && flag_unsafe_math_optimizations"
15113 {
15114 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15115 DONE;
15116 })
15117
15118 (define_expand "nearbyint<mode>2"
15119 [(use (match_operand:MODEF 0 "register_operand" ""))
15120 (use (match_operand:MODEF 1 "register_operand" ""))]
15121 "TARGET_USE_FANCY_MATH_387
15122 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15123 || TARGET_MIX_SSE_I387)
15124 && flag_unsafe_math_optimizations"
15125 {
15126 rtx op0 = gen_reg_rtx (XFmode);
15127 rtx op1 = gen_reg_rtx (XFmode);
15128
15129 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15130 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15131
15132 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15133 DONE;
15134 })
15135
15136 (define_insn "fxam<mode>2_i387"
15137 [(set (match_operand:HI 0 "register_operand" "=a")
15138 (unspec:HI
15139 [(match_operand:X87MODEF 1 "register_operand" "f")]
15140 UNSPEC_FXAM))]
15141 "TARGET_USE_FANCY_MATH_387"
15142 "fxam\n\tfnstsw\t%0"
15143 [(set_attr "type" "multi")
15144 (set_attr "length" "4")
15145 (set_attr "unit" "i387")
15146 (set_attr "mode" "<MODE>")])
15147
15148 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15149 [(set (match_operand:HI 0 "register_operand" "")
15150 (unspec:HI
15151 [(match_operand:MODEF 1 "memory_operand" "")]
15152 UNSPEC_FXAM_MEM))]
15153 "TARGET_USE_FANCY_MATH_387
15154 && can_create_pseudo_p ()"
15155 "#"
15156 "&& 1"
15157 [(set (match_dup 2)(match_dup 1))
15158 (set (match_dup 0)
15159 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15160 {
15161 operands[2] = gen_reg_rtx (<MODE>mode);
15162
15163 MEM_VOLATILE_P (operands[1]) = 1;
15164 }
15165 [(set_attr "type" "multi")
15166 (set_attr "unit" "i387")
15167 (set_attr "mode" "<MODE>")])
15168
15169 (define_expand "isinfxf2"
15170 [(use (match_operand:SI 0 "register_operand" ""))
15171 (use (match_operand:XF 1 "register_operand" ""))]
15172 "TARGET_USE_FANCY_MATH_387
15173 && TARGET_C99_FUNCTIONS"
15174 {
15175 rtx mask = GEN_INT (0x45);
15176 rtx val = GEN_INT (0x05);
15177
15178 rtx cond;
15179
15180 rtx scratch = gen_reg_rtx (HImode);
15181 rtx res = gen_reg_rtx (QImode);
15182
15183 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15184
15185 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15186 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15187 cond = gen_rtx_fmt_ee (EQ, QImode,
15188 gen_rtx_REG (CCmode, FLAGS_REG),
15189 const0_rtx);
15190 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15191 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15192 DONE;
15193 })
15194
15195 (define_expand "isinf<mode>2"
15196 [(use (match_operand:SI 0 "register_operand" ""))
15197 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15198 "TARGET_USE_FANCY_MATH_387
15199 && TARGET_C99_FUNCTIONS
15200 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15201 {
15202 rtx mask = GEN_INT (0x45);
15203 rtx val = GEN_INT (0x05);
15204
15205 rtx cond;
15206
15207 rtx scratch = gen_reg_rtx (HImode);
15208 rtx res = gen_reg_rtx (QImode);
15209
15210 /* Remove excess precision by forcing value through memory. */
15211 if (memory_operand (operands[1], VOIDmode))
15212 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15213 else
15214 {
15215 enum ix86_stack_slot slot = (virtuals_instantiated
15216 ? SLOT_TEMP
15217 : SLOT_VIRTUAL);
15218 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15219
15220 emit_move_insn (temp, operands[1]);
15221 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15222 }
15223
15224 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15225 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15226 cond = gen_rtx_fmt_ee (EQ, QImode,
15227 gen_rtx_REG (CCmode, FLAGS_REG),
15228 const0_rtx);
15229 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15230 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15231 DONE;
15232 })
15233
15234 (define_expand "signbitxf2"
15235 [(use (match_operand:SI 0 "register_operand" ""))
15236 (use (match_operand:XF 1 "register_operand" ""))]
15237 "TARGET_USE_FANCY_MATH_387"
15238 {
15239 rtx scratch = gen_reg_rtx (HImode);
15240
15241 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15242 emit_insn (gen_andsi3 (operands[0],
15243 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15244 DONE;
15245 })
15246
15247 (define_insn "movmsk_df"
15248 [(set (match_operand:SI 0 "register_operand" "=r")
15249 (unspec:SI
15250 [(match_operand:DF 1 "register_operand" "x")]
15251 UNSPEC_MOVMSK))]
15252 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15253 "%vmovmskpd\t{%1, %0|%0, %1}"
15254 [(set_attr "type" "ssemov")
15255 (set_attr "prefix" "maybe_vex")
15256 (set_attr "mode" "DF")])
15257
15258 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15259 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15260 (define_expand "signbitdf2"
15261 [(use (match_operand:SI 0 "register_operand" ""))
15262 (use (match_operand:DF 1 "register_operand" ""))]
15263 "TARGET_USE_FANCY_MATH_387
15264 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15265 {
15266 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15267 {
15268 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15269 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15270 }
15271 else
15272 {
15273 rtx scratch = gen_reg_rtx (HImode);
15274
15275 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15276 emit_insn (gen_andsi3 (operands[0],
15277 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15278 }
15279 DONE;
15280 })
15281
15282 (define_expand "signbitsf2"
15283 [(use (match_operand:SI 0 "register_operand" ""))
15284 (use (match_operand:SF 1 "register_operand" ""))]
15285 "TARGET_USE_FANCY_MATH_387
15286 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15287 {
15288 rtx scratch = gen_reg_rtx (HImode);
15289
15290 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15291 emit_insn (gen_andsi3 (operands[0],
15292 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15293 DONE;
15294 })
15295 \f
15296 ;; Block operation instructions
15297
15298 (define_insn "cld"
15299 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15300 ""
15301 "cld"
15302 [(set_attr "length" "1")
15303 (set_attr "length_immediate" "0")
15304 (set_attr "modrm" "0")])
15305
15306 (define_expand "movmem<mode>"
15307 [(use (match_operand:BLK 0 "memory_operand" ""))
15308 (use (match_operand:BLK 1 "memory_operand" ""))
15309 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15310 (use (match_operand:SWI48 3 "const_int_operand" ""))
15311 (use (match_operand:SI 4 "const_int_operand" ""))
15312 (use (match_operand:SI 5 "const_int_operand" ""))]
15313 ""
15314 {
15315 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15316 operands[4], operands[5]))
15317 DONE;
15318 else
15319 FAIL;
15320 })
15321
15322 ;; Most CPUs don't like single string operations
15323 ;; Handle this case here to simplify previous expander.
15324
15325 (define_expand "strmov"
15326 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15327 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15328 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15329 (clobber (reg:CC FLAGS_REG))])
15330 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15331 (clobber (reg:CC FLAGS_REG))])]
15332 ""
15333 {
15334 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15335
15336 /* If .md ever supports :P for Pmode, these can be directly
15337 in the pattern above. */
15338 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15339 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15340
15341 /* Can't use this if the user has appropriated esi or edi. */
15342 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15343 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15344 {
15345 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15346 operands[2], operands[3],
15347 operands[5], operands[6]));
15348 DONE;
15349 }
15350
15351 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15352 })
15353
15354 (define_expand "strmov_singleop"
15355 [(parallel [(set (match_operand 1 "memory_operand" "")
15356 (match_operand 3 "memory_operand" ""))
15357 (set (match_operand 0 "register_operand" "")
15358 (match_operand 4 "" ""))
15359 (set (match_operand 2 "register_operand" "")
15360 (match_operand 5 "" ""))])]
15361 ""
15362 "ix86_current_function_needs_cld = 1;")
15363
15364 (define_insn "*strmovdi_rex_1"
15365 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15366 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15367 (set (match_operand:DI 0 "register_operand" "=D")
15368 (plus:DI (match_dup 2)
15369 (const_int 8)))
15370 (set (match_operand:DI 1 "register_operand" "=S")
15371 (plus:DI (match_dup 3)
15372 (const_int 8)))]
15373 "TARGET_64BIT"
15374 "movsq"
15375 [(set_attr "type" "str")
15376 (set_attr "memory" "both")
15377 (set_attr "mode" "DI")])
15378
15379 (define_insn "*strmovsi_1"
15380 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15381 (mem:SI (match_operand:P 3 "register_operand" "1")))
15382 (set (match_operand:P 0 "register_operand" "=D")
15383 (plus:P (match_dup 2)
15384 (const_int 4)))
15385 (set (match_operand:P 1 "register_operand" "=S")
15386 (plus:P (match_dup 3)
15387 (const_int 4)))]
15388 ""
15389 "movs{l|d}"
15390 [(set_attr "type" "str")
15391 (set_attr "memory" "both")
15392 (set_attr "mode" "SI")])
15393
15394 (define_insn "*strmovhi_1"
15395 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15396 (mem:HI (match_operand:P 3 "register_operand" "1")))
15397 (set (match_operand:P 0 "register_operand" "=D")
15398 (plus:P (match_dup 2)
15399 (const_int 2)))
15400 (set (match_operand:P 1 "register_operand" "=S")
15401 (plus:P (match_dup 3)
15402 (const_int 2)))]
15403 ""
15404 "movsw"
15405 [(set_attr "type" "str")
15406 (set_attr "memory" "both")
15407 (set_attr "mode" "HI")])
15408
15409 (define_insn "*strmovqi_1"
15410 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15411 (mem:QI (match_operand:P 3 "register_operand" "1")))
15412 (set (match_operand:P 0 "register_operand" "=D")
15413 (plus:P (match_dup 2)
15414 (const_int 1)))
15415 (set (match_operand:P 1 "register_operand" "=S")
15416 (plus:P (match_dup 3)
15417 (const_int 1)))]
15418 ""
15419 "movsb"
15420 [(set_attr "type" "str")
15421 (set_attr "memory" "both")
15422 (set (attr "prefix_rex")
15423 (if_then_else
15424 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15425 (const_string "0")
15426 (const_string "*")))
15427 (set_attr "mode" "QI")])
15428
15429 (define_expand "rep_mov"
15430 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15431 (set (match_operand 0 "register_operand" "")
15432 (match_operand 5 "" ""))
15433 (set (match_operand 2 "register_operand" "")
15434 (match_operand 6 "" ""))
15435 (set (match_operand 1 "memory_operand" "")
15436 (match_operand 3 "memory_operand" ""))
15437 (use (match_dup 4))])]
15438 ""
15439 "ix86_current_function_needs_cld = 1;")
15440
15441 (define_insn "*rep_movdi_rex64"
15442 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15443 (set (match_operand:DI 0 "register_operand" "=D")
15444 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15445 (const_int 3))
15446 (match_operand:DI 3 "register_operand" "0")))
15447 (set (match_operand:DI 1 "register_operand" "=S")
15448 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15449 (match_operand:DI 4 "register_operand" "1")))
15450 (set (mem:BLK (match_dup 3))
15451 (mem:BLK (match_dup 4)))
15452 (use (match_dup 5))]
15453 "TARGET_64BIT"
15454 "rep{%;} movsq"
15455 [(set_attr "type" "str")
15456 (set_attr "prefix_rep" "1")
15457 (set_attr "memory" "both")
15458 (set_attr "mode" "DI")])
15459
15460 (define_insn "*rep_movsi"
15461 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15462 (set (match_operand:P 0 "register_operand" "=D")
15463 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15464 (const_int 2))
15465 (match_operand:P 3 "register_operand" "0")))
15466 (set (match_operand:P 1 "register_operand" "=S")
15467 (plus:P (ashift:P (match_dup 5) (const_int 2))
15468 (match_operand:P 4 "register_operand" "1")))
15469 (set (mem:BLK (match_dup 3))
15470 (mem:BLK (match_dup 4)))
15471 (use (match_dup 5))]
15472 ""
15473 "rep{%;} movs{l|d}"
15474 [(set_attr "type" "str")
15475 (set_attr "prefix_rep" "1")
15476 (set_attr "memory" "both")
15477 (set_attr "mode" "SI")])
15478
15479 (define_insn "*rep_movqi"
15480 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15481 (set (match_operand:P 0 "register_operand" "=D")
15482 (plus:P (match_operand:P 3 "register_operand" "0")
15483 (match_operand:P 5 "register_operand" "2")))
15484 (set (match_operand:P 1 "register_operand" "=S")
15485 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15486 (set (mem:BLK (match_dup 3))
15487 (mem:BLK (match_dup 4)))
15488 (use (match_dup 5))]
15489 ""
15490 "rep{%;} movsb"
15491 [(set_attr "type" "str")
15492 (set_attr "prefix_rep" "1")
15493 (set_attr "memory" "both")
15494 (set_attr "mode" "QI")])
15495
15496 (define_expand "setmem<mode>"
15497 [(use (match_operand:BLK 0 "memory_operand" ""))
15498 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15499 (use (match_operand:QI 2 "nonmemory_operand" ""))
15500 (use (match_operand 3 "const_int_operand" ""))
15501 (use (match_operand:SI 4 "const_int_operand" ""))
15502 (use (match_operand:SI 5 "const_int_operand" ""))]
15503 ""
15504 {
15505 if (ix86_expand_setmem (operands[0], operands[1],
15506 operands[2], operands[3],
15507 operands[4], operands[5]))
15508 DONE;
15509 else
15510 FAIL;
15511 })
15512
15513 ;; Most CPUs don't like single string operations
15514 ;; Handle this case here to simplify previous expander.
15515
15516 (define_expand "strset"
15517 [(set (match_operand 1 "memory_operand" "")
15518 (match_operand 2 "register_operand" ""))
15519 (parallel [(set (match_operand 0 "register_operand" "")
15520 (match_dup 3))
15521 (clobber (reg:CC FLAGS_REG))])]
15522 ""
15523 {
15524 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15525 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15526
15527 /* If .md ever supports :P for Pmode, this can be directly
15528 in the pattern above. */
15529 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15530 GEN_INT (GET_MODE_SIZE (GET_MODE
15531 (operands[2]))));
15532 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15533 {
15534 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15535 operands[3]));
15536 DONE;
15537 }
15538 })
15539
15540 (define_expand "strset_singleop"
15541 [(parallel [(set (match_operand 1 "memory_operand" "")
15542 (match_operand 2 "register_operand" ""))
15543 (set (match_operand 0 "register_operand" "")
15544 (match_operand 3 "" ""))])]
15545 ""
15546 "ix86_current_function_needs_cld = 1;")
15547
15548 (define_insn "*strsetdi_rex_1"
15549 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15550 (match_operand:DI 2 "register_operand" "a"))
15551 (set (match_operand:DI 0 "register_operand" "=D")
15552 (plus:DI (match_dup 1)
15553 (const_int 8)))]
15554 "TARGET_64BIT"
15555 "stosq"
15556 [(set_attr "type" "str")
15557 (set_attr "memory" "store")
15558 (set_attr "mode" "DI")])
15559
15560 (define_insn "*strsetsi_1"
15561 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15562 (match_operand:SI 2 "register_operand" "a"))
15563 (set (match_operand:P 0 "register_operand" "=D")
15564 (plus:P (match_dup 1)
15565 (const_int 4)))]
15566 ""
15567 "stos{l|d}"
15568 [(set_attr "type" "str")
15569 (set_attr "memory" "store")
15570 (set_attr "mode" "SI")])
15571
15572 (define_insn "*strsethi_1"
15573 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15574 (match_operand:HI 2 "register_operand" "a"))
15575 (set (match_operand:P 0 "register_operand" "=D")
15576 (plus:P (match_dup 1)
15577 (const_int 2)))]
15578 ""
15579 "stosw"
15580 [(set_attr "type" "str")
15581 (set_attr "memory" "store")
15582 (set_attr "mode" "HI")])
15583
15584 (define_insn "*strsetqi_1"
15585 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15586 (match_operand:QI 2 "register_operand" "a"))
15587 (set (match_operand:P 0 "register_operand" "=D")
15588 (plus:P (match_dup 1)
15589 (const_int 1)))]
15590 ""
15591 "stosb"
15592 [(set_attr "type" "str")
15593 (set_attr "memory" "store")
15594 (set (attr "prefix_rex")
15595 (if_then_else
15596 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15597 (const_string "0")
15598 (const_string "*")))
15599 (set_attr "mode" "QI")])
15600
15601 (define_expand "rep_stos"
15602 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15603 (set (match_operand 0 "register_operand" "")
15604 (match_operand 4 "" ""))
15605 (set (match_operand 2 "memory_operand" "") (const_int 0))
15606 (use (match_operand 3 "register_operand" ""))
15607 (use (match_dup 1))])]
15608 ""
15609 "ix86_current_function_needs_cld = 1;")
15610
15611 (define_insn "*rep_stosdi_rex64"
15612 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15613 (set (match_operand:DI 0 "register_operand" "=D")
15614 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15615 (const_int 3))
15616 (match_operand:DI 3 "register_operand" "0")))
15617 (set (mem:BLK (match_dup 3))
15618 (const_int 0))
15619 (use (match_operand:DI 2 "register_operand" "a"))
15620 (use (match_dup 4))]
15621 "TARGET_64BIT"
15622 "rep{%;} stosq"
15623 [(set_attr "type" "str")
15624 (set_attr "prefix_rep" "1")
15625 (set_attr "memory" "store")
15626 (set_attr "mode" "DI")])
15627
15628 (define_insn "*rep_stossi"
15629 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15630 (set (match_operand:P 0 "register_operand" "=D")
15631 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15632 (const_int 2))
15633 (match_operand:P 3 "register_operand" "0")))
15634 (set (mem:BLK (match_dup 3))
15635 (const_int 0))
15636 (use (match_operand:SI 2 "register_operand" "a"))
15637 (use (match_dup 4))]
15638 ""
15639 "rep{%;} stos{l|d}"
15640 [(set_attr "type" "str")
15641 (set_attr "prefix_rep" "1")
15642 (set_attr "memory" "store")
15643 (set_attr "mode" "SI")])
15644
15645 (define_insn "*rep_stosqi"
15646 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15647 (set (match_operand:P 0 "register_operand" "=D")
15648 (plus:P (match_operand:P 3 "register_operand" "0")
15649 (match_operand:P 4 "register_operand" "1")))
15650 (set (mem:BLK (match_dup 3))
15651 (const_int 0))
15652 (use (match_operand:QI 2 "register_operand" "a"))
15653 (use (match_dup 4))]
15654 ""
15655 "rep{%;} stosb"
15656 [(set_attr "type" "str")
15657 (set_attr "prefix_rep" "1")
15658 (set_attr "memory" "store")
15659 (set (attr "prefix_rex")
15660 (if_then_else
15661 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15662 (const_string "0")
15663 (const_string "*")))
15664 (set_attr "mode" "QI")])
15665
15666 (define_expand "cmpstrnsi"
15667 [(set (match_operand:SI 0 "register_operand" "")
15668 (compare:SI (match_operand:BLK 1 "general_operand" "")
15669 (match_operand:BLK 2 "general_operand" "")))
15670 (use (match_operand 3 "general_operand" ""))
15671 (use (match_operand 4 "immediate_operand" ""))]
15672 ""
15673 {
15674 rtx addr1, addr2, out, outlow, count, countreg, align;
15675
15676 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15677 FAIL;
15678
15679 /* Can't use this if the user has appropriated esi or edi. */
15680 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15681 FAIL;
15682
15683 out = operands[0];
15684 if (!REG_P (out))
15685 out = gen_reg_rtx (SImode);
15686
15687 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15688 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15689 if (addr1 != XEXP (operands[1], 0))
15690 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15691 if (addr2 != XEXP (operands[2], 0))
15692 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15693
15694 count = operands[3];
15695 countreg = ix86_zero_extend_to_Pmode (count);
15696
15697 /* %%% Iff we are testing strict equality, we can use known alignment
15698 to good advantage. This may be possible with combine, particularly
15699 once cc0 is dead. */
15700 align = operands[4];
15701
15702 if (CONST_INT_P (count))
15703 {
15704 if (INTVAL (count) == 0)
15705 {
15706 emit_move_insn (operands[0], const0_rtx);
15707 DONE;
15708 }
15709 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15710 operands[1], operands[2]));
15711 }
15712 else
15713 {
15714 rtx (*gen_cmp) (rtx, rtx);
15715
15716 gen_cmp = (TARGET_64BIT
15717 ? gen_cmpdi_1 : gen_cmpsi_1);
15718
15719 emit_insn (gen_cmp (countreg, countreg));
15720 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15721 operands[1], operands[2]));
15722 }
15723
15724 outlow = gen_lowpart (QImode, out);
15725 emit_insn (gen_cmpintqi (outlow));
15726 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15727
15728 if (operands[0] != out)
15729 emit_move_insn (operands[0], out);
15730
15731 DONE;
15732 })
15733
15734 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15735
15736 (define_expand "cmpintqi"
15737 [(set (match_dup 1)
15738 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15739 (set (match_dup 2)
15740 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15741 (parallel [(set (match_operand:QI 0 "register_operand" "")
15742 (minus:QI (match_dup 1)
15743 (match_dup 2)))
15744 (clobber (reg:CC FLAGS_REG))])]
15745 ""
15746 {
15747 operands[1] = gen_reg_rtx (QImode);
15748 operands[2] = gen_reg_rtx (QImode);
15749 })
15750
15751 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15752 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15753
15754 (define_expand "cmpstrnqi_nz_1"
15755 [(parallel [(set (reg:CC FLAGS_REG)
15756 (compare:CC (match_operand 4 "memory_operand" "")
15757 (match_operand 5 "memory_operand" "")))
15758 (use (match_operand 2 "register_operand" ""))
15759 (use (match_operand:SI 3 "immediate_operand" ""))
15760 (clobber (match_operand 0 "register_operand" ""))
15761 (clobber (match_operand 1 "register_operand" ""))
15762 (clobber (match_dup 2))])]
15763 ""
15764 "ix86_current_function_needs_cld = 1;")
15765
15766 (define_insn "*cmpstrnqi_nz_1"
15767 [(set (reg:CC FLAGS_REG)
15768 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15769 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15770 (use (match_operand:P 6 "register_operand" "2"))
15771 (use (match_operand:SI 3 "immediate_operand" "i"))
15772 (clobber (match_operand:P 0 "register_operand" "=S"))
15773 (clobber (match_operand:P 1 "register_operand" "=D"))
15774 (clobber (match_operand:P 2 "register_operand" "=c"))]
15775 ""
15776 "repz{%;} cmpsb"
15777 [(set_attr "type" "str")
15778 (set_attr "mode" "QI")
15779 (set (attr "prefix_rex")
15780 (if_then_else
15781 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15782 (const_string "0")
15783 (const_string "*")))
15784 (set_attr "prefix_rep" "1")])
15785
15786 ;; The same, but the count is not known to not be zero.
15787
15788 (define_expand "cmpstrnqi_1"
15789 [(parallel [(set (reg:CC FLAGS_REG)
15790 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15791 (const_int 0))
15792 (compare:CC (match_operand 4 "memory_operand" "")
15793 (match_operand 5 "memory_operand" ""))
15794 (const_int 0)))
15795 (use (match_operand:SI 3 "immediate_operand" ""))
15796 (use (reg:CC FLAGS_REG))
15797 (clobber (match_operand 0 "register_operand" ""))
15798 (clobber (match_operand 1 "register_operand" ""))
15799 (clobber (match_dup 2))])]
15800 ""
15801 "ix86_current_function_needs_cld = 1;")
15802
15803 (define_insn "*cmpstrnqi_1"
15804 [(set (reg:CC FLAGS_REG)
15805 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15806 (const_int 0))
15807 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15808 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15809 (const_int 0)))
15810 (use (match_operand:SI 3 "immediate_operand" "i"))
15811 (use (reg:CC FLAGS_REG))
15812 (clobber (match_operand:P 0 "register_operand" "=S"))
15813 (clobber (match_operand:P 1 "register_operand" "=D"))
15814 (clobber (match_operand:P 2 "register_operand" "=c"))]
15815 ""
15816 "repz{%;} cmpsb"
15817 [(set_attr "type" "str")
15818 (set_attr "mode" "QI")
15819 (set (attr "prefix_rex")
15820 (if_then_else
15821 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15822 (const_string "0")
15823 (const_string "*")))
15824 (set_attr "prefix_rep" "1")])
15825
15826 (define_expand "strlen<mode>"
15827 [(set (match_operand:P 0 "register_operand" "")
15828 (unspec:P [(match_operand:BLK 1 "general_operand" "")
15829 (match_operand:QI 2 "immediate_operand" "")
15830 (match_operand 3 "immediate_operand" "")]
15831 UNSPEC_SCAS))]
15832 ""
15833 {
15834 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15835 DONE;
15836 else
15837 FAIL;
15838 })
15839
15840 (define_expand "strlenqi_1"
15841 [(parallel [(set (match_operand 0 "register_operand" "")
15842 (match_operand 2 "" ""))
15843 (clobber (match_operand 1 "register_operand" ""))
15844 (clobber (reg:CC FLAGS_REG))])]
15845 ""
15846 "ix86_current_function_needs_cld = 1;")
15847
15848 (define_insn "*strlenqi_1"
15849 [(set (match_operand:P 0 "register_operand" "=&c")
15850 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15851 (match_operand:QI 2 "register_operand" "a")
15852 (match_operand:P 3 "immediate_operand" "i")
15853 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15854 (clobber (match_operand:P 1 "register_operand" "=D"))
15855 (clobber (reg:CC FLAGS_REG))]
15856 ""
15857 "repnz{%;} scasb"
15858 [(set_attr "type" "str")
15859 (set_attr "mode" "QI")
15860 (set (attr "prefix_rex")
15861 (if_then_else
15862 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15863 (const_string "0")
15864 (const_string "*")))
15865 (set_attr "prefix_rep" "1")])
15866
15867 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15868 ;; handled in combine, but it is not currently up to the task.
15869 ;; When used for their truth value, the cmpstrn* expanders generate
15870 ;; code like this:
15871 ;;
15872 ;; repz cmpsb
15873 ;; seta %al
15874 ;; setb %dl
15875 ;; cmpb %al, %dl
15876 ;; jcc label
15877 ;;
15878 ;; The intermediate three instructions are unnecessary.
15879
15880 ;; This one handles cmpstrn*_nz_1...
15881 (define_peephole2
15882 [(parallel[
15883 (set (reg:CC FLAGS_REG)
15884 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15885 (mem:BLK (match_operand 5 "register_operand" ""))))
15886 (use (match_operand 6 "register_operand" ""))
15887 (use (match_operand:SI 3 "immediate_operand" ""))
15888 (clobber (match_operand 0 "register_operand" ""))
15889 (clobber (match_operand 1 "register_operand" ""))
15890 (clobber (match_operand 2 "register_operand" ""))])
15891 (set (match_operand:QI 7 "register_operand" "")
15892 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15893 (set (match_operand:QI 8 "register_operand" "")
15894 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15895 (set (reg FLAGS_REG)
15896 (compare (match_dup 7) (match_dup 8)))
15897 ]
15898 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15899 [(parallel[
15900 (set (reg:CC FLAGS_REG)
15901 (compare:CC (mem:BLK (match_dup 4))
15902 (mem:BLK (match_dup 5))))
15903 (use (match_dup 6))
15904 (use (match_dup 3))
15905 (clobber (match_dup 0))
15906 (clobber (match_dup 1))
15907 (clobber (match_dup 2))])])
15908
15909 ;; ...and this one handles cmpstrn*_1.
15910 (define_peephole2
15911 [(parallel[
15912 (set (reg:CC FLAGS_REG)
15913 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15914 (const_int 0))
15915 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15916 (mem:BLK (match_operand 5 "register_operand" "")))
15917 (const_int 0)))
15918 (use (match_operand:SI 3 "immediate_operand" ""))
15919 (use (reg:CC FLAGS_REG))
15920 (clobber (match_operand 0 "register_operand" ""))
15921 (clobber (match_operand 1 "register_operand" ""))
15922 (clobber (match_operand 2 "register_operand" ""))])
15923 (set (match_operand:QI 7 "register_operand" "")
15924 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15925 (set (match_operand:QI 8 "register_operand" "")
15926 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15927 (set (reg FLAGS_REG)
15928 (compare (match_dup 7) (match_dup 8)))
15929 ]
15930 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15931 [(parallel[
15932 (set (reg:CC FLAGS_REG)
15933 (if_then_else:CC (ne (match_dup 6)
15934 (const_int 0))
15935 (compare:CC (mem:BLK (match_dup 4))
15936 (mem:BLK (match_dup 5)))
15937 (const_int 0)))
15938 (use (match_dup 3))
15939 (use (reg:CC FLAGS_REG))
15940 (clobber (match_dup 0))
15941 (clobber (match_dup 1))
15942 (clobber (match_dup 2))])])
15943 \f
15944 ;; Conditional move instructions.
15945
15946 (define_expand "mov<mode>cc"
15947 [(set (match_operand:SWIM 0 "register_operand" "")
15948 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15949 (match_operand:SWIM 2 "<general_operand>" "")
15950 (match_operand:SWIM 3 "<general_operand>" "")))]
15951 ""
15952 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15953
15954 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15955 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15956 ;; So just document what we're doing explicitly.
15957
15958 (define_expand "x86_mov<mode>cc_0_m1"
15959 [(parallel
15960 [(set (match_operand:SWI48 0 "register_operand" "")
15961 (if_then_else:SWI48
15962 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15963 [(match_operand 1 "flags_reg_operand" "")
15964 (const_int 0)])
15965 (const_int -1)
15966 (const_int 0)))
15967 (clobber (reg:CC FLAGS_REG))])])
15968
15969 (define_insn "*x86_mov<mode>cc_0_m1"
15970 [(set (match_operand:SWI48 0 "register_operand" "=r")
15971 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15972 [(reg FLAGS_REG) (const_int 0)])
15973 (const_int -1)
15974 (const_int 0)))
15975 (clobber (reg:CC FLAGS_REG))]
15976 ""
15977 "sbb{<imodesuffix>}\t%0, %0"
15978 ; Since we don't have the proper number of operands for an alu insn,
15979 ; fill in all the blanks.
15980 [(set_attr "type" "alu")
15981 (set_attr "use_carry" "1")
15982 (set_attr "pent_pair" "pu")
15983 (set_attr "memory" "none")
15984 (set_attr "imm_disp" "false")
15985 (set_attr "mode" "<MODE>")
15986 (set_attr "length_immediate" "0")])
15987
15988 (define_insn "*x86_mov<mode>cc_0_m1_se"
15989 [(set (match_operand:SWI48 0 "register_operand" "=r")
15990 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15991 [(reg FLAGS_REG) (const_int 0)])
15992 (const_int 1)
15993 (const_int 0)))
15994 (clobber (reg:CC FLAGS_REG))]
15995 ""
15996 "sbb{<imodesuffix>}\t%0, %0"
15997 [(set_attr "type" "alu")
15998 (set_attr "use_carry" "1")
15999 (set_attr "pent_pair" "pu")
16000 (set_attr "memory" "none")
16001 (set_attr "imm_disp" "false")
16002 (set_attr "mode" "<MODE>")
16003 (set_attr "length_immediate" "0")])
16004
16005 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16006 [(set (match_operand:SWI48 0 "register_operand" "=r")
16007 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16008 [(reg FLAGS_REG) (const_int 0)])))]
16009 ""
16010 "sbb{<imodesuffix>}\t%0, %0"
16011 [(set_attr "type" "alu")
16012 (set_attr "use_carry" "1")
16013 (set_attr "pent_pair" "pu")
16014 (set_attr "memory" "none")
16015 (set_attr "imm_disp" "false")
16016 (set_attr "mode" "<MODE>")
16017 (set_attr "length_immediate" "0")])
16018
16019 (define_insn "*mov<mode>cc_noc"
16020 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16021 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16022 [(reg FLAGS_REG) (const_int 0)])
16023 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16024 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16025 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16026 "@
16027 cmov%O2%C1\t{%2, %0|%0, %2}
16028 cmov%O2%c1\t{%3, %0|%0, %3}"
16029 [(set_attr "type" "icmov")
16030 (set_attr "mode" "<MODE>")])
16031
16032 (define_insn_and_split "*movqicc_noc"
16033 [(set (match_operand:QI 0 "register_operand" "=r,r")
16034 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16035 [(match_operand 4 "flags_reg_operand" "")
16036 (const_int 0)])
16037 (match_operand:QI 2 "register_operand" "r,0")
16038 (match_operand:QI 3 "register_operand" "0,r")))]
16039 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16040 "#"
16041 "&& reload_completed"
16042 [(set (match_dup 0)
16043 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16044 (match_dup 2)
16045 (match_dup 3)))]
16046 "operands[0] = gen_lowpart (SImode, operands[0]);
16047 operands[2] = gen_lowpart (SImode, operands[2]);
16048 operands[3] = gen_lowpart (SImode, operands[3]);"
16049 [(set_attr "type" "icmov")
16050 (set_attr "mode" "SI")])
16051
16052 (define_expand "mov<mode>cc"
16053 [(set (match_operand:X87MODEF 0 "register_operand" "")
16054 (if_then_else:X87MODEF
16055 (match_operand 1 "ix86_fp_comparison_operator" "")
16056 (match_operand:X87MODEF 2 "register_operand" "")
16057 (match_operand:X87MODEF 3 "register_operand" "")))]
16058 "(TARGET_80387 && TARGET_CMOVE)
16059 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16060 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16061
16062 (define_insn "*movxfcc_1"
16063 [(set (match_operand:XF 0 "register_operand" "=f,f")
16064 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16065 [(reg FLAGS_REG) (const_int 0)])
16066 (match_operand:XF 2 "register_operand" "f,0")
16067 (match_operand:XF 3 "register_operand" "0,f")))]
16068 "TARGET_80387 && TARGET_CMOVE"
16069 "@
16070 fcmov%F1\t{%2, %0|%0, %2}
16071 fcmov%f1\t{%3, %0|%0, %3}"
16072 [(set_attr "type" "fcmov")
16073 (set_attr "mode" "XF")])
16074
16075 (define_insn "*movdfcc_1_rex64"
16076 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16077 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16078 [(reg FLAGS_REG) (const_int 0)])
16079 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16080 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16081 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16082 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16083 "@
16084 fcmov%F1\t{%2, %0|%0, %2}
16085 fcmov%f1\t{%3, %0|%0, %3}
16086 cmov%O2%C1\t{%2, %0|%0, %2}
16087 cmov%O2%c1\t{%3, %0|%0, %3}"
16088 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16089 (set_attr "mode" "DF,DF,DI,DI")])
16090
16091 (define_insn "*movdfcc_1"
16092 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16093 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16094 [(reg FLAGS_REG) (const_int 0)])
16095 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16096 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16097 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16098 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16099 "@
16100 fcmov%F1\t{%2, %0|%0, %2}
16101 fcmov%f1\t{%3, %0|%0, %3}
16102 #
16103 #"
16104 [(set_attr "type" "fcmov,fcmov,multi,multi")
16105 (set_attr "mode" "DF,DF,DI,DI")])
16106
16107 (define_split
16108 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16109 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16110 [(match_operand 4 "flags_reg_operand" "")
16111 (const_int 0)])
16112 (match_operand:DF 2 "nonimmediate_operand" "")
16113 (match_operand:DF 3 "nonimmediate_operand" "")))]
16114 "!TARGET_64BIT && reload_completed"
16115 [(set (match_dup 2)
16116 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16117 (match_dup 5)
16118 (match_dup 6)))
16119 (set (match_dup 3)
16120 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16121 (match_dup 7)
16122 (match_dup 8)))]
16123 {
16124 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16125 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16126 })
16127
16128 (define_insn "*movsfcc_1_387"
16129 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16130 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16131 [(reg FLAGS_REG) (const_int 0)])
16132 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16133 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16134 "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" "SF,SF,SI,SI")])
16143
16144 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16145 ;; the scalar versions to have only XMM registers as operands.
16146
16147 ;; XOP conditional move
16148 (define_insn "*xop_pcmov_<mode>"
16149 [(set (match_operand:MODEF 0 "register_operand" "=x")
16150 (if_then_else:MODEF
16151 (match_operand:MODEF 1 "register_operand" "x")
16152 (match_operand:MODEF 2 "register_operand" "x")
16153 (match_operand:MODEF 3 "register_operand" "x")))]
16154 "TARGET_XOP"
16155 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16156 [(set_attr "type" "sse4arg")])
16157
16158 ;; These versions of the min/max patterns are intentionally ignorant of
16159 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16160 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16161 ;; are undefined in this condition, we're certain this is correct.
16162
16163 (define_insn "<code><mode>3"
16164 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16165 (smaxmin:MODEF
16166 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16167 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16168 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16169 "@
16170 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16171 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16172 [(set_attr "isa" "noavx,avx")
16173 (set_attr "prefix" "orig,vex")
16174 (set_attr "type" "sseadd")
16175 (set_attr "mode" "<MODE>")])
16176
16177 ;; These versions of the min/max patterns implement exactly the operations
16178 ;; min = (op1 < op2 ? op1 : op2)
16179 ;; max = (!(op1 < op2) ? op1 : op2)
16180 ;; Their operands are not commutative, and thus they may be used in the
16181 ;; presence of -0.0 and NaN.
16182
16183 (define_insn "*ieee_smin<mode>3"
16184 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16185 (unspec:MODEF
16186 [(match_operand:MODEF 1 "register_operand" "0,x")
16187 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16188 UNSPEC_IEEE_MIN))]
16189 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16190 "@
16191 min<ssemodesuffix>\t{%2, %0|%0, %2}
16192 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16193 [(set_attr "isa" "noavx,avx")
16194 (set_attr "prefix" "orig,vex")
16195 (set_attr "type" "sseadd")
16196 (set_attr "mode" "<MODE>")])
16197
16198 (define_insn "*ieee_smax<mode>3"
16199 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16200 (unspec:MODEF
16201 [(match_operand:MODEF 1 "register_operand" "0,x")
16202 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16203 UNSPEC_IEEE_MAX))]
16204 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16205 "@
16206 max<ssemodesuffix>\t{%2, %0|%0, %2}
16207 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16208 [(set_attr "isa" "noavx,avx")
16209 (set_attr "prefix" "orig,vex")
16210 (set_attr "type" "sseadd")
16211 (set_attr "mode" "<MODE>")])
16212
16213 ;; Make two stack loads independent:
16214 ;; fld aa fld aa
16215 ;; fld %st(0) -> fld bb
16216 ;; fmul bb fmul %st(1), %st
16217 ;;
16218 ;; Actually we only match the last two instructions for simplicity.
16219 (define_peephole2
16220 [(set (match_operand 0 "fp_register_operand" "")
16221 (match_operand 1 "fp_register_operand" ""))
16222 (set (match_dup 0)
16223 (match_operator 2 "binary_fp_operator"
16224 [(match_dup 0)
16225 (match_operand 3 "memory_operand" "")]))]
16226 "REGNO (operands[0]) != REGNO (operands[1])"
16227 [(set (match_dup 0) (match_dup 3))
16228 (set (match_dup 0) (match_dup 4))]
16229
16230 ;; The % modifier is not operational anymore in peephole2's, so we have to
16231 ;; swap the operands manually in the case of addition and multiplication.
16232 "if (COMMUTATIVE_ARITH_P (operands[2]))
16233 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16234 GET_MODE (operands[2]),
16235 operands[0], operands[1]);
16236 else
16237 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16238 GET_MODE (operands[2]),
16239 operands[1], operands[0]);")
16240
16241 ;; Conditional addition patterns
16242 (define_expand "add<mode>cc"
16243 [(match_operand:SWI 0 "register_operand" "")
16244 (match_operand 1 "ordered_comparison_operator" "")
16245 (match_operand:SWI 2 "register_operand" "")
16246 (match_operand:SWI 3 "const_int_operand" "")]
16247 ""
16248 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16249 \f
16250 ;; Misc patterns (?)
16251
16252 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16253 ;; Otherwise there will be nothing to keep
16254 ;;
16255 ;; [(set (reg ebp) (reg esp))]
16256 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16257 ;; (clobber (eflags)]
16258 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16259 ;;
16260 ;; in proper program order.
16261
16262 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16263 [(set (match_operand:P 0 "register_operand" "=r,r")
16264 (plus:P (match_operand:P 1 "register_operand" "0,r")
16265 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16266 (clobber (reg:CC FLAGS_REG))
16267 (clobber (mem:BLK (scratch)))]
16268 ""
16269 {
16270 switch (get_attr_type (insn))
16271 {
16272 case TYPE_IMOV:
16273 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16274
16275 case TYPE_ALU:
16276 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16277 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16278 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16279
16280 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16281
16282 default:
16283 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16284 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16285 }
16286 }
16287 [(set (attr "type")
16288 (cond [(and (eq_attr "alternative" "0")
16289 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16290 (const_string "alu")
16291 (match_operand:<MODE> 2 "const0_operand" "")
16292 (const_string "imov")
16293 ]
16294 (const_string "lea")))
16295 (set (attr "length_immediate")
16296 (cond [(eq_attr "type" "imov")
16297 (const_string "0")
16298 (and (eq_attr "type" "alu")
16299 (match_operand 2 "const128_operand" ""))
16300 (const_string "1")
16301 ]
16302 (const_string "*")))
16303 (set_attr "mode" "<MODE>")])
16304
16305 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16306 [(set (match_operand:P 0 "register_operand" "=r")
16307 (minus:P (match_operand:P 1 "register_operand" "0")
16308 (match_operand:P 2 "register_operand" "r")))
16309 (clobber (reg:CC FLAGS_REG))
16310 (clobber (mem:BLK (scratch)))]
16311 ""
16312 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16313 [(set_attr "type" "alu")
16314 (set_attr "mode" "<MODE>")])
16315
16316 (define_insn "allocate_stack_worker_probe_<mode>"
16317 [(set (match_operand:P 0 "register_operand" "=a")
16318 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16319 UNSPECV_STACK_PROBE))
16320 (clobber (reg:CC FLAGS_REG))]
16321 "ix86_target_stack_probe ()"
16322 "call\t___chkstk_ms"
16323 [(set_attr "type" "multi")
16324 (set_attr "length" "5")])
16325
16326 (define_expand "allocate_stack"
16327 [(match_operand 0 "register_operand" "")
16328 (match_operand 1 "general_operand" "")]
16329 "ix86_target_stack_probe ()"
16330 {
16331 rtx x;
16332
16333 #ifndef CHECK_STACK_LIMIT
16334 #define CHECK_STACK_LIMIT 0
16335 #endif
16336
16337 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16338 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16339 {
16340 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16341 stack_pointer_rtx, 0, OPTAB_DIRECT);
16342 if (x != stack_pointer_rtx)
16343 emit_move_insn (stack_pointer_rtx, x);
16344 }
16345 else
16346 {
16347 x = copy_to_mode_reg (Pmode, operands[1]);
16348 if (TARGET_64BIT)
16349 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16350 else
16351 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16352 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16353 stack_pointer_rtx, 0, OPTAB_DIRECT);
16354 if (x != stack_pointer_rtx)
16355 emit_move_insn (stack_pointer_rtx, x);
16356 }
16357
16358 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16359 DONE;
16360 })
16361
16362 ;; Use IOR for stack probes, this is shorter.
16363 (define_expand "probe_stack"
16364 [(match_operand 0 "memory_operand" "")]
16365 ""
16366 {
16367 rtx (*gen_ior3) (rtx, rtx, rtx);
16368
16369 gen_ior3 = (GET_MODE (operands[0]) == DImode
16370 ? gen_iordi3 : gen_iorsi3);
16371
16372 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16373 DONE;
16374 })
16375
16376 (define_insn "adjust_stack_and_probe<mode>"
16377 [(set (match_operand:P 0 "register_operand" "=r")
16378 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16379 UNSPECV_PROBE_STACK_RANGE))
16380 (set (reg:P SP_REG)
16381 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16382 (clobber (reg:CC FLAGS_REG))
16383 (clobber (mem:BLK (scratch)))]
16384 ""
16385 "* return output_adjust_stack_and_probe (operands[0]);"
16386 [(set_attr "type" "multi")])
16387
16388 (define_insn "probe_stack_range<mode>"
16389 [(set (match_operand:P 0 "register_operand" "=r")
16390 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16391 (match_operand:P 2 "const_int_operand" "n")]
16392 UNSPECV_PROBE_STACK_RANGE))
16393 (clobber (reg:CC FLAGS_REG))]
16394 ""
16395 "* return output_probe_stack_range (operands[0], operands[2]);"
16396 [(set_attr "type" "multi")])
16397
16398 (define_expand "builtin_setjmp_receiver"
16399 [(label_ref (match_operand 0 "" ""))]
16400 "!TARGET_64BIT && flag_pic"
16401 {
16402 #if TARGET_MACHO
16403 if (TARGET_MACHO)
16404 {
16405 rtx xops[3];
16406 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16407 rtx label_rtx = gen_label_rtx ();
16408 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16409 xops[0] = xops[1] = picreg;
16410 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16411 ix86_expand_binary_operator (MINUS, SImode, xops);
16412 }
16413 else
16414 #endif
16415 emit_insn (gen_set_got (pic_offset_table_rtx));
16416 DONE;
16417 })
16418 \f
16419 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16420
16421 (define_split
16422 [(set (match_operand 0 "register_operand" "")
16423 (match_operator 3 "promotable_binary_operator"
16424 [(match_operand 1 "register_operand" "")
16425 (match_operand 2 "aligned_operand" "")]))
16426 (clobber (reg:CC FLAGS_REG))]
16427 "! TARGET_PARTIAL_REG_STALL && reload_completed
16428 && ((GET_MODE (operands[0]) == HImode
16429 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16430 /* ??? next two lines just !satisfies_constraint_K (...) */
16431 || !CONST_INT_P (operands[2])
16432 || satisfies_constraint_K (operands[2])))
16433 || (GET_MODE (operands[0]) == QImode
16434 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16435 [(parallel [(set (match_dup 0)
16436 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16437 (clobber (reg:CC FLAGS_REG))])]
16438 "operands[0] = gen_lowpart (SImode, operands[0]);
16439 operands[1] = gen_lowpart (SImode, operands[1]);
16440 if (GET_CODE (operands[3]) != ASHIFT)
16441 operands[2] = gen_lowpart (SImode, operands[2]);
16442 PUT_MODE (operands[3], SImode);")
16443
16444 ; Promote the QImode tests, as i386 has encoding of the AND
16445 ; instruction with 32-bit sign-extended immediate and thus the
16446 ; instruction size is unchanged, except in the %eax case for
16447 ; which it is increased by one byte, hence the ! optimize_size.
16448 (define_split
16449 [(set (match_operand 0 "flags_reg_operand" "")
16450 (match_operator 2 "compare_operator"
16451 [(and (match_operand 3 "aligned_operand" "")
16452 (match_operand 4 "const_int_operand" ""))
16453 (const_int 0)]))
16454 (set (match_operand 1 "register_operand" "")
16455 (and (match_dup 3) (match_dup 4)))]
16456 "! TARGET_PARTIAL_REG_STALL && reload_completed
16457 && optimize_insn_for_speed_p ()
16458 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16459 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16460 /* Ensure that the operand will remain sign-extended immediate. */
16461 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16462 [(parallel [(set (match_dup 0)
16463 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16464 (const_int 0)]))
16465 (set (match_dup 1)
16466 (and:SI (match_dup 3) (match_dup 4)))])]
16467 {
16468 operands[4]
16469 = gen_int_mode (INTVAL (operands[4])
16470 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16471 operands[1] = gen_lowpart (SImode, operands[1]);
16472 operands[3] = gen_lowpart (SImode, operands[3]);
16473 })
16474
16475 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16476 ; the TEST instruction with 32-bit sign-extended immediate and thus
16477 ; the instruction size would at least double, which is not what we
16478 ; want even with ! optimize_size.
16479 (define_split
16480 [(set (match_operand 0 "flags_reg_operand" "")
16481 (match_operator 1 "compare_operator"
16482 [(and (match_operand:HI 2 "aligned_operand" "")
16483 (match_operand:HI 3 "const_int_operand" ""))
16484 (const_int 0)]))]
16485 "! TARGET_PARTIAL_REG_STALL && reload_completed
16486 && ! TARGET_FAST_PREFIX
16487 && optimize_insn_for_speed_p ()
16488 /* Ensure that the operand will remain sign-extended immediate. */
16489 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16490 [(set (match_dup 0)
16491 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16492 (const_int 0)]))]
16493 {
16494 operands[3]
16495 = gen_int_mode (INTVAL (operands[3])
16496 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16497 operands[2] = gen_lowpart (SImode, operands[2]);
16498 })
16499
16500 (define_split
16501 [(set (match_operand 0 "register_operand" "")
16502 (neg (match_operand 1 "register_operand" "")))
16503 (clobber (reg:CC FLAGS_REG))]
16504 "! TARGET_PARTIAL_REG_STALL && reload_completed
16505 && (GET_MODE (operands[0]) == HImode
16506 || (GET_MODE (operands[0]) == QImode
16507 && (TARGET_PROMOTE_QImode
16508 || optimize_insn_for_size_p ())))"
16509 [(parallel [(set (match_dup 0)
16510 (neg:SI (match_dup 1)))
16511 (clobber (reg:CC FLAGS_REG))])]
16512 "operands[0] = gen_lowpart (SImode, operands[0]);
16513 operands[1] = gen_lowpart (SImode, operands[1]);")
16514
16515 (define_split
16516 [(set (match_operand 0 "register_operand" "")
16517 (not (match_operand 1 "register_operand" "")))]
16518 "! TARGET_PARTIAL_REG_STALL && reload_completed
16519 && (GET_MODE (operands[0]) == HImode
16520 || (GET_MODE (operands[0]) == QImode
16521 && (TARGET_PROMOTE_QImode
16522 || optimize_insn_for_size_p ())))"
16523 [(set (match_dup 0)
16524 (not:SI (match_dup 1)))]
16525 "operands[0] = gen_lowpart (SImode, operands[0]);
16526 operands[1] = gen_lowpart (SImode, operands[1]);")
16527
16528 (define_split
16529 [(set (match_operand 0 "register_operand" "")
16530 (if_then_else (match_operator 1 "ordered_comparison_operator"
16531 [(reg FLAGS_REG) (const_int 0)])
16532 (match_operand 2 "register_operand" "")
16533 (match_operand 3 "register_operand" "")))]
16534 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16535 && (GET_MODE (operands[0]) == HImode
16536 || (GET_MODE (operands[0]) == QImode
16537 && (TARGET_PROMOTE_QImode
16538 || optimize_insn_for_size_p ())))"
16539 [(set (match_dup 0)
16540 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16541 "operands[0] = gen_lowpart (SImode, operands[0]);
16542 operands[2] = gen_lowpart (SImode, operands[2]);
16543 operands[3] = gen_lowpart (SImode, operands[3]);")
16544 \f
16545 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16546 ;; transform a complex memory operation into two memory to register operations.
16547
16548 ;; Don't push memory operands
16549 (define_peephole2
16550 [(set (match_operand:SWI 0 "push_operand" "")
16551 (match_operand:SWI 1 "memory_operand" ""))
16552 (match_scratch:SWI 2 "<r>")]
16553 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16554 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16555 [(set (match_dup 2) (match_dup 1))
16556 (set (match_dup 0) (match_dup 2))])
16557
16558 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16559 ;; SImode pushes.
16560 (define_peephole2
16561 [(set (match_operand:SF 0 "push_operand" "")
16562 (match_operand:SF 1 "memory_operand" ""))
16563 (match_scratch:SF 2 "r")]
16564 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16565 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16566 [(set (match_dup 2) (match_dup 1))
16567 (set (match_dup 0) (match_dup 2))])
16568
16569 ;; Don't move an immediate directly to memory when the instruction
16570 ;; gets too big.
16571 (define_peephole2
16572 [(match_scratch:SWI124 1 "<r>")
16573 (set (match_operand:SWI124 0 "memory_operand" "")
16574 (const_int 0))]
16575 "optimize_insn_for_speed_p ()
16576 && !TARGET_USE_MOV0
16577 && TARGET_SPLIT_LONG_MOVES
16578 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16579 && peep2_regno_dead_p (0, FLAGS_REG)"
16580 [(parallel [(set (match_dup 2) (const_int 0))
16581 (clobber (reg:CC FLAGS_REG))])
16582 (set (match_dup 0) (match_dup 1))]
16583 "operands[2] = gen_lowpart (SImode, operands[1]);")
16584
16585 (define_peephole2
16586 [(match_scratch:SWI124 2 "<r>")
16587 (set (match_operand:SWI124 0 "memory_operand" "")
16588 (match_operand:SWI124 1 "immediate_operand" ""))]
16589 "optimize_insn_for_speed_p ()
16590 && TARGET_SPLIT_LONG_MOVES
16591 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16592 [(set (match_dup 2) (match_dup 1))
16593 (set (match_dup 0) (match_dup 2))])
16594
16595 ;; Don't compare memory with zero, load and use a test instead.
16596 (define_peephole2
16597 [(set (match_operand 0 "flags_reg_operand" "")
16598 (match_operator 1 "compare_operator"
16599 [(match_operand:SI 2 "memory_operand" "")
16600 (const_int 0)]))
16601 (match_scratch:SI 3 "r")]
16602 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16603 [(set (match_dup 3) (match_dup 2))
16604 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16605
16606 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16607 ;; Don't split NOTs with a displacement operand, because resulting XOR
16608 ;; will not be pairable anyway.
16609 ;;
16610 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16611 ;; represented using a modRM byte. The XOR replacement is long decoded,
16612 ;; so this split helps here as well.
16613 ;;
16614 ;; Note: Can't do this as a regular split because we can't get proper
16615 ;; lifetime information then.
16616
16617 (define_peephole2
16618 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16619 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16620 "optimize_insn_for_speed_p ()
16621 && ((TARGET_NOT_UNPAIRABLE
16622 && (!MEM_P (operands[0])
16623 || !memory_displacement_operand (operands[0], <MODE>mode)))
16624 || (TARGET_NOT_VECTORMODE
16625 && long_memory_operand (operands[0], <MODE>mode)))
16626 && peep2_regno_dead_p (0, FLAGS_REG)"
16627 [(parallel [(set (match_dup 0)
16628 (xor:SWI124 (match_dup 1) (const_int -1)))
16629 (clobber (reg:CC FLAGS_REG))])])
16630
16631 ;; Non pairable "test imm, reg" instructions can be translated to
16632 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16633 ;; byte opcode instead of two, have a short form for byte operands),
16634 ;; so do it for other CPUs as well. Given that the value was dead,
16635 ;; this should not create any new dependencies. Pass on the sub-word
16636 ;; versions if we're concerned about partial register stalls.
16637
16638 (define_peephole2
16639 [(set (match_operand 0 "flags_reg_operand" "")
16640 (match_operator 1 "compare_operator"
16641 [(and:SI (match_operand:SI 2 "register_operand" "")
16642 (match_operand:SI 3 "immediate_operand" ""))
16643 (const_int 0)]))]
16644 "ix86_match_ccmode (insn, CCNOmode)
16645 && (true_regnum (operands[2]) != AX_REG
16646 || satisfies_constraint_K (operands[3]))
16647 && peep2_reg_dead_p (1, operands[2])"
16648 [(parallel
16649 [(set (match_dup 0)
16650 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16651 (const_int 0)]))
16652 (set (match_dup 2)
16653 (and:SI (match_dup 2) (match_dup 3)))])])
16654
16655 ;; We don't need to handle HImode case, because it will be promoted to SImode
16656 ;; on ! TARGET_PARTIAL_REG_STALL
16657
16658 (define_peephole2
16659 [(set (match_operand 0 "flags_reg_operand" "")
16660 (match_operator 1 "compare_operator"
16661 [(and:QI (match_operand:QI 2 "register_operand" "")
16662 (match_operand:QI 3 "immediate_operand" ""))
16663 (const_int 0)]))]
16664 "! TARGET_PARTIAL_REG_STALL
16665 && ix86_match_ccmode (insn, CCNOmode)
16666 && true_regnum (operands[2]) != AX_REG
16667 && peep2_reg_dead_p (1, operands[2])"
16668 [(parallel
16669 [(set (match_dup 0)
16670 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16671 (const_int 0)]))
16672 (set (match_dup 2)
16673 (and:QI (match_dup 2) (match_dup 3)))])])
16674
16675 (define_peephole2
16676 [(set (match_operand 0 "flags_reg_operand" "")
16677 (match_operator 1 "compare_operator"
16678 [(and:SI
16679 (zero_extract:SI
16680 (match_operand 2 "ext_register_operand" "")
16681 (const_int 8)
16682 (const_int 8))
16683 (match_operand 3 "const_int_operand" ""))
16684 (const_int 0)]))]
16685 "! TARGET_PARTIAL_REG_STALL
16686 && ix86_match_ccmode (insn, CCNOmode)
16687 && true_regnum (operands[2]) != AX_REG
16688 && peep2_reg_dead_p (1, operands[2])"
16689 [(parallel [(set (match_dup 0)
16690 (match_op_dup 1
16691 [(and:SI
16692 (zero_extract:SI
16693 (match_dup 2)
16694 (const_int 8)
16695 (const_int 8))
16696 (match_dup 3))
16697 (const_int 0)]))
16698 (set (zero_extract:SI (match_dup 2)
16699 (const_int 8)
16700 (const_int 8))
16701 (and:SI
16702 (zero_extract:SI
16703 (match_dup 2)
16704 (const_int 8)
16705 (const_int 8))
16706 (match_dup 3)))])])
16707
16708 ;; Don't do logical operations with memory inputs.
16709 (define_peephole2
16710 [(match_scratch:SI 2 "r")
16711 (parallel [(set (match_operand:SI 0 "register_operand" "")
16712 (match_operator:SI 3 "arith_or_logical_operator"
16713 [(match_dup 0)
16714 (match_operand:SI 1 "memory_operand" "")]))
16715 (clobber (reg:CC FLAGS_REG))])]
16716 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16717 [(set (match_dup 2) (match_dup 1))
16718 (parallel [(set (match_dup 0)
16719 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16720 (clobber (reg:CC FLAGS_REG))])])
16721
16722 (define_peephole2
16723 [(match_scratch:SI 2 "r")
16724 (parallel [(set (match_operand:SI 0 "register_operand" "")
16725 (match_operator:SI 3 "arith_or_logical_operator"
16726 [(match_operand:SI 1 "memory_operand" "")
16727 (match_dup 0)]))
16728 (clobber (reg:CC FLAGS_REG))])]
16729 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16730 [(set (match_dup 2) (match_dup 1))
16731 (parallel [(set (match_dup 0)
16732 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16733 (clobber (reg:CC FLAGS_REG))])])
16734
16735 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16736 ;; refers to the destination of the load!
16737
16738 (define_peephole2
16739 [(set (match_operand:SI 0 "register_operand" "")
16740 (match_operand:SI 1 "register_operand" ""))
16741 (parallel [(set (match_dup 0)
16742 (match_operator:SI 3 "commutative_operator"
16743 [(match_dup 0)
16744 (match_operand:SI 2 "memory_operand" "")]))
16745 (clobber (reg:CC FLAGS_REG))])]
16746 "REGNO (operands[0]) != REGNO (operands[1])
16747 && GENERAL_REGNO_P (REGNO (operands[0]))
16748 && GENERAL_REGNO_P (REGNO (operands[1]))"
16749 [(set (match_dup 0) (match_dup 4))
16750 (parallel [(set (match_dup 0)
16751 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16752 (clobber (reg:CC FLAGS_REG))])]
16753 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16754
16755 (define_peephole2
16756 [(set (match_operand 0 "register_operand" "")
16757 (match_operand 1 "register_operand" ""))
16758 (set (match_dup 0)
16759 (match_operator 3 "commutative_operator"
16760 [(match_dup 0)
16761 (match_operand 2 "memory_operand" "")]))]
16762 "REGNO (operands[0]) != REGNO (operands[1])
16763 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16764 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16765 [(set (match_dup 0) (match_dup 2))
16766 (set (match_dup 0)
16767 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16768
16769 ; Don't do logical operations with memory outputs
16770 ;
16771 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16772 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16773 ; the same decoder scheduling characteristics as the original.
16774
16775 (define_peephole2
16776 [(match_scratch:SI 2 "r")
16777 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16778 (match_operator:SI 3 "arith_or_logical_operator"
16779 [(match_dup 0)
16780 (match_operand:SI 1 "nonmemory_operand" "")]))
16781 (clobber (reg:CC FLAGS_REG))])]
16782 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16783 /* Do not split stack checking probes. */
16784 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16785 [(set (match_dup 2) (match_dup 0))
16786 (parallel [(set (match_dup 2)
16787 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16788 (clobber (reg:CC FLAGS_REG))])
16789 (set (match_dup 0) (match_dup 2))])
16790
16791 (define_peephole2
16792 [(match_scratch:SI 2 "r")
16793 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16794 (match_operator:SI 3 "arith_or_logical_operator"
16795 [(match_operand:SI 1 "nonmemory_operand" "")
16796 (match_dup 0)]))
16797 (clobber (reg:CC FLAGS_REG))])]
16798 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16799 /* Do not split stack checking probes. */
16800 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16801 [(set (match_dup 2) (match_dup 0))
16802 (parallel [(set (match_dup 2)
16803 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16804 (clobber (reg:CC FLAGS_REG))])
16805 (set (match_dup 0) (match_dup 2))])
16806
16807 ;; Attempt to use arith or logical operations with memory outputs with
16808 ;; setting of flags.
16809 (define_peephole2
16810 [(set (match_operand:SWI 0 "register_operand" "")
16811 (match_operand:SWI 1 "memory_operand" ""))
16812 (parallel [(set (match_dup 0)
16813 (match_operator:SWI 3 "plusminuslogic_operator"
16814 [(match_dup 0)
16815 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16816 (clobber (reg:CC FLAGS_REG))])
16817 (set (match_dup 1) (match_dup 0))
16818 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16819 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16820 && peep2_reg_dead_p (4, operands[0])
16821 && !reg_overlap_mentioned_p (operands[0], operands[1])
16822 && ix86_match_ccmode (peep2_next_insn (3),
16823 (GET_CODE (operands[3]) == PLUS
16824 || GET_CODE (operands[3]) == MINUS)
16825 ? CCGOCmode : CCNOmode)"
16826 [(parallel [(set (match_dup 4) (match_dup 5))
16827 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16828 (match_dup 2)]))])]
16829 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16830 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16831 copy_rtx (operands[1]),
16832 copy_rtx (operands[2]));
16833 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16834 operands[5], const0_rtx);")
16835
16836 (define_peephole2
16837 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16838 (match_operator:SWI 2 "plusminuslogic_operator"
16839 [(match_dup 0)
16840 (match_operand:SWI 1 "memory_operand" "")]))
16841 (clobber (reg:CC FLAGS_REG))])
16842 (set (match_dup 1) (match_dup 0))
16843 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16844 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16845 && GET_CODE (operands[2]) != MINUS
16846 && peep2_reg_dead_p (3, operands[0])
16847 && !reg_overlap_mentioned_p (operands[0], operands[1])
16848 && ix86_match_ccmode (peep2_next_insn (2),
16849 GET_CODE (operands[2]) == PLUS
16850 ? CCGOCmode : CCNOmode)"
16851 [(parallel [(set (match_dup 3) (match_dup 4))
16852 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16853 (match_dup 0)]))])]
16854 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16855 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16856 copy_rtx (operands[1]),
16857 copy_rtx (operands[0]));
16858 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16859 operands[4], const0_rtx);")
16860
16861 (define_peephole2
16862 [(set (match_operand:SWI12 0 "register_operand" "")
16863 (match_operand:SWI12 1 "memory_operand" ""))
16864 (parallel [(set (match_operand:SI 4 "register_operand" "")
16865 (match_operator:SI 3 "plusminuslogic_operator"
16866 [(match_dup 4)
16867 (match_operand:SI 2 "nonmemory_operand" "")]))
16868 (clobber (reg:CC FLAGS_REG))])
16869 (set (match_dup 1) (match_dup 0))
16870 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16871 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16872 && REG_P (operands[0]) && REG_P (operands[4])
16873 && REGNO (operands[0]) == REGNO (operands[4])
16874 && peep2_reg_dead_p (4, operands[0])
16875 && !reg_overlap_mentioned_p (operands[0], operands[1])
16876 && ix86_match_ccmode (peep2_next_insn (3),
16877 (GET_CODE (operands[3]) == PLUS
16878 || GET_CODE (operands[3]) == MINUS)
16879 ? CCGOCmode : CCNOmode)"
16880 [(parallel [(set (match_dup 4) (match_dup 5))
16881 (set (match_dup 1) (match_dup 6))])]
16882 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16883 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16884 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16885 copy_rtx (operands[1]), operands[2]);
16886 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16887 operands[5], const0_rtx);
16888 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16889 copy_rtx (operands[1]),
16890 copy_rtx (operands[2]));")
16891
16892 ;; Attempt to always use XOR for zeroing registers.
16893 (define_peephole2
16894 [(set (match_operand 0 "register_operand" "")
16895 (match_operand 1 "const0_operand" ""))]
16896 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16897 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16898 && GENERAL_REG_P (operands[0])
16899 && peep2_regno_dead_p (0, FLAGS_REG)"
16900 [(parallel [(set (match_dup 0) (const_int 0))
16901 (clobber (reg:CC FLAGS_REG))])]
16902 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16903
16904 (define_peephole2
16905 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16906 (const_int 0))]
16907 "(GET_MODE (operands[0]) == QImode
16908 || GET_MODE (operands[0]) == HImode)
16909 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16910 && peep2_regno_dead_p (0, FLAGS_REG)"
16911 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16912 (clobber (reg:CC FLAGS_REG))])])
16913
16914 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16915 (define_peephole2
16916 [(set (match_operand:SWI248 0 "register_operand" "")
16917 (const_int -1))]
16918 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16919 && peep2_regno_dead_p (0, FLAGS_REG)"
16920 [(parallel [(set (match_dup 0) (const_int -1))
16921 (clobber (reg:CC FLAGS_REG))])]
16922 {
16923 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16924 operands[0] = gen_lowpart (SImode, operands[0]);
16925 })
16926
16927 ;; Attempt to convert simple lea to add/shift.
16928 ;; These can be created by move expanders.
16929
16930 (define_peephole2
16931 [(set (match_operand:SWI48 0 "register_operand" "")
16932 (plus:SWI48 (match_dup 0)
16933 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16934 "peep2_regno_dead_p (0, FLAGS_REG)"
16935 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16936 (clobber (reg:CC FLAGS_REG))])])
16937
16938 (define_peephole2
16939 [(set (match_operand:SI 0 "register_operand" "")
16940 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16941 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16942 "TARGET_64BIT
16943 && peep2_regno_dead_p (0, FLAGS_REG)
16944 && REGNO (operands[0]) == REGNO (operands[1])"
16945 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16946 (clobber (reg:CC FLAGS_REG))])]
16947 "operands[2] = gen_lowpart (SImode, operands[2]);")
16948
16949 (define_peephole2
16950 [(set (match_operand:SWI48 0 "register_operand" "")
16951 (mult:SWI48 (match_dup 0)
16952 (match_operand:SWI48 1 "const_int_operand" "")))]
16953 "exact_log2 (INTVAL (operands[1])) >= 0
16954 && peep2_regno_dead_p (0, FLAGS_REG)"
16955 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16956 (clobber (reg:CC FLAGS_REG))])]
16957 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16958
16959 (define_peephole2
16960 [(set (match_operand:SI 0 "register_operand" "")
16961 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16962 (match_operand:DI 2 "const_int_operand" "")) 0))]
16963 "TARGET_64BIT
16964 && exact_log2 (INTVAL (operands[2])) >= 0
16965 && REGNO (operands[0]) == REGNO (operands[1])
16966 && peep2_regno_dead_p (0, FLAGS_REG)"
16967 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16968 (clobber (reg:CC FLAGS_REG))])]
16969 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16970
16971 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16972 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16973 ;; On many CPUs it is also faster, since special hardware to avoid esp
16974 ;; dependencies is present.
16975
16976 ;; While some of these conversions may be done using splitters, we use
16977 ;; peepholes in order to allow combine_stack_adjustments pass to see
16978 ;; nonobfuscated RTL.
16979
16980 ;; Convert prologue esp subtractions to push.
16981 ;; We need register to push. In order to keep verify_flow_info happy we have
16982 ;; two choices
16983 ;; - use scratch and clobber it in order to avoid dependencies
16984 ;; - use already live register
16985 ;; We can't use the second way right now, since there is no reliable way how to
16986 ;; verify that given register is live. First choice will also most likely in
16987 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16988 ;; call clobbered registers are dead. We may want to use base pointer as an
16989 ;; alternative when no register is available later.
16990
16991 (define_peephole2
16992 [(match_scratch:P 1 "r")
16993 (parallel [(set (reg:P SP_REG)
16994 (plus:P (reg:P SP_REG)
16995 (match_operand:P 0 "const_int_operand" "")))
16996 (clobber (reg:CC FLAGS_REG))
16997 (clobber (mem:BLK (scratch)))])]
16998 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16999 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17000 [(clobber (match_dup 1))
17001 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17002 (clobber (mem:BLK (scratch)))])])
17003
17004 (define_peephole2
17005 [(match_scratch:P 1 "r")
17006 (parallel [(set (reg:P SP_REG)
17007 (plus:P (reg:P SP_REG)
17008 (match_operand:P 0 "const_int_operand" "")))
17009 (clobber (reg:CC FLAGS_REG))
17010 (clobber (mem:BLK (scratch)))])]
17011 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17012 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17013 [(clobber (match_dup 1))
17014 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17015 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17016 (clobber (mem:BLK (scratch)))])])
17017
17018 ;; Convert esp subtractions to push.
17019 (define_peephole2
17020 [(match_scratch:P 1 "r")
17021 (parallel [(set (reg:P SP_REG)
17022 (plus:P (reg:P SP_REG)
17023 (match_operand:P 0 "const_int_operand" "")))
17024 (clobber (reg:CC FLAGS_REG))])]
17025 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17026 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17027 [(clobber (match_dup 1))
17028 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17029
17030 (define_peephole2
17031 [(match_scratch:P 1 "r")
17032 (parallel [(set (reg:P SP_REG)
17033 (plus:P (reg:P SP_REG)
17034 (match_operand:P 0 "const_int_operand" "")))
17035 (clobber (reg:CC FLAGS_REG))])]
17036 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17037 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17038 [(clobber (match_dup 1))
17039 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17040 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17041
17042 ;; Convert epilogue deallocator to pop.
17043 (define_peephole2
17044 [(match_scratch:P 1 "r")
17045 (parallel [(set (reg:P SP_REG)
17046 (plus:P (reg:P SP_REG)
17047 (match_operand:P 0 "const_int_operand" "")))
17048 (clobber (reg:CC FLAGS_REG))
17049 (clobber (mem:BLK (scratch)))])]
17050 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17051 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17052 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17053 (clobber (mem:BLK (scratch)))])])
17054
17055 ;; Two pops case is tricky, since pop causes dependency
17056 ;; on destination register. We use two registers if available.
17057 (define_peephole2
17058 [(match_scratch:P 1 "r")
17059 (match_scratch:P 2 "r")
17060 (parallel [(set (reg:P SP_REG)
17061 (plus:P (reg:P SP_REG)
17062 (match_operand:P 0 "const_int_operand" "")))
17063 (clobber (reg:CC FLAGS_REG))
17064 (clobber (mem:BLK (scratch)))])]
17065 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17066 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17067 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17068 (clobber (mem:BLK (scratch)))])
17069 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17070
17071 (define_peephole2
17072 [(match_scratch:P 1 "r")
17073 (parallel [(set (reg:P SP_REG)
17074 (plus:P (reg:P SP_REG)
17075 (match_operand:P 0 "const_int_operand" "")))
17076 (clobber (reg:CC FLAGS_REG))
17077 (clobber (mem:BLK (scratch)))])]
17078 "optimize_insn_for_size_p ()
17079 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17080 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17081 (clobber (mem:BLK (scratch)))])
17082 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17083
17084 ;; Convert esp additions to pop.
17085 (define_peephole2
17086 [(match_scratch:P 1 "r")
17087 (parallel [(set (reg:P SP_REG)
17088 (plus:P (reg:P SP_REG)
17089 (match_operand:P 0 "const_int_operand" "")))
17090 (clobber (reg:CC FLAGS_REG))])]
17091 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17092 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17093
17094 ;; Two pops case is tricky, since pop causes dependency
17095 ;; on destination register. We use two registers if available.
17096 (define_peephole2
17097 [(match_scratch:P 1 "r")
17098 (match_scratch:P 2 "r")
17099 (parallel [(set (reg:P SP_REG)
17100 (plus:P (reg:P SP_REG)
17101 (match_operand:P 0 "const_int_operand" "")))
17102 (clobber (reg:CC FLAGS_REG))])]
17103 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17104 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17105 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17106
17107 (define_peephole2
17108 [(match_scratch:P 1 "r")
17109 (parallel [(set (reg:P SP_REG)
17110 (plus:P (reg:P SP_REG)
17111 (match_operand:P 0 "const_int_operand" "")))
17112 (clobber (reg:CC FLAGS_REG))])]
17113 "optimize_insn_for_size_p ()
17114 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17115 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17116 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17117 \f
17118 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17119 ;; required and register dies. Similarly for 128 to -128.
17120 (define_peephole2
17121 [(set (match_operand 0 "flags_reg_operand" "")
17122 (match_operator 1 "compare_operator"
17123 [(match_operand 2 "register_operand" "")
17124 (match_operand 3 "const_int_operand" "")]))]
17125 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17126 && incdec_operand (operands[3], GET_MODE (operands[3])))
17127 || (!TARGET_FUSE_CMP_AND_BRANCH
17128 && INTVAL (operands[3]) == 128))
17129 && ix86_match_ccmode (insn, CCGCmode)
17130 && peep2_reg_dead_p (1, operands[2])"
17131 [(parallel [(set (match_dup 0)
17132 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17133 (clobber (match_dup 2))])])
17134 \f
17135 ;; Convert imul by three, five and nine into lea
17136 (define_peephole2
17137 [(parallel
17138 [(set (match_operand:SWI48 0 "register_operand" "")
17139 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17140 (match_operand:SWI48 2 "const359_operand" "")))
17141 (clobber (reg:CC FLAGS_REG))])]
17142 "!TARGET_PARTIAL_REG_STALL
17143 || <MODE>mode == SImode
17144 || optimize_function_for_size_p (cfun)"
17145 [(set (match_dup 0)
17146 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17147 (match_dup 1)))]
17148 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17149
17150 (define_peephole2
17151 [(parallel
17152 [(set (match_operand:SWI48 0 "register_operand" "")
17153 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17154 (match_operand:SWI48 2 "const359_operand" "")))
17155 (clobber (reg:CC FLAGS_REG))])]
17156 "optimize_insn_for_speed_p ()
17157 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17158 [(set (match_dup 0) (match_dup 1))
17159 (set (match_dup 0)
17160 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17161 (match_dup 0)))]
17162 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17163
17164 ;; imul $32bit_imm, mem, reg is vector decoded, while
17165 ;; imul $32bit_imm, reg, reg is direct decoded.
17166 (define_peephole2
17167 [(match_scratch:SWI48 3 "r")
17168 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17169 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17170 (match_operand:SWI48 2 "immediate_operand" "")))
17171 (clobber (reg:CC FLAGS_REG))])]
17172 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17173 && !satisfies_constraint_K (operands[2])"
17174 [(set (match_dup 3) (match_dup 1))
17175 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17176 (clobber (reg:CC FLAGS_REG))])])
17177
17178 (define_peephole2
17179 [(match_scratch:SI 3 "r")
17180 (parallel [(set (match_operand:DI 0 "register_operand" "")
17181 (zero_extend:DI
17182 (mult:SI (match_operand:SI 1 "memory_operand" "")
17183 (match_operand:SI 2 "immediate_operand" ""))))
17184 (clobber (reg:CC FLAGS_REG))])]
17185 "TARGET_64BIT
17186 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17187 && !satisfies_constraint_K (operands[2])"
17188 [(set (match_dup 3) (match_dup 1))
17189 (parallel [(set (match_dup 0)
17190 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17191 (clobber (reg:CC FLAGS_REG))])])
17192
17193 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17194 ;; Convert it into imul reg, reg
17195 ;; It would be better to force assembler to encode instruction using long
17196 ;; immediate, but there is apparently no way to do so.
17197 (define_peephole2
17198 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17199 (mult:SWI248
17200 (match_operand:SWI248 1 "nonimmediate_operand" "")
17201 (match_operand:SWI248 2 "const_int_operand" "")))
17202 (clobber (reg:CC FLAGS_REG))])
17203 (match_scratch:SWI248 3 "r")]
17204 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17205 && satisfies_constraint_K (operands[2])"
17206 [(set (match_dup 3) (match_dup 2))
17207 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17208 (clobber (reg:CC FLAGS_REG))])]
17209 {
17210 if (!rtx_equal_p (operands[0], operands[1]))
17211 emit_move_insn (operands[0], operands[1]);
17212 })
17213
17214 ;; After splitting up read-modify operations, array accesses with memory
17215 ;; operands might end up in form:
17216 ;; sall $2, %eax
17217 ;; movl 4(%esp), %edx
17218 ;; addl %edx, %eax
17219 ;; instead of pre-splitting:
17220 ;; sall $2, %eax
17221 ;; addl 4(%esp), %eax
17222 ;; Turn it into:
17223 ;; movl 4(%esp), %edx
17224 ;; leal (%edx,%eax,4), %eax
17225
17226 (define_peephole2
17227 [(match_scratch:P 5 "r")
17228 (parallel [(set (match_operand 0 "register_operand" "")
17229 (ashift (match_operand 1 "register_operand" "")
17230 (match_operand 2 "const_int_operand" "")))
17231 (clobber (reg:CC FLAGS_REG))])
17232 (parallel [(set (match_operand 3 "register_operand" "")
17233 (plus (match_dup 0)
17234 (match_operand 4 "x86_64_general_operand" "")))
17235 (clobber (reg:CC FLAGS_REG))])]
17236 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17237 /* Validate MODE for lea. */
17238 && ((!TARGET_PARTIAL_REG_STALL
17239 && (GET_MODE (operands[0]) == QImode
17240 || GET_MODE (operands[0]) == HImode))
17241 || GET_MODE (operands[0]) == SImode
17242 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17243 && (rtx_equal_p (operands[0], operands[3])
17244 || peep2_reg_dead_p (2, operands[0]))
17245 /* We reorder load and the shift. */
17246 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17247 [(set (match_dup 5) (match_dup 4))
17248 (set (match_dup 0) (match_dup 1))]
17249 {
17250 enum machine_mode op1mode = GET_MODE (operands[1]);
17251 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17252 int scale = 1 << INTVAL (operands[2]);
17253 rtx index = gen_lowpart (Pmode, operands[1]);
17254 rtx base = gen_lowpart (Pmode, operands[5]);
17255 rtx dest = gen_lowpart (mode, operands[3]);
17256
17257 operands[1] = gen_rtx_PLUS (Pmode, base,
17258 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17259 operands[5] = base;
17260 if (mode != Pmode)
17261 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17262 if (op1mode != Pmode)
17263 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17264 operands[0] = dest;
17265 })
17266 \f
17267 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17268 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17269 ;; caught for use by garbage collectors and the like. Using an insn that
17270 ;; maps to SIGILL makes it more likely the program will rightfully die.
17271 ;; Keeping with tradition, "6" is in honor of #UD.
17272 (define_insn "trap"
17273 [(trap_if (const_int 1) (const_int 6))]
17274 ""
17275 { return ASM_SHORT "0x0b0f"; }
17276 [(set_attr "length" "2")])
17277
17278 (define_expand "prefetch"
17279 [(prefetch (match_operand 0 "address_operand" "")
17280 (match_operand:SI 1 "const_int_operand" "")
17281 (match_operand:SI 2 "const_int_operand" ""))]
17282 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17283 {
17284 int rw = INTVAL (operands[1]);
17285 int locality = INTVAL (operands[2]);
17286
17287 gcc_assert (rw == 0 || rw == 1);
17288 gcc_assert (locality >= 0 && locality <= 3);
17289 gcc_assert (GET_MODE (operands[0]) == Pmode
17290 || GET_MODE (operands[0]) == VOIDmode);
17291
17292 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17293 supported by SSE counterpart or the SSE prefetch is not available
17294 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17295 of locality. */
17296 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17297 operands[2] = GEN_INT (3);
17298 else
17299 operands[1] = const0_rtx;
17300 })
17301
17302 (define_insn "*prefetch_sse_<mode>"
17303 [(prefetch (match_operand:P 0 "address_operand" "p")
17304 (const_int 0)
17305 (match_operand:SI 1 "const_int_operand" ""))]
17306 "TARGET_PREFETCH_SSE"
17307 {
17308 static const char * const patterns[4] = {
17309 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17310 };
17311
17312 int locality = INTVAL (operands[1]);
17313 gcc_assert (locality >= 0 && locality <= 3);
17314
17315 return patterns[locality];
17316 }
17317 [(set_attr "type" "sse")
17318 (set_attr "atom_sse_attr" "prefetch")
17319 (set (attr "length_address")
17320 (symbol_ref "memory_address_length (operands[0])"))
17321 (set_attr "memory" "none")])
17322
17323 (define_insn "*prefetch_3dnow_<mode>"
17324 [(prefetch (match_operand:P 0 "address_operand" "p")
17325 (match_operand:SI 1 "const_int_operand" "n")
17326 (const_int 3))]
17327 "TARGET_3DNOW"
17328 {
17329 if (INTVAL (operands[1]) == 0)
17330 return "prefetch\t%a0";
17331 else
17332 return "prefetchw\t%a0";
17333 }
17334 [(set_attr "type" "mmx")
17335 (set (attr "length_address")
17336 (symbol_ref "memory_address_length (operands[0])"))
17337 (set_attr "memory" "none")])
17338
17339 (define_expand "stack_protect_set"
17340 [(match_operand 0 "memory_operand" "")
17341 (match_operand 1 "memory_operand" "")]
17342 ""
17343 {
17344 rtx (*insn)(rtx, rtx);
17345
17346 #ifdef TARGET_THREAD_SSP_OFFSET
17347 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17348 insn = (TARGET_64BIT
17349 ? gen_stack_tls_protect_set_di
17350 : gen_stack_tls_protect_set_si);
17351 #else
17352 insn = (TARGET_64BIT
17353 ? gen_stack_protect_set_di
17354 : gen_stack_protect_set_si);
17355 #endif
17356
17357 emit_insn (insn (operands[0], operands[1]));
17358 DONE;
17359 })
17360
17361 (define_insn "stack_protect_set_<mode>"
17362 [(set (match_operand:P 0 "memory_operand" "=m")
17363 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17364 (set (match_scratch:P 2 "=&r") (const_int 0))
17365 (clobber (reg:CC FLAGS_REG))]
17366 ""
17367 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17368 [(set_attr "type" "multi")])
17369
17370 (define_insn "stack_tls_protect_set_<mode>"
17371 [(set (match_operand:P 0 "memory_operand" "=m")
17372 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17373 UNSPEC_SP_TLS_SET))
17374 (set (match_scratch:P 2 "=&r") (const_int 0))
17375 (clobber (reg:CC FLAGS_REG))]
17376 ""
17377 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17378 [(set_attr "type" "multi")])
17379
17380 (define_expand "stack_protect_test"
17381 [(match_operand 0 "memory_operand" "")
17382 (match_operand 1 "memory_operand" "")
17383 (match_operand 2 "" "")]
17384 ""
17385 {
17386 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17387
17388 rtx (*insn)(rtx, rtx, rtx);
17389
17390 #ifdef TARGET_THREAD_SSP_OFFSET
17391 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17392 insn = (TARGET_64BIT
17393 ? gen_stack_tls_protect_test_di
17394 : gen_stack_tls_protect_test_si);
17395 #else
17396 insn = (TARGET_64BIT
17397 ? gen_stack_protect_test_di
17398 : gen_stack_protect_test_si);
17399 #endif
17400
17401 emit_insn (insn (flags, operands[0], operands[1]));
17402
17403 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17404 flags, const0_rtx, operands[2]));
17405 DONE;
17406 })
17407
17408 (define_insn "stack_protect_test_<mode>"
17409 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17410 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17411 (match_operand:P 2 "memory_operand" "m")]
17412 UNSPEC_SP_TEST))
17413 (clobber (match_scratch:P 3 "=&r"))]
17414 ""
17415 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17416 [(set_attr "type" "multi")])
17417
17418 (define_insn "stack_tls_protect_test_<mode>"
17419 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17420 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17421 (match_operand:P 2 "const_int_operand" "i")]
17422 UNSPEC_SP_TLS_TEST))
17423 (clobber (match_scratch:P 3 "=r"))]
17424 ""
17425 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17426 [(set_attr "type" "multi")])
17427
17428 (define_insn "sse4_2_crc32<mode>"
17429 [(set (match_operand:SI 0 "register_operand" "=r")
17430 (unspec:SI
17431 [(match_operand:SI 1 "register_operand" "0")
17432 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17433 UNSPEC_CRC32))]
17434 "TARGET_SSE4_2 || TARGET_CRC32"
17435 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17436 [(set_attr "type" "sselog1")
17437 (set_attr "prefix_rep" "1")
17438 (set_attr "prefix_extra" "1")
17439 (set (attr "prefix_data16")
17440 (if_then_else (match_operand:HI 2 "" "")
17441 (const_string "1")
17442 (const_string "*")))
17443 (set (attr "prefix_rex")
17444 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17445 (const_string "1")
17446 (const_string "*")))
17447 (set_attr "mode" "SI")])
17448
17449 (define_insn "sse4_2_crc32di"
17450 [(set (match_operand:DI 0 "register_operand" "=r")
17451 (unspec:DI
17452 [(match_operand:DI 1 "register_operand" "0")
17453 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17454 UNSPEC_CRC32))]
17455 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17456 "crc32{q}\t{%2, %0|%0, %2}"
17457 [(set_attr "type" "sselog1")
17458 (set_attr "prefix_rep" "1")
17459 (set_attr "prefix_extra" "1")
17460 (set_attr "mode" "DI")])
17461
17462 (define_expand "rdpmc"
17463 [(match_operand:DI 0 "register_operand" "")
17464 (match_operand:SI 1 "register_operand" "")]
17465 ""
17466 {
17467 rtx reg = gen_reg_rtx (DImode);
17468 rtx si;
17469
17470 /* Force operand 1 into ECX. */
17471 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17472 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17473 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17474 UNSPECV_RDPMC);
17475
17476 if (TARGET_64BIT)
17477 {
17478 rtvec vec = rtvec_alloc (2);
17479 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17480 rtx upper = gen_reg_rtx (DImode);
17481 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17482 gen_rtvec (1, const0_rtx),
17483 UNSPECV_RDPMC);
17484 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17485 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17486 emit_insn (load);
17487 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17488 NULL, 1, OPTAB_DIRECT);
17489 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17490 OPTAB_DIRECT);
17491 }
17492 else
17493 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17494 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17495 DONE;
17496 })
17497
17498 (define_insn "*rdpmc"
17499 [(set (match_operand:DI 0 "register_operand" "=A")
17500 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17501 UNSPECV_RDPMC))]
17502 "!TARGET_64BIT"
17503 "rdpmc"
17504 [(set_attr "type" "other")
17505 (set_attr "length" "2")])
17506
17507 (define_insn "*rdpmc_rex64"
17508 [(set (match_operand:DI 0 "register_operand" "=a")
17509 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17510 UNSPECV_RDPMC))
17511 (set (match_operand:DI 1 "register_operand" "=d")
17512 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17513 "TARGET_64BIT"
17514 "rdpmc"
17515 [(set_attr "type" "other")
17516 (set_attr "length" "2")])
17517
17518 (define_expand "rdtsc"
17519 [(set (match_operand:DI 0 "register_operand" "")
17520 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17521 ""
17522 {
17523 if (TARGET_64BIT)
17524 {
17525 rtvec vec = rtvec_alloc (2);
17526 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17527 rtx upper = gen_reg_rtx (DImode);
17528 rtx lower = gen_reg_rtx (DImode);
17529 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17530 gen_rtvec (1, const0_rtx),
17531 UNSPECV_RDTSC);
17532 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17533 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17534 emit_insn (load);
17535 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17536 NULL, 1, OPTAB_DIRECT);
17537 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17538 OPTAB_DIRECT);
17539 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17540 DONE;
17541 }
17542 })
17543
17544 (define_insn "*rdtsc"
17545 [(set (match_operand:DI 0 "register_operand" "=A")
17546 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17547 "!TARGET_64BIT"
17548 "rdtsc"
17549 [(set_attr "type" "other")
17550 (set_attr "length" "2")])
17551
17552 (define_insn "*rdtsc_rex64"
17553 [(set (match_operand:DI 0 "register_operand" "=a")
17554 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17555 (set (match_operand:DI 1 "register_operand" "=d")
17556 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17557 "TARGET_64BIT"
17558 "rdtsc"
17559 [(set_attr "type" "other")
17560 (set_attr "length" "2")])
17561
17562 (define_expand "rdtscp"
17563 [(match_operand:DI 0 "register_operand" "")
17564 (match_operand:SI 1 "memory_operand" "")]
17565 ""
17566 {
17567 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17568 gen_rtvec (1, const0_rtx),
17569 UNSPECV_RDTSCP);
17570 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17571 gen_rtvec (1, const0_rtx),
17572 UNSPECV_RDTSCP);
17573 rtx reg = gen_reg_rtx (DImode);
17574 rtx tmp = gen_reg_rtx (SImode);
17575
17576 if (TARGET_64BIT)
17577 {
17578 rtvec vec = rtvec_alloc (3);
17579 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17580 rtx upper = gen_reg_rtx (DImode);
17581 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17582 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17583 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17584 emit_insn (load);
17585 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17586 NULL, 1, OPTAB_DIRECT);
17587 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17588 OPTAB_DIRECT);
17589 }
17590 else
17591 {
17592 rtvec vec = rtvec_alloc (2);
17593 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17594 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17595 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17596 emit_insn (load);
17597 }
17598 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17599 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17600 DONE;
17601 })
17602
17603 (define_insn "*rdtscp"
17604 [(set (match_operand:DI 0 "register_operand" "=A")
17605 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17606 (set (match_operand:SI 1 "register_operand" "=c")
17607 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17608 "!TARGET_64BIT"
17609 "rdtscp"
17610 [(set_attr "type" "other")
17611 (set_attr "length" "3")])
17612
17613 (define_insn "*rdtscp_rex64"
17614 [(set (match_operand:DI 0 "register_operand" "=a")
17615 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17616 (set (match_operand:DI 1 "register_operand" "=d")
17617 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17618 (set (match_operand:SI 2 "register_operand" "=c")
17619 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17620 "TARGET_64BIT"
17621 "rdtscp"
17622 [(set_attr "type" "other")
17623 (set_attr "length" "3")])
17624
17625 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17626 ;;
17627 ;; LWP instructions
17628 ;;
17629 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17630
17631 (define_expand "lwp_llwpcb"
17632 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17633 UNSPECV_LLWP_INTRINSIC)]
17634 "TARGET_LWP")
17635
17636 (define_insn "*lwp_llwpcb<mode>1"
17637 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17638 UNSPECV_LLWP_INTRINSIC)]
17639 "TARGET_LWP"
17640 "llwpcb\t%0"
17641 [(set_attr "type" "lwp")
17642 (set_attr "mode" "<MODE>")
17643 (set_attr "length" "5")])
17644
17645 (define_expand "lwp_slwpcb"
17646 [(set (match_operand 0 "register_operand" "=r")
17647 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17648 "TARGET_LWP"
17649 {
17650 rtx (*insn)(rtx);
17651
17652 insn = (TARGET_64BIT
17653 ? gen_lwp_slwpcbdi
17654 : gen_lwp_slwpcbsi);
17655
17656 emit_insn (insn (operands[0]));
17657 DONE;
17658 })
17659
17660 (define_insn "lwp_slwpcb<mode>"
17661 [(set (match_operand:P 0 "register_operand" "=r")
17662 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17663 "TARGET_LWP"
17664 "slwpcb\t%0"
17665 [(set_attr "type" "lwp")
17666 (set_attr "mode" "<MODE>")
17667 (set_attr "length" "5")])
17668
17669 (define_expand "lwp_lwpval<mode>3"
17670 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17671 (match_operand:SI 2 "nonimmediate_operand" "rm")
17672 (match_operand:SI 3 "const_int_operand" "i")]
17673 UNSPECV_LWPVAL_INTRINSIC)]
17674 "TARGET_LWP"
17675 "/* Avoid unused variable warning. */
17676 (void) operand0;")
17677
17678 (define_insn "*lwp_lwpval<mode>3_1"
17679 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17680 (match_operand:SI 1 "nonimmediate_operand" "rm")
17681 (match_operand:SI 2 "const_int_operand" "i")]
17682 UNSPECV_LWPVAL_INTRINSIC)]
17683 "TARGET_LWP"
17684 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17685 [(set_attr "type" "lwp")
17686 (set_attr "mode" "<MODE>")
17687 (set (attr "length")
17688 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17689
17690 (define_expand "lwp_lwpins<mode>3"
17691 [(set (reg:CCC FLAGS_REG)
17692 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17693 (match_operand:SI 2 "nonimmediate_operand" "rm")
17694 (match_operand:SI 3 "const_int_operand" "i")]
17695 UNSPECV_LWPINS_INTRINSIC))
17696 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17697 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17698 "TARGET_LWP")
17699
17700 (define_insn "*lwp_lwpins<mode>3_1"
17701 [(set (reg:CCC FLAGS_REG)
17702 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17703 (match_operand:SI 1 "nonimmediate_operand" "rm")
17704 (match_operand:SI 2 "const_int_operand" "i")]
17705 UNSPECV_LWPINS_INTRINSIC))]
17706 "TARGET_LWP"
17707 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17708 [(set_attr "type" "lwp")
17709 (set_attr "mode" "<MODE>")
17710 (set (attr "length")
17711 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17712
17713 (define_insn "rdfsbase<mode>"
17714 [(set (match_operand:SWI48 0 "register_operand" "=r")
17715 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17716 "TARGET_64BIT && TARGET_FSGSBASE"
17717 "rdfsbase %0"
17718 [(set_attr "type" "other")
17719 (set_attr "prefix_extra" "2")])
17720
17721 (define_insn "rdgsbase<mode>"
17722 [(set (match_operand:SWI48 0 "register_operand" "=r")
17723 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17724 "TARGET_64BIT && TARGET_FSGSBASE"
17725 "rdgsbase %0"
17726 [(set_attr "type" "other")
17727 (set_attr "prefix_extra" "2")])
17728
17729 (define_insn "wrfsbase<mode>"
17730 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17731 UNSPECV_WRFSBASE)]
17732 "TARGET_64BIT && TARGET_FSGSBASE"
17733 "wrfsbase %0"
17734 [(set_attr "type" "other")
17735 (set_attr "prefix_extra" "2")])
17736
17737 (define_insn "wrgsbase<mode>"
17738 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17739 UNSPECV_WRGSBASE)]
17740 "TARGET_64BIT && TARGET_FSGSBASE"
17741 "wrgsbase %0"
17742 [(set_attr "type" "other")
17743 (set_attr "prefix_extra" "2")])
17744
17745 (define_insn "rdrand<mode>_1"
17746 [(set (match_operand:SWI248 0 "register_operand" "=r")
17747 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17748 (set (reg:CCC FLAGS_REG)
17749 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17750 "TARGET_RDRND"
17751 "rdrand\t%0"
17752 [(set_attr "type" "other")
17753 (set_attr "prefix_extra" "1")])
17754
17755 (define_expand "pause"
17756 [(set (match_dup 0)
17757 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17758 ""
17759 {
17760 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17761 MEM_VOLATILE_P (operands[0]) = 1;
17762 })
17763
17764 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17765 ;; They have the same encoding.
17766 (define_insn "*pause"
17767 [(set (match_operand:BLK 0 "" "")
17768 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17769 ""
17770 "rep; nop"
17771 [(set_attr "length" "2")
17772 (set_attr "memory" "unknown")])
17773
17774 (include "mmx.md")
17775 (include "sse.md")
17776 (include "sync.md")