i386.md (splitters for int-float conversion): Use reg_or_subregno in splitter constra...
[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 AVX2 support
235 UNSPEC_VPERMSI
236 UNSPEC_VPERMDF
237 UNSPEC_VPERMSF
238 UNSPEC_VPERMTI
239 UNSPEC_GATHER
240 UNSPEC_VSIBADDR
241
242 ;; For BMI support
243 UNSPEC_BEXTR
244
245 ;; For RDRAND support
246 UNSPEC_RDRAND
247
248 ;; For BMI2 support
249 UNSPEC_PDEP
250 UNSPEC_PEXT
251 ])
252
253 (define_c_enum "unspecv" [
254 UNSPECV_BLOCKAGE
255 UNSPECV_STACK_PROBE
256 UNSPECV_PROBE_STACK_RANGE
257 UNSPECV_EMMS
258 UNSPECV_LDMXCSR
259 UNSPECV_STMXCSR
260 UNSPECV_FEMMS
261 UNSPECV_CLFLUSH
262 UNSPECV_ALIGN
263 UNSPECV_MONITOR
264 UNSPECV_MWAIT
265 UNSPECV_CMPXCHG
266 UNSPECV_XCHG
267 UNSPECV_LOCK
268 UNSPECV_PROLOGUE_USE
269 UNSPECV_CLD
270 UNSPECV_NOPS
271 UNSPECV_VZEROALL
272 UNSPECV_VZEROUPPER
273 UNSPECV_RDTSC
274 UNSPECV_RDTSCP
275 UNSPECV_RDPMC
276 UNSPECV_LLWP_INTRINSIC
277 UNSPECV_SLWP_INTRINSIC
278 UNSPECV_LWPVAL_INTRINSIC
279 UNSPECV_LWPINS_INTRINSIC
280 UNSPECV_RDFSBASE
281 UNSPECV_RDGSBASE
282 UNSPECV_WRFSBASE
283 UNSPECV_WRGSBASE
284 UNSPECV_SPLIT_STACK_RETURN
285 ])
286
287 ;; Constants to represent rounding modes in the ROUND instruction
288 (define_constants
289 [(ROUND_FLOOR 0x1)
290 (ROUND_CEIL 0x2)
291 (ROUND_TRUNC 0x3)
292 (ROUND_MXCSR 0x4)
293 (ROUND_NO_EXC 0x8)
294 ])
295
296 ;; Constants to represent pcomtrue/pcomfalse variants
297 (define_constants
298 [(PCOM_FALSE 0)
299 (PCOM_TRUE 1)
300 (COM_FALSE_S 2)
301 (COM_FALSE_P 3)
302 (COM_TRUE_S 4)
303 (COM_TRUE_P 5)
304 ])
305
306 ;; Constants used in the XOP pperm instruction
307 (define_constants
308 [(PPERM_SRC 0x00) /* copy source */
309 (PPERM_INVERT 0x20) /* invert source */
310 (PPERM_REVERSE 0x40) /* bit reverse source */
311 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
312 (PPERM_ZERO 0x80) /* all 0's */
313 (PPERM_ONES 0xa0) /* all 1's */
314 (PPERM_SIGN 0xc0) /* propagate sign bit */
315 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
316 (PPERM_SRC1 0x00) /* use first source byte */
317 (PPERM_SRC2 0x10) /* use second source byte */
318 ])
319
320 ;; Registers by name.
321 (define_constants
322 [(AX_REG 0)
323 (DX_REG 1)
324 (CX_REG 2)
325 (BX_REG 3)
326 (SI_REG 4)
327 (DI_REG 5)
328 (BP_REG 6)
329 (SP_REG 7)
330 (ST0_REG 8)
331 (ST1_REG 9)
332 (ST2_REG 10)
333 (ST3_REG 11)
334 (ST4_REG 12)
335 (ST5_REG 13)
336 (ST6_REG 14)
337 (ST7_REG 15)
338 (FLAGS_REG 17)
339 (FPSR_REG 18)
340 (FPCR_REG 19)
341 (XMM0_REG 21)
342 (XMM1_REG 22)
343 (XMM2_REG 23)
344 (XMM3_REG 24)
345 (XMM4_REG 25)
346 (XMM5_REG 26)
347 (XMM6_REG 27)
348 (XMM7_REG 28)
349 (MM0_REG 29)
350 (MM1_REG 30)
351 (MM2_REG 31)
352 (MM3_REG 32)
353 (MM4_REG 33)
354 (MM5_REG 34)
355 (MM6_REG 35)
356 (MM7_REG 36)
357 (R8_REG 37)
358 (R9_REG 38)
359 (R10_REG 39)
360 (R11_REG 40)
361 (R12_REG 41)
362 (R13_REG 42)
363 (XMM8_REG 45)
364 (XMM9_REG 46)
365 (XMM10_REG 47)
366 (XMM11_REG 48)
367 (XMM12_REG 49)
368 (XMM13_REG 50)
369 (XMM14_REG 51)
370 (XMM15_REG 52)
371 ])
372
373 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
374 ;; from i386.c.
375
376 ;; In C guard expressions, put expressions which may be compile-time
377 ;; constants first. This allows for better optimization. For
378 ;; example, write "TARGET_64BIT && reload_completed", not
379 ;; "reload_completed && TARGET_64BIT".
380
381 \f
382 ;; Processor type.
383 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
384 atom,generic64,amdfam10,bdver1,bdver2,btver1"
385 (const (symbol_ref "ix86_schedule")))
386
387 ;; A basic instruction type. Refinements due to arguments to be
388 ;; provided in other attributes.
389 (define_attr "type"
390 "other,multi,
391 alu,alu1,negnot,imov,imovx,lea,
392 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
393 icmp,test,ibr,setcc,icmov,
394 push,pop,call,callv,leave,
395 str,bitmanip,
396 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
397 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
398 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
399 ssemuladd,sse4arg,lwp,
400 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
401 (const_string "other"))
402
403 ;; Main data type used by the insn
404 (define_attr "mode"
405 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
406 (const_string "unknown"))
407
408 ;; The CPU unit operations uses.
409 (define_attr "unit" "integer,i387,sse,mmx,unknown"
410 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
411 (const_string "i387")
412 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
413 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
414 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
415 (const_string "sse")
416 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
417 (const_string "mmx")
418 (eq_attr "type" "other")
419 (const_string "unknown")]
420 (const_string "integer")))
421
422 ;; The (bounding maximum) length of an instruction immediate.
423 (define_attr "length_immediate" ""
424 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
425 bitmanip,imulx")
426 (const_int 0)
427 (eq_attr "unit" "i387,sse,mmx")
428 (const_int 0)
429 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
430 rotate,rotatex,rotate1,imul,icmp,push,pop")
431 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
432 (eq_attr "type" "imov,test")
433 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
434 (eq_attr "type" "call")
435 (if_then_else (match_operand 0 "constant_call_address_operand" "")
436 (const_int 4)
437 (const_int 0))
438 (eq_attr "type" "callv")
439 (if_then_else (match_operand 1 "constant_call_address_operand" "")
440 (const_int 4)
441 (const_int 0))
442 ;; We don't know the size before shorten_branches. Expect
443 ;; the instruction to fit for better scheduling.
444 (eq_attr "type" "ibr")
445 (const_int 1)
446 ]
447 (symbol_ref "/* Update immediate_length and other attributes! */
448 gcc_unreachable (),1")))
449
450 ;; The (bounding maximum) length of an instruction address.
451 (define_attr "length_address" ""
452 (cond [(eq_attr "type" "str,other,multi,fxch")
453 (const_int 0)
454 (and (eq_attr "type" "call")
455 (match_operand 0 "constant_call_address_operand" ""))
456 (const_int 0)
457 (and (eq_attr "type" "callv")
458 (match_operand 1 "constant_call_address_operand" ""))
459 (const_int 0)
460 ]
461 (symbol_ref "ix86_attr_length_address_default (insn)")))
462
463 ;; Set when length prefix is used.
464 (define_attr "prefix_data16" ""
465 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
466 (const_int 0)
467 (eq_attr "mode" "HI")
468 (const_int 1)
469 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
470 (const_int 1)
471 ]
472 (const_int 0)))
473
474 ;; Set when string REP prefix is used.
475 (define_attr "prefix_rep" ""
476 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
477 (const_int 0)
478 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
479 (const_int 1)
480 ]
481 (const_int 0)))
482
483 ;; Set when 0f opcode prefix is used.
484 (define_attr "prefix_0f" ""
485 (if_then_else
486 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
487 (eq_attr "unit" "sse,mmx"))
488 (const_int 1)
489 (const_int 0)))
490
491 ;; Set when REX opcode prefix is used.
492 (define_attr "prefix_rex" ""
493 (cond [(not (match_test "TARGET_64BIT"))
494 (const_int 0)
495 (and (eq_attr "mode" "DI")
496 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
497 (eq_attr "unit" "!mmx")))
498 (const_int 1)
499 (and (eq_attr "mode" "QI")
500 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
501 (const_int 1)
502 (match_test "x86_extended_reg_mentioned_p (insn)")
503 (const_int 1)
504 (and (eq_attr "type" "imovx")
505 (match_operand:QI 1 "ext_QIreg_operand" ""))
506 (const_int 1)
507 ]
508 (const_int 0)))
509
510 ;; There are also additional prefixes in 3DNOW, SSSE3.
511 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
512 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
513 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
514 (define_attr "prefix_extra" ""
515 (cond [(eq_attr "type" "ssemuladd,sse4arg")
516 (const_int 2)
517 (eq_attr "type" "sseiadd1,ssecvt1")
518 (const_int 1)
519 ]
520 (const_int 0)))
521
522 ;; Prefix used: original, VEX or maybe VEX.
523 (define_attr "prefix" "orig,vex,maybe_vex"
524 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
525 (const_string "vex")
526 (const_string "orig")))
527
528 ;; VEX W bit is used.
529 (define_attr "prefix_vex_w" "" (const_int 0))
530
531 ;; The length of VEX prefix
532 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
533 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
534 ;; still prefix_0f 1, with prefix_extra 1.
535 (define_attr "length_vex" ""
536 (if_then_else (and (eq_attr "prefix_0f" "1")
537 (eq_attr "prefix_extra" "0"))
538 (if_then_else (eq_attr "prefix_vex_w" "1")
539 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
540 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
541 (if_then_else (eq_attr "prefix_vex_w" "1")
542 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
543 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
544
545 ;; Set when modrm byte is used.
546 (define_attr "modrm" ""
547 (cond [(eq_attr "type" "str,leave")
548 (const_int 0)
549 (eq_attr "unit" "i387")
550 (const_int 0)
551 (and (eq_attr "type" "incdec")
552 (and (not (match_test "TARGET_64BIT"))
553 (ior (match_operand:SI 1 "register_operand" "")
554 (match_operand:HI 1 "register_operand" ""))))
555 (const_int 0)
556 (and (eq_attr "type" "push")
557 (not (match_operand 1 "memory_operand" "")))
558 (const_int 0)
559 (and (eq_attr "type" "pop")
560 (not (match_operand 0 "memory_operand" "")))
561 (const_int 0)
562 (and (eq_attr "type" "imov")
563 (and (not (eq_attr "mode" "DI"))
564 (ior (and (match_operand 0 "register_operand" "")
565 (match_operand 1 "immediate_operand" ""))
566 (ior (and (match_operand 0 "ax_reg_operand" "")
567 (match_operand 1 "memory_displacement_only_operand" ""))
568 (and (match_operand 0 "memory_displacement_only_operand" "")
569 (match_operand 1 "ax_reg_operand" ""))))))
570 (const_int 0)
571 (and (eq_attr "type" "call")
572 (match_operand 0 "constant_call_address_operand" ""))
573 (const_int 0)
574 (and (eq_attr "type" "callv")
575 (match_operand 1 "constant_call_address_operand" ""))
576 (const_int 0)
577 (and (eq_attr "type" "alu,alu1,icmp,test")
578 (match_operand 0 "ax_reg_operand" ""))
579 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
580 ]
581 (const_int 1)))
582
583 ;; The (bounding maximum) length of an instruction in bytes.
584 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
585 ;; Later we may want to split them and compute proper length as for
586 ;; other insns.
587 (define_attr "length" ""
588 (cond [(eq_attr "type" "other,multi,fistp,frndint")
589 (const_int 16)
590 (eq_attr "type" "fcmp")
591 (const_int 4)
592 (eq_attr "unit" "i387")
593 (plus (const_int 2)
594 (plus (attr "prefix_data16")
595 (attr "length_address")))
596 (ior (eq_attr "prefix" "vex")
597 (and (eq_attr "prefix" "maybe_vex")
598 (match_test "TARGET_AVX")))
599 (plus (attr "length_vex")
600 (plus (attr "length_immediate")
601 (plus (attr "modrm")
602 (attr "length_address"))))]
603 (plus (plus (attr "modrm")
604 (plus (attr "prefix_0f")
605 (plus (attr "prefix_rex")
606 (plus (attr "prefix_extra")
607 (const_int 1)))))
608 (plus (attr "prefix_rep")
609 (plus (attr "prefix_data16")
610 (plus (attr "length_immediate")
611 (attr "length_address")))))))
612
613 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
614 ;; `store' if there is a simple memory reference therein, or `unknown'
615 ;; if the instruction is complex.
616
617 (define_attr "memory" "none,load,store,both,unknown"
618 (cond [(eq_attr "type" "other,multi,str,lwp")
619 (const_string "unknown")
620 (eq_attr "type" "lea,fcmov,fpspc")
621 (const_string "none")
622 (eq_attr "type" "fistp,leave")
623 (const_string "both")
624 (eq_attr "type" "frndint")
625 (const_string "load")
626 (eq_attr "type" "push")
627 (if_then_else (match_operand 1 "memory_operand" "")
628 (const_string "both")
629 (const_string "store"))
630 (eq_attr "type" "pop")
631 (if_then_else (match_operand 0 "memory_operand" "")
632 (const_string "both")
633 (const_string "load"))
634 (eq_attr "type" "setcc")
635 (if_then_else (match_operand 0 "memory_operand" "")
636 (const_string "store")
637 (const_string "none"))
638 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
639 (if_then_else (ior (match_operand 0 "memory_operand" "")
640 (match_operand 1 "memory_operand" ""))
641 (const_string "load")
642 (const_string "none"))
643 (eq_attr "type" "ibr")
644 (if_then_else (match_operand 0 "memory_operand" "")
645 (const_string "load")
646 (const_string "none"))
647 (eq_attr "type" "call")
648 (if_then_else (match_operand 0 "constant_call_address_operand" "")
649 (const_string "none")
650 (const_string "load"))
651 (eq_attr "type" "callv")
652 (if_then_else (match_operand 1 "constant_call_address_operand" "")
653 (const_string "none")
654 (const_string "load"))
655 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
656 (match_operand 1 "memory_operand" ""))
657 (const_string "both")
658 (and (match_operand 0 "memory_operand" "")
659 (match_operand 1 "memory_operand" ""))
660 (const_string "both")
661 (match_operand 0 "memory_operand" "")
662 (const_string "store")
663 (match_operand 1 "memory_operand" "")
664 (const_string "load")
665 (and (eq_attr "type"
666 "!alu1,negnot,ishift1,
667 imov,imovx,icmp,test,bitmanip,
668 fmov,fcmp,fsgn,
669 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
670 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
671 (match_operand 2 "memory_operand" ""))
672 (const_string "load")
673 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
674 (match_operand 3 "memory_operand" ""))
675 (const_string "load")
676 ]
677 (const_string "none")))
678
679 ;; Indicates if an instruction has both an immediate and a displacement.
680
681 (define_attr "imm_disp" "false,true,unknown"
682 (cond [(eq_attr "type" "other,multi")
683 (const_string "unknown")
684 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
685 (and (match_operand 0 "memory_displacement_operand" "")
686 (match_operand 1 "immediate_operand" "")))
687 (const_string "true")
688 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
689 (and (match_operand 0 "memory_displacement_operand" "")
690 (match_operand 2 "immediate_operand" "")))
691 (const_string "true")
692 ]
693 (const_string "false")))
694
695 ;; Indicates if an FP operation has an integer source.
696
697 (define_attr "fp_int_src" "false,true"
698 (const_string "false"))
699
700 ;; Defines rounding mode of an FP operation.
701
702 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
703 (const_string "any"))
704
705 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
706 (define_attr "use_carry" "0,1" (const_string "0"))
707
708 ;; Define attribute to indicate unaligned ssemov insns
709 (define_attr "movu" "0,1" (const_string "0"))
710
711 ;; Used to control the "enabled" attribute on a per-instruction basis.
712 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
713 (const_string "base"))
714
715 (define_attr "enabled" ""
716 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
717 (eq_attr "isa" "sse2_noavx")
718 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
719 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
720 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
721 (eq_attr "isa" "sse4_noavx")
722 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
723 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
724 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
725 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
726 ]
727 (const_int 1)))
728
729 ;; Describe a user's asm statement.
730 (define_asm_attributes
731 [(set_attr "length" "128")
732 (set_attr "type" "multi")])
733
734 (define_code_iterator plusminus [plus minus])
735
736 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
737
738 ;; Base name for define_insn
739 (define_code_attr plusminus_insn
740 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
741 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
742
743 ;; Base name for insn mnemonic.
744 (define_code_attr plusminus_mnemonic
745 [(plus "add") (ss_plus "adds") (us_plus "addus")
746 (minus "sub") (ss_minus "subs") (us_minus "subus")])
747 (define_code_attr plusminus_carry_mnemonic
748 [(plus "adc") (minus "sbb")])
749
750 ;; Mark commutative operators as such in constraints.
751 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
752 (minus "") (ss_minus "") (us_minus "")])
753
754 ;; Mapping of max and min
755 (define_code_iterator maxmin [smax smin umax umin])
756
757 ;; Mapping of signed max and min
758 (define_code_iterator smaxmin [smax smin])
759
760 ;; Mapping of unsigned max and min
761 (define_code_iterator umaxmin [umax umin])
762
763 ;; Base name for integer and FP insn mnemonic
764 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
765 (umax "maxu") (umin "minu")])
766 (define_code_attr maxmin_float [(smax "max") (smin "min")])
767
768 ;; Mapping of logic operators
769 (define_code_iterator any_logic [and ior xor])
770 (define_code_iterator any_or [ior xor])
771
772 ;; Base name for insn mnemonic.
773 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
774
775 ;; Mapping of logic-shift operators
776 (define_code_iterator any_lshift [ashift lshiftrt])
777
778 ;; Mapping of shift-right operators
779 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
780
781 ;; Base name for define_insn
782 (define_code_attr shift_insn
783 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
784
785 ;; Base name for insn mnemonic.
786 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
787 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
788
789 ;; Mapping of rotate operators
790 (define_code_iterator any_rotate [rotate rotatert])
791
792 ;; Base name for define_insn
793 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
794
795 ;; Base name for insn mnemonic.
796 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
797
798 ;; Mapping of abs neg operators
799 (define_code_iterator absneg [abs neg])
800
801 ;; Base name for x87 insn mnemonic.
802 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
803
804 ;; Used in signed and unsigned widening multiplications.
805 (define_code_iterator any_extend [sign_extend zero_extend])
806
807 ;; Prefix for insn menmonic.
808 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
809
810 ;; Prefix for define_insn
811 (define_code_attr u [(sign_extend "") (zero_extend "u")])
812 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
813
814 ;; All integer modes.
815 (define_mode_iterator SWI1248x [QI HI SI DI])
816
817 ;; All integer modes without QImode.
818 (define_mode_iterator SWI248x [HI SI DI])
819
820 ;; All integer modes without QImode and HImode.
821 (define_mode_iterator SWI48x [SI DI])
822
823 ;; All integer modes without SImode and DImode.
824 (define_mode_iterator SWI12 [QI HI])
825
826 ;; All integer modes without DImode.
827 (define_mode_iterator SWI124 [QI HI SI])
828
829 ;; All integer modes without QImode and DImode.
830 (define_mode_iterator SWI24 [HI SI])
831
832 ;; Single word integer modes.
833 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
834
835 ;; Single word integer modes without QImode.
836 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
837
838 ;; Single word integer modes without QImode and HImode.
839 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
840
841 ;; All math-dependant single and double word integer modes.
842 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
843 (HI "TARGET_HIMODE_MATH")
844 SI DI (TI "TARGET_64BIT")])
845
846 ;; Math-dependant single word integer modes.
847 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
848 (HI "TARGET_HIMODE_MATH")
849 SI (DI "TARGET_64BIT")])
850
851 ;; Math-dependant integer modes without DImode.
852 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
853 (HI "TARGET_HIMODE_MATH")
854 SI])
855
856 ;; Math-dependant single word integer modes without QImode.
857 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
858 SI (DI "TARGET_64BIT")])
859
860 ;; Double word integer modes.
861 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
862 (TI "TARGET_64BIT")])
863
864 ;; Double word integer modes as mode attribute.
865 (define_mode_attr DWI [(SI "DI") (DI "TI")])
866 (define_mode_attr dwi [(SI "di") (DI "ti")])
867
868 ;; Half mode for double word integer modes.
869 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
870 (DI "TARGET_64BIT")])
871
872 ;; Instruction suffix for integer modes.
873 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
874
875 ;; Pointer size prefix for integer modes (Intel asm dialect)
876 (define_mode_attr iptrsize [(QI "BYTE")
877 (HI "WORD")
878 (SI "DWORD")
879 (DI "QWORD")])
880
881 ;; Register class for integer modes.
882 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
883
884 ;; Immediate operand constraint for integer modes.
885 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
886
887 ;; General operand constraint for word modes.
888 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
889
890 ;; Immediate operand constraint for double integer modes.
891 (define_mode_attr di [(SI "nF") (DI "e")])
892
893 ;; Immediate operand constraint for shifts.
894 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
895
896 ;; General operand predicate for integer modes.
897 (define_mode_attr general_operand
898 [(QI "general_operand")
899 (HI "general_operand")
900 (SI "x86_64_general_operand")
901 (DI "x86_64_general_operand")
902 (TI "x86_64_general_operand")])
903
904 ;; General sign/zero extend operand predicate for integer modes.
905 (define_mode_attr general_szext_operand
906 [(QI "general_operand")
907 (HI "general_operand")
908 (SI "x86_64_szext_general_operand")
909 (DI "x86_64_szext_general_operand")])
910
911 ;; Immediate operand predicate for integer modes.
912 (define_mode_attr immediate_operand
913 [(QI "immediate_operand")
914 (HI "immediate_operand")
915 (SI "x86_64_immediate_operand")
916 (DI "x86_64_immediate_operand")])
917
918 ;; Nonmemory operand predicate for integer modes.
919 (define_mode_attr nonmemory_operand
920 [(QI "nonmemory_operand")
921 (HI "nonmemory_operand")
922 (SI "x86_64_nonmemory_operand")
923 (DI "x86_64_nonmemory_operand")])
924
925 ;; Operand predicate for shifts.
926 (define_mode_attr shift_operand
927 [(QI "nonimmediate_operand")
928 (HI "nonimmediate_operand")
929 (SI "nonimmediate_operand")
930 (DI "shiftdi_operand")
931 (TI "register_operand")])
932
933 ;; Operand predicate for shift argument.
934 (define_mode_attr shift_immediate_operand
935 [(QI "const_1_to_31_operand")
936 (HI "const_1_to_31_operand")
937 (SI "const_1_to_31_operand")
938 (DI "const_1_to_63_operand")])
939
940 ;; Input operand predicate for arithmetic left shifts.
941 (define_mode_attr ashl_input_operand
942 [(QI "nonimmediate_operand")
943 (HI "nonimmediate_operand")
944 (SI "nonimmediate_operand")
945 (DI "ashldi_input_operand")
946 (TI "reg_or_pm1_operand")])
947
948 ;; SSE and x87 SFmode and DFmode floating point modes
949 (define_mode_iterator MODEF [SF DF])
950
951 ;; All x87 floating point modes
952 (define_mode_iterator X87MODEF [SF DF XF])
953
954 ;; SSE instruction suffix for various modes
955 (define_mode_attr ssemodesuffix
956 [(SF "ss") (DF "sd")
957 (V8SF "ps") (V4DF "pd")
958 (V4SF "ps") (V2DF "pd")
959 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
960 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
961
962 ;; SSE vector suffix for floating point modes
963 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
964
965 ;; SSE vector mode corresponding to a scalar mode
966 (define_mode_attr ssevecmode
967 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
968
969 ;; Instruction suffix for REX 64bit operators.
970 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
971
972 ;; This mode iterator allows :P to be used for patterns that operate on
973 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
974 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
975
976 ;; This mode iterator allows :PTR to be used for patterns that operate on
977 ;; ptr_mode sized quantities.
978 (define_mode_iterator PTR
979 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
980 \f
981 ;; Scheduling descriptions
982
983 (include "pentium.md")
984 (include "ppro.md")
985 (include "k6.md")
986 (include "athlon.md")
987 (include "bdver1.md")
988 (include "geode.md")
989 (include "atom.md")
990 (include "core2.md")
991
992 \f
993 ;; Operand and operator predicates and constraints
994
995 (include "predicates.md")
996 (include "constraints.md")
997
998 \f
999 ;; Compare and branch/compare and store instructions.
1000
1001 (define_expand "cbranch<mode>4"
1002 [(set (reg:CC FLAGS_REG)
1003 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
1004 (match_operand:SDWIM 2 "<general_operand>" "")))
1005 (set (pc) (if_then_else
1006 (match_operator 0 "ordered_comparison_operator"
1007 [(reg:CC FLAGS_REG) (const_int 0)])
1008 (label_ref (match_operand 3 "" ""))
1009 (pc)))]
1010 ""
1011 {
1012 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1013 operands[1] = force_reg (<MODE>mode, operands[1]);
1014 ix86_expand_branch (GET_CODE (operands[0]),
1015 operands[1], operands[2], operands[3]);
1016 DONE;
1017 })
1018
1019 (define_expand "cstore<mode>4"
1020 [(set (reg:CC FLAGS_REG)
1021 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1022 (match_operand:SWIM 3 "<general_operand>" "")))
1023 (set (match_operand:QI 0 "register_operand" "")
1024 (match_operator 1 "ordered_comparison_operator"
1025 [(reg:CC FLAGS_REG) (const_int 0)]))]
1026 ""
1027 {
1028 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1029 operands[2] = force_reg (<MODE>mode, operands[2]);
1030 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1031 operands[2], operands[3]);
1032 DONE;
1033 })
1034
1035 (define_expand "cmp<mode>_1"
1036 [(set (reg:CC FLAGS_REG)
1037 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1038 (match_operand:SWI48 1 "<general_operand>" "")))])
1039
1040 (define_insn "*cmp<mode>_ccno_1"
1041 [(set (reg FLAGS_REG)
1042 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1043 (match_operand:SWI 1 "const0_operand" "")))]
1044 "ix86_match_ccmode (insn, CCNOmode)"
1045 "@
1046 test{<imodesuffix>}\t%0, %0
1047 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1048 [(set_attr "type" "test,icmp")
1049 (set_attr "length_immediate" "0,1")
1050 (set_attr "mode" "<MODE>")])
1051
1052 (define_insn "*cmp<mode>_1"
1053 [(set (reg FLAGS_REG)
1054 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1055 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1056 "ix86_match_ccmode (insn, CCmode)"
1057 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1058 [(set_attr "type" "icmp")
1059 (set_attr "mode" "<MODE>")])
1060
1061 (define_insn "*cmp<mode>_minus_1"
1062 [(set (reg FLAGS_REG)
1063 (compare
1064 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1065 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1066 (const_int 0)))]
1067 "ix86_match_ccmode (insn, CCGOCmode)"
1068 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1069 [(set_attr "type" "icmp")
1070 (set_attr "mode" "<MODE>")])
1071
1072 (define_insn "*cmpqi_ext_1"
1073 [(set (reg FLAGS_REG)
1074 (compare
1075 (match_operand:QI 0 "general_operand" "Qm")
1076 (subreg:QI
1077 (zero_extract:SI
1078 (match_operand 1 "ext_register_operand" "Q")
1079 (const_int 8)
1080 (const_int 8)) 0)))]
1081 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1082 "cmp{b}\t{%h1, %0|%0, %h1}"
1083 [(set_attr "type" "icmp")
1084 (set_attr "mode" "QI")])
1085
1086 (define_insn "*cmpqi_ext_1_rex64"
1087 [(set (reg FLAGS_REG)
1088 (compare
1089 (match_operand:QI 0 "register_operand" "Q")
1090 (subreg:QI
1091 (zero_extract:SI
1092 (match_operand 1 "ext_register_operand" "Q")
1093 (const_int 8)
1094 (const_int 8)) 0)))]
1095 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1096 "cmp{b}\t{%h1, %0|%0, %h1}"
1097 [(set_attr "type" "icmp")
1098 (set_attr "mode" "QI")])
1099
1100 (define_insn "*cmpqi_ext_2"
1101 [(set (reg FLAGS_REG)
1102 (compare
1103 (subreg:QI
1104 (zero_extract:SI
1105 (match_operand 0 "ext_register_operand" "Q")
1106 (const_int 8)
1107 (const_int 8)) 0)
1108 (match_operand:QI 1 "const0_operand" "")))]
1109 "ix86_match_ccmode (insn, CCNOmode)"
1110 "test{b}\t%h0, %h0"
1111 [(set_attr "type" "test")
1112 (set_attr "length_immediate" "0")
1113 (set_attr "mode" "QI")])
1114
1115 (define_expand "cmpqi_ext_3"
1116 [(set (reg:CC FLAGS_REG)
1117 (compare:CC
1118 (subreg:QI
1119 (zero_extract:SI
1120 (match_operand 0 "ext_register_operand" "")
1121 (const_int 8)
1122 (const_int 8)) 0)
1123 (match_operand:QI 1 "immediate_operand" "")))])
1124
1125 (define_insn "*cmpqi_ext_3_insn"
1126 [(set (reg FLAGS_REG)
1127 (compare
1128 (subreg:QI
1129 (zero_extract:SI
1130 (match_operand 0 "ext_register_operand" "Q")
1131 (const_int 8)
1132 (const_int 8)) 0)
1133 (match_operand:QI 1 "general_operand" "Qmn")))]
1134 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1135 "cmp{b}\t{%1, %h0|%h0, %1}"
1136 [(set_attr "type" "icmp")
1137 (set_attr "modrm" "1")
1138 (set_attr "mode" "QI")])
1139
1140 (define_insn "*cmpqi_ext_3_insn_rex64"
1141 [(set (reg FLAGS_REG)
1142 (compare
1143 (subreg:QI
1144 (zero_extract:SI
1145 (match_operand 0 "ext_register_operand" "Q")
1146 (const_int 8)
1147 (const_int 8)) 0)
1148 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1149 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1150 "cmp{b}\t{%1, %h0|%h0, %1}"
1151 [(set_attr "type" "icmp")
1152 (set_attr "modrm" "1")
1153 (set_attr "mode" "QI")])
1154
1155 (define_insn "*cmpqi_ext_4"
1156 [(set (reg FLAGS_REG)
1157 (compare
1158 (subreg:QI
1159 (zero_extract:SI
1160 (match_operand 0 "ext_register_operand" "Q")
1161 (const_int 8)
1162 (const_int 8)) 0)
1163 (subreg:QI
1164 (zero_extract:SI
1165 (match_operand 1 "ext_register_operand" "Q")
1166 (const_int 8)
1167 (const_int 8)) 0)))]
1168 "ix86_match_ccmode (insn, CCmode)"
1169 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1170 [(set_attr "type" "icmp")
1171 (set_attr "mode" "QI")])
1172
1173 ;; These implement float point compares.
1174 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1175 ;; which would allow mix and match FP modes on the compares. Which is what
1176 ;; the old patterns did, but with many more of them.
1177
1178 (define_expand "cbranchxf4"
1179 [(set (reg:CC FLAGS_REG)
1180 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1181 (match_operand:XF 2 "nonmemory_operand" "")))
1182 (set (pc) (if_then_else
1183 (match_operator 0 "ix86_fp_comparison_operator"
1184 [(reg:CC FLAGS_REG)
1185 (const_int 0)])
1186 (label_ref (match_operand 3 "" ""))
1187 (pc)))]
1188 "TARGET_80387"
1189 {
1190 ix86_expand_branch (GET_CODE (operands[0]),
1191 operands[1], operands[2], operands[3]);
1192 DONE;
1193 })
1194
1195 (define_expand "cstorexf4"
1196 [(set (reg:CC FLAGS_REG)
1197 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1198 (match_operand:XF 3 "nonmemory_operand" "")))
1199 (set (match_operand:QI 0 "register_operand" "")
1200 (match_operator 1 "ix86_fp_comparison_operator"
1201 [(reg:CC FLAGS_REG)
1202 (const_int 0)]))]
1203 "TARGET_80387"
1204 {
1205 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1206 operands[2], operands[3]);
1207 DONE;
1208 })
1209
1210 (define_expand "cbranch<mode>4"
1211 [(set (reg:CC FLAGS_REG)
1212 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1213 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1214 (set (pc) (if_then_else
1215 (match_operator 0 "ix86_fp_comparison_operator"
1216 [(reg:CC FLAGS_REG)
1217 (const_int 0)])
1218 (label_ref (match_operand 3 "" ""))
1219 (pc)))]
1220 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1221 {
1222 ix86_expand_branch (GET_CODE (operands[0]),
1223 operands[1], operands[2], operands[3]);
1224 DONE;
1225 })
1226
1227 (define_expand "cstore<mode>4"
1228 [(set (reg:CC FLAGS_REG)
1229 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1230 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1231 (set (match_operand:QI 0 "register_operand" "")
1232 (match_operator 1 "ix86_fp_comparison_operator"
1233 [(reg:CC FLAGS_REG)
1234 (const_int 0)]))]
1235 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1236 {
1237 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1238 operands[2], operands[3]);
1239 DONE;
1240 })
1241
1242 (define_expand "cbranchcc4"
1243 [(set (pc) (if_then_else
1244 (match_operator 0 "comparison_operator"
1245 [(match_operand 1 "flags_reg_operand" "")
1246 (match_operand 2 "const0_operand" "")])
1247 (label_ref (match_operand 3 "" ""))
1248 (pc)))]
1249 ""
1250 {
1251 ix86_expand_branch (GET_CODE (operands[0]),
1252 operands[1], operands[2], operands[3]);
1253 DONE;
1254 })
1255
1256 (define_expand "cstorecc4"
1257 [(set (match_operand:QI 0 "register_operand" "")
1258 (match_operator 1 "comparison_operator"
1259 [(match_operand 2 "flags_reg_operand" "")
1260 (match_operand 3 "const0_operand" "")]))]
1261 ""
1262 {
1263 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1264 operands[2], operands[3]);
1265 DONE;
1266 })
1267
1268
1269 ;; FP compares, step 1:
1270 ;; Set the FP condition codes.
1271 ;;
1272 ;; CCFPmode compare with exceptions
1273 ;; CCFPUmode compare with no exceptions
1274
1275 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1276 ;; used to manage the reg stack popping would not be preserved.
1277
1278 (define_insn "*cmpfp_0"
1279 [(set (match_operand:HI 0 "register_operand" "=a")
1280 (unspec:HI
1281 [(compare:CCFP
1282 (match_operand 1 "register_operand" "f")
1283 (match_operand 2 "const0_operand" ""))]
1284 UNSPEC_FNSTSW))]
1285 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1286 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1287 "* return output_fp_compare (insn, operands, false, false);"
1288 [(set_attr "type" "multi")
1289 (set_attr "unit" "i387")
1290 (set (attr "mode")
1291 (cond [(match_operand:SF 1 "" "")
1292 (const_string "SF")
1293 (match_operand:DF 1 "" "")
1294 (const_string "DF")
1295 ]
1296 (const_string "XF")))])
1297
1298 (define_insn_and_split "*cmpfp_0_cc"
1299 [(set (reg:CCFP FLAGS_REG)
1300 (compare:CCFP
1301 (match_operand 1 "register_operand" "f")
1302 (match_operand 2 "const0_operand" "")))
1303 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1304 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1305 && TARGET_SAHF && !TARGET_CMOVE
1306 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1307 "#"
1308 "&& reload_completed"
1309 [(set (match_dup 0)
1310 (unspec:HI
1311 [(compare:CCFP (match_dup 1)(match_dup 2))]
1312 UNSPEC_FNSTSW))
1313 (set (reg:CC FLAGS_REG)
1314 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1315 ""
1316 [(set_attr "type" "multi")
1317 (set_attr "unit" "i387")
1318 (set (attr "mode")
1319 (cond [(match_operand:SF 1 "" "")
1320 (const_string "SF")
1321 (match_operand:DF 1 "" "")
1322 (const_string "DF")
1323 ]
1324 (const_string "XF")))])
1325
1326 (define_insn "*cmpfp_xf"
1327 [(set (match_operand:HI 0 "register_operand" "=a")
1328 (unspec:HI
1329 [(compare:CCFP
1330 (match_operand:XF 1 "register_operand" "f")
1331 (match_operand:XF 2 "register_operand" "f"))]
1332 UNSPEC_FNSTSW))]
1333 "TARGET_80387"
1334 "* return output_fp_compare (insn, operands, false, false);"
1335 [(set_attr "type" "multi")
1336 (set_attr "unit" "i387")
1337 (set_attr "mode" "XF")])
1338
1339 (define_insn_and_split "*cmpfp_xf_cc"
1340 [(set (reg:CCFP FLAGS_REG)
1341 (compare:CCFP
1342 (match_operand:XF 1 "register_operand" "f")
1343 (match_operand:XF 2 "register_operand" "f")))
1344 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1345 "TARGET_80387
1346 && TARGET_SAHF && !TARGET_CMOVE"
1347 "#"
1348 "&& reload_completed"
1349 [(set (match_dup 0)
1350 (unspec:HI
1351 [(compare:CCFP (match_dup 1)(match_dup 2))]
1352 UNSPEC_FNSTSW))
1353 (set (reg:CC FLAGS_REG)
1354 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1355 ""
1356 [(set_attr "type" "multi")
1357 (set_attr "unit" "i387")
1358 (set_attr "mode" "XF")])
1359
1360 (define_insn "*cmpfp_<mode>"
1361 [(set (match_operand:HI 0 "register_operand" "=a")
1362 (unspec:HI
1363 [(compare:CCFP
1364 (match_operand:MODEF 1 "register_operand" "f")
1365 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1366 UNSPEC_FNSTSW))]
1367 "TARGET_80387"
1368 "* return output_fp_compare (insn, operands, false, false);"
1369 [(set_attr "type" "multi")
1370 (set_attr "unit" "i387")
1371 (set_attr "mode" "<MODE>")])
1372
1373 (define_insn_and_split "*cmpfp_<mode>_cc"
1374 [(set (reg:CCFP FLAGS_REG)
1375 (compare:CCFP
1376 (match_operand:MODEF 1 "register_operand" "f")
1377 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1378 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1379 "TARGET_80387
1380 && TARGET_SAHF && !TARGET_CMOVE"
1381 "#"
1382 "&& reload_completed"
1383 [(set (match_dup 0)
1384 (unspec:HI
1385 [(compare:CCFP (match_dup 1)(match_dup 2))]
1386 UNSPEC_FNSTSW))
1387 (set (reg:CC FLAGS_REG)
1388 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1389 ""
1390 [(set_attr "type" "multi")
1391 (set_attr "unit" "i387")
1392 (set_attr "mode" "<MODE>")])
1393
1394 (define_insn "*cmpfp_u"
1395 [(set (match_operand:HI 0 "register_operand" "=a")
1396 (unspec:HI
1397 [(compare:CCFPU
1398 (match_operand 1 "register_operand" "f")
1399 (match_operand 2 "register_operand" "f"))]
1400 UNSPEC_FNSTSW))]
1401 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1402 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1403 "* return output_fp_compare (insn, operands, false, true);"
1404 [(set_attr "type" "multi")
1405 (set_attr "unit" "i387")
1406 (set (attr "mode")
1407 (cond [(match_operand:SF 1 "" "")
1408 (const_string "SF")
1409 (match_operand:DF 1 "" "")
1410 (const_string "DF")
1411 ]
1412 (const_string "XF")))])
1413
1414 (define_insn_and_split "*cmpfp_u_cc"
1415 [(set (reg:CCFPU FLAGS_REG)
1416 (compare:CCFPU
1417 (match_operand 1 "register_operand" "f")
1418 (match_operand 2 "register_operand" "f")))
1419 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1420 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1421 && TARGET_SAHF && !TARGET_CMOVE
1422 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1423 "#"
1424 "&& reload_completed"
1425 [(set (match_dup 0)
1426 (unspec:HI
1427 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1428 UNSPEC_FNSTSW))
1429 (set (reg:CC FLAGS_REG)
1430 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1431 ""
1432 [(set_attr "type" "multi")
1433 (set_attr "unit" "i387")
1434 (set (attr "mode")
1435 (cond [(match_operand:SF 1 "" "")
1436 (const_string "SF")
1437 (match_operand:DF 1 "" "")
1438 (const_string "DF")
1439 ]
1440 (const_string "XF")))])
1441
1442 (define_insn "*cmpfp_<mode>"
1443 [(set (match_operand:HI 0 "register_operand" "=a")
1444 (unspec:HI
1445 [(compare:CCFP
1446 (match_operand 1 "register_operand" "f")
1447 (match_operator 3 "float_operator"
1448 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1449 UNSPEC_FNSTSW))]
1450 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1451 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1452 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1453 "* return output_fp_compare (insn, operands, false, false);"
1454 [(set_attr "type" "multi")
1455 (set_attr "unit" "i387")
1456 (set_attr "fp_int_src" "true")
1457 (set_attr "mode" "<MODE>")])
1458
1459 (define_insn_and_split "*cmpfp_<mode>_cc"
1460 [(set (reg:CCFP FLAGS_REG)
1461 (compare:CCFP
1462 (match_operand 1 "register_operand" "f")
1463 (match_operator 3 "float_operator"
1464 [(match_operand:SWI24 2 "memory_operand" "m")])))
1465 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1466 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1467 && TARGET_SAHF && !TARGET_CMOVE
1468 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1469 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1470 "#"
1471 "&& reload_completed"
1472 [(set (match_dup 0)
1473 (unspec:HI
1474 [(compare:CCFP
1475 (match_dup 1)
1476 (match_op_dup 3 [(match_dup 2)]))]
1477 UNSPEC_FNSTSW))
1478 (set (reg:CC FLAGS_REG)
1479 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1480 ""
1481 [(set_attr "type" "multi")
1482 (set_attr "unit" "i387")
1483 (set_attr "fp_int_src" "true")
1484 (set_attr "mode" "<MODE>")])
1485
1486 ;; FP compares, step 2
1487 ;; Move the fpsw to ax.
1488
1489 (define_insn "x86_fnstsw_1"
1490 [(set (match_operand:HI 0 "register_operand" "=a")
1491 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1492 "TARGET_80387"
1493 "fnstsw\t%0"
1494 [(set (attr "length")
1495 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1496 (set_attr "mode" "SI")
1497 (set_attr "unit" "i387")])
1498
1499 ;; FP compares, step 3
1500 ;; Get ax into flags, general case.
1501
1502 (define_insn "x86_sahf_1"
1503 [(set (reg:CC FLAGS_REG)
1504 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1505 UNSPEC_SAHF))]
1506 "TARGET_SAHF"
1507 {
1508 #ifndef HAVE_AS_IX86_SAHF
1509 if (TARGET_64BIT)
1510 return ASM_BYTE "0x9e";
1511 else
1512 #endif
1513 return "sahf";
1514 }
1515 [(set_attr "length" "1")
1516 (set_attr "athlon_decode" "vector")
1517 (set_attr "amdfam10_decode" "direct")
1518 (set_attr "bdver1_decode" "direct")
1519 (set_attr "mode" "SI")])
1520
1521 ;; Pentium Pro can do steps 1 through 3 in one go.
1522 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1523 ;; (these i387 instructions set flags directly)
1524 (define_insn "*cmpfp_i_mixed"
1525 [(set (reg:CCFP FLAGS_REG)
1526 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1527 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1528 "TARGET_MIX_SSE_I387
1529 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1530 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1531 "* return output_fp_compare (insn, operands, true, false);"
1532 [(set_attr "type" "fcmp,ssecomi")
1533 (set_attr "prefix" "orig,maybe_vex")
1534 (set (attr "mode")
1535 (if_then_else (match_operand:SF 1 "" "")
1536 (const_string "SF")
1537 (const_string "DF")))
1538 (set (attr "prefix_rep")
1539 (if_then_else (eq_attr "type" "ssecomi")
1540 (const_string "0")
1541 (const_string "*")))
1542 (set (attr "prefix_data16")
1543 (cond [(eq_attr "type" "fcmp")
1544 (const_string "*")
1545 (eq_attr "mode" "DF")
1546 (const_string "1")
1547 ]
1548 (const_string "0")))
1549 (set_attr "athlon_decode" "vector")
1550 (set_attr "amdfam10_decode" "direct")
1551 (set_attr "bdver1_decode" "double")])
1552
1553 (define_insn "*cmpfp_i_sse"
1554 [(set (reg:CCFP FLAGS_REG)
1555 (compare:CCFP (match_operand 0 "register_operand" "x")
1556 (match_operand 1 "nonimmediate_operand" "xm")))]
1557 "TARGET_SSE_MATH
1558 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1559 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1560 "* return output_fp_compare (insn, operands, true, false);"
1561 [(set_attr "type" "ssecomi")
1562 (set_attr "prefix" "maybe_vex")
1563 (set (attr "mode")
1564 (if_then_else (match_operand:SF 1 "" "")
1565 (const_string "SF")
1566 (const_string "DF")))
1567 (set_attr "prefix_rep" "0")
1568 (set (attr "prefix_data16")
1569 (if_then_else (eq_attr "mode" "DF")
1570 (const_string "1")
1571 (const_string "0")))
1572 (set_attr "athlon_decode" "vector")
1573 (set_attr "amdfam10_decode" "direct")
1574 (set_attr "bdver1_decode" "double")])
1575
1576 (define_insn "*cmpfp_i_i387"
1577 [(set (reg:CCFP FLAGS_REG)
1578 (compare:CCFP (match_operand 0 "register_operand" "f")
1579 (match_operand 1 "register_operand" "f")))]
1580 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1581 && TARGET_CMOVE
1582 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1583 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1584 "* return output_fp_compare (insn, operands, true, false);"
1585 [(set_attr "type" "fcmp")
1586 (set (attr "mode")
1587 (cond [(match_operand:SF 1 "" "")
1588 (const_string "SF")
1589 (match_operand:DF 1 "" "")
1590 (const_string "DF")
1591 ]
1592 (const_string "XF")))
1593 (set_attr "athlon_decode" "vector")
1594 (set_attr "amdfam10_decode" "direct")
1595 (set_attr "bdver1_decode" "double")])
1596
1597 (define_insn "*cmpfp_iu_mixed"
1598 [(set (reg:CCFPU FLAGS_REG)
1599 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1600 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1601 "TARGET_MIX_SSE_I387
1602 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1603 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1604 "* return output_fp_compare (insn, operands, true, true);"
1605 [(set_attr "type" "fcmp,ssecomi")
1606 (set_attr "prefix" "orig,maybe_vex")
1607 (set (attr "mode")
1608 (if_then_else (match_operand:SF 1 "" "")
1609 (const_string "SF")
1610 (const_string "DF")))
1611 (set (attr "prefix_rep")
1612 (if_then_else (eq_attr "type" "ssecomi")
1613 (const_string "0")
1614 (const_string "*")))
1615 (set (attr "prefix_data16")
1616 (cond [(eq_attr "type" "fcmp")
1617 (const_string "*")
1618 (eq_attr "mode" "DF")
1619 (const_string "1")
1620 ]
1621 (const_string "0")))
1622 (set_attr "athlon_decode" "vector")
1623 (set_attr "amdfam10_decode" "direct")
1624 (set_attr "bdver1_decode" "double")])
1625
1626 (define_insn "*cmpfp_iu_sse"
1627 [(set (reg:CCFPU FLAGS_REG)
1628 (compare:CCFPU (match_operand 0 "register_operand" "x")
1629 (match_operand 1 "nonimmediate_operand" "xm")))]
1630 "TARGET_SSE_MATH
1631 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1632 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1633 "* return output_fp_compare (insn, operands, true, true);"
1634 [(set_attr "type" "ssecomi")
1635 (set_attr "prefix" "maybe_vex")
1636 (set (attr "mode")
1637 (if_then_else (match_operand:SF 1 "" "")
1638 (const_string "SF")
1639 (const_string "DF")))
1640 (set_attr "prefix_rep" "0")
1641 (set (attr "prefix_data16")
1642 (if_then_else (eq_attr "mode" "DF")
1643 (const_string "1")
1644 (const_string "0")))
1645 (set_attr "athlon_decode" "vector")
1646 (set_attr "amdfam10_decode" "direct")
1647 (set_attr "bdver1_decode" "double")])
1648
1649 (define_insn "*cmpfp_iu_387"
1650 [(set (reg:CCFPU FLAGS_REG)
1651 (compare:CCFPU (match_operand 0 "register_operand" "f")
1652 (match_operand 1 "register_operand" "f")))]
1653 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1654 && TARGET_CMOVE
1655 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1656 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1657 "* return output_fp_compare (insn, operands, true, true);"
1658 [(set_attr "type" "fcmp")
1659 (set (attr "mode")
1660 (cond [(match_operand:SF 1 "" "")
1661 (const_string "SF")
1662 (match_operand:DF 1 "" "")
1663 (const_string "DF")
1664 ]
1665 (const_string "XF")))
1666 (set_attr "athlon_decode" "vector")
1667 (set_attr "amdfam10_decode" "direct")
1668 (set_attr "bdver1_decode" "direct")])
1669 \f
1670 ;; Push/pop instructions.
1671
1672 (define_insn "*push<mode>2"
1673 [(set (match_operand:DWI 0 "push_operand" "=<")
1674 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1675 ""
1676 "#"
1677 [(set_attr "type" "multi")
1678 (set_attr "mode" "<MODE>")])
1679
1680 (define_split
1681 [(set (match_operand:TI 0 "push_operand" "")
1682 (match_operand:TI 1 "general_operand" ""))]
1683 "TARGET_64BIT && reload_completed
1684 && !SSE_REG_P (operands[1])"
1685 [(const_int 0)]
1686 "ix86_split_long_move (operands); DONE;")
1687
1688 (define_insn "*pushdi2_rex64"
1689 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1690 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1691 "TARGET_64BIT"
1692 "@
1693 push{q}\t%1
1694 #"
1695 [(set_attr "type" "push,multi")
1696 (set_attr "mode" "DI")])
1697
1698 ;; Convert impossible pushes of immediate to existing instructions.
1699 ;; First try to get scratch register and go through it. In case this
1700 ;; fails, push sign extended lower part first and then overwrite
1701 ;; upper part by 32bit move.
1702 (define_peephole2
1703 [(match_scratch:DI 2 "r")
1704 (set (match_operand:DI 0 "push_operand" "")
1705 (match_operand:DI 1 "immediate_operand" ""))]
1706 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1707 && !x86_64_immediate_operand (operands[1], DImode)"
1708 [(set (match_dup 2) (match_dup 1))
1709 (set (match_dup 0) (match_dup 2))])
1710
1711 ;; We need to define this as both peepholer and splitter for case
1712 ;; peephole2 pass is not run.
1713 ;; "&& 1" is needed to keep it from matching the previous pattern.
1714 (define_peephole2
1715 [(set (match_operand:DI 0 "push_operand" "")
1716 (match_operand:DI 1 "immediate_operand" ""))]
1717 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1718 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1719 [(set (match_dup 0) (match_dup 1))
1720 (set (match_dup 2) (match_dup 3))]
1721 {
1722 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1723
1724 operands[1] = gen_lowpart (DImode, operands[2]);
1725 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1726 GEN_INT (4)));
1727 })
1728
1729 (define_split
1730 [(set (match_operand:DI 0 "push_operand" "")
1731 (match_operand:DI 1 "immediate_operand" ""))]
1732 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1733 ? epilogue_completed : reload_completed)
1734 && !symbolic_operand (operands[1], DImode)
1735 && !x86_64_immediate_operand (operands[1], DImode)"
1736 [(set (match_dup 0) (match_dup 1))
1737 (set (match_dup 2) (match_dup 3))]
1738 {
1739 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1740
1741 operands[1] = gen_lowpart (DImode, operands[2]);
1742 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1743 GEN_INT (4)));
1744 })
1745
1746 (define_split
1747 [(set (match_operand:DI 0 "push_operand" "")
1748 (match_operand:DI 1 "general_operand" ""))]
1749 "!TARGET_64BIT && reload_completed
1750 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1751 [(const_int 0)]
1752 "ix86_split_long_move (operands); DONE;")
1753
1754 (define_insn "*pushsi2"
1755 [(set (match_operand:SI 0 "push_operand" "=<")
1756 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1757 "!TARGET_64BIT"
1758 "push{l}\t%1"
1759 [(set_attr "type" "push")
1760 (set_attr "mode" "SI")])
1761
1762 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1763 ;; "push a byte/word". But actually we use pushl, which has the effect
1764 ;; of rounding the amount pushed up to a word.
1765
1766 ;; For TARGET_64BIT we always round up to 8 bytes.
1767 (define_insn "*push<mode>2_rex64"
1768 [(set (match_operand:SWI124 0 "push_operand" "=X")
1769 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1770 "TARGET_64BIT"
1771 "push{q}\t%q1"
1772 [(set_attr "type" "push")
1773 (set_attr "mode" "DI")])
1774
1775 (define_insn "*push<mode>2"
1776 [(set (match_operand:SWI12 0 "push_operand" "=X")
1777 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1778 "!TARGET_64BIT"
1779 "push{l}\t%k1"
1780 [(set_attr "type" "push")
1781 (set_attr "mode" "SI")])
1782
1783 (define_insn "*push<mode>2_prologue"
1784 [(set (match_operand:P 0 "push_operand" "=<")
1785 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1786 (clobber (mem:BLK (scratch)))]
1787 ""
1788 "push{<imodesuffix>}\t%1"
1789 [(set_attr "type" "push")
1790 (set_attr "mode" "<MODE>")])
1791
1792 (define_insn "*pop<mode>1"
1793 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1794 (match_operand:P 1 "pop_operand" ">"))]
1795 ""
1796 "pop{<imodesuffix>}\t%0"
1797 [(set_attr "type" "pop")
1798 (set_attr "mode" "<MODE>")])
1799
1800 (define_insn "*pop<mode>1_epilogue"
1801 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1802 (match_operand:P 1 "pop_operand" ">"))
1803 (clobber (mem:BLK (scratch)))]
1804 ""
1805 "pop{<imodesuffix>}\t%0"
1806 [(set_attr "type" "pop")
1807 (set_attr "mode" "<MODE>")])
1808 \f
1809 ;; Move instructions.
1810
1811 (define_expand "movoi"
1812 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1813 (match_operand:OI 1 "general_operand" ""))]
1814 "TARGET_AVX"
1815 "ix86_expand_move (OImode, operands); DONE;")
1816
1817 (define_expand "movti"
1818 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1819 (match_operand:TI 1 "nonimmediate_operand" ""))]
1820 "TARGET_64BIT || TARGET_SSE"
1821 {
1822 if (TARGET_64BIT)
1823 ix86_expand_move (TImode, operands);
1824 else if (push_operand (operands[0], TImode))
1825 ix86_expand_push (TImode, operands[1]);
1826 else
1827 ix86_expand_vector_move (TImode, operands);
1828 DONE;
1829 })
1830
1831 ;; This expands to what emit_move_complex would generate if we didn't
1832 ;; have a movti pattern. Having this avoids problems with reload on
1833 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1834 ;; to have around all the time.
1835 (define_expand "movcdi"
1836 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1837 (match_operand:CDI 1 "general_operand" ""))]
1838 ""
1839 {
1840 if (push_operand (operands[0], CDImode))
1841 emit_move_complex_push (CDImode, operands[0], operands[1]);
1842 else
1843 emit_move_complex_parts (operands[0], operands[1]);
1844 DONE;
1845 })
1846
1847 (define_expand "mov<mode>"
1848 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1849 (match_operand:SWI1248x 1 "general_operand" ""))]
1850 ""
1851 "ix86_expand_move (<MODE>mode, operands); DONE;")
1852
1853 (define_insn "*mov<mode>_xor"
1854 [(set (match_operand:SWI48 0 "register_operand" "=r")
1855 (match_operand:SWI48 1 "const0_operand" ""))
1856 (clobber (reg:CC FLAGS_REG))]
1857 "reload_completed"
1858 "xor{l}\t%k0, %k0"
1859 [(set_attr "type" "alu1")
1860 (set_attr "mode" "SI")
1861 (set_attr "length_immediate" "0")])
1862
1863 (define_insn "*mov<mode>_or"
1864 [(set (match_operand:SWI48 0 "register_operand" "=r")
1865 (match_operand:SWI48 1 "const_int_operand" ""))
1866 (clobber (reg:CC FLAGS_REG))]
1867 "reload_completed
1868 && operands[1] == constm1_rtx"
1869 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1870 [(set_attr "type" "alu1")
1871 (set_attr "mode" "<MODE>")
1872 (set_attr "length_immediate" "1")])
1873
1874 (define_insn "*movoi_internal_avx"
1875 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1876 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1877 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1878 {
1879 switch (which_alternative)
1880 {
1881 case 0:
1882 return standard_sse_constant_opcode (insn, operands[1]);
1883 case 1:
1884 case 2:
1885 if (misaligned_operand (operands[0], OImode)
1886 || misaligned_operand (operands[1], OImode))
1887 return "vmovdqu\t{%1, %0|%0, %1}";
1888 else
1889 return "vmovdqa\t{%1, %0|%0, %1}";
1890 default:
1891 gcc_unreachable ();
1892 }
1893 }
1894 [(set_attr "type" "sselog1,ssemov,ssemov")
1895 (set_attr "prefix" "vex")
1896 (set_attr "mode" "OI")])
1897
1898 (define_insn "*movti_internal_rex64"
1899 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1900 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1901 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1902 {
1903 switch (which_alternative)
1904 {
1905 case 0:
1906 case 1:
1907 return "#";
1908 case 2:
1909 return standard_sse_constant_opcode (insn, operands[1]);
1910 case 3:
1911 case 4:
1912 /* TDmode values are passed as TImode on the stack. Moving them
1913 to stack may result in unaligned memory access. */
1914 if (misaligned_operand (operands[0], TImode)
1915 || misaligned_operand (operands[1], TImode))
1916 {
1917 if (get_attr_mode (insn) == MODE_V4SF)
1918 return "%vmovups\t{%1, %0|%0, %1}";
1919 else
1920 return "%vmovdqu\t{%1, %0|%0, %1}";
1921 }
1922 else
1923 {
1924 if (get_attr_mode (insn) == MODE_V4SF)
1925 return "%vmovaps\t{%1, %0|%0, %1}";
1926 else
1927 return "%vmovdqa\t{%1, %0|%0, %1}";
1928 }
1929 default:
1930 gcc_unreachable ();
1931 }
1932 }
1933 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1934 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1935 (set (attr "mode")
1936 (cond [(eq_attr "alternative" "2,3")
1937 (if_then_else
1938 (match_test "optimize_function_for_size_p (cfun)")
1939 (const_string "V4SF")
1940 (const_string "TI"))
1941 (eq_attr "alternative" "4")
1942 (if_then_else
1943 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1944 (match_test "optimize_function_for_size_p (cfun)"))
1945 (const_string "V4SF")
1946 (const_string "TI"))]
1947 (const_string "DI")))])
1948
1949 (define_split
1950 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1951 (match_operand:TI 1 "general_operand" ""))]
1952 "reload_completed
1953 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1954 [(const_int 0)]
1955 "ix86_split_long_move (operands); DONE;")
1956
1957 (define_insn "*movti_internal_sse"
1958 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1959 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1960 "TARGET_SSE && !TARGET_64BIT
1961 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1962 {
1963 switch (which_alternative)
1964 {
1965 case 0:
1966 return standard_sse_constant_opcode (insn, operands[1]);
1967 case 1:
1968 case 2:
1969 /* TDmode values are passed as TImode on the stack. Moving them
1970 to stack may result in unaligned memory access. */
1971 if (misaligned_operand (operands[0], TImode)
1972 || misaligned_operand (operands[1], TImode))
1973 {
1974 if (get_attr_mode (insn) == MODE_V4SF)
1975 return "%vmovups\t{%1, %0|%0, %1}";
1976 else
1977 return "%vmovdqu\t{%1, %0|%0, %1}";
1978 }
1979 else
1980 {
1981 if (get_attr_mode (insn) == MODE_V4SF)
1982 return "%vmovaps\t{%1, %0|%0, %1}";
1983 else
1984 return "%vmovdqa\t{%1, %0|%0, %1}";
1985 }
1986 default:
1987 gcc_unreachable ();
1988 }
1989 }
1990 [(set_attr "type" "sselog1,ssemov,ssemov")
1991 (set_attr "prefix" "maybe_vex")
1992 (set (attr "mode")
1993 (cond [(ior (not (match_test "TARGET_SSE2"))
1994 (match_test "optimize_function_for_size_p (cfun)"))
1995 (const_string "V4SF")
1996 (and (eq_attr "alternative" "2")
1997 (match_test "TARGET_SSE_TYPELESS_STORES"))
1998 (const_string "V4SF")]
1999 (const_string "TI")))])
2000
2001 (define_insn "*movdi_internal_rex64"
2002 [(set (match_operand:DI 0 "nonimmediate_operand"
2003 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
2004 (match_operand:DI 1 "general_operand"
2005 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
2006 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2007 {
2008 switch (get_attr_type (insn))
2009 {
2010 case TYPE_SSECVT:
2011 if (SSE_REG_P (operands[0]))
2012 return "movq2dq\t{%1, %0|%0, %1}";
2013 else
2014 return "movdq2q\t{%1, %0|%0, %1}";
2015
2016 case TYPE_SSEMOV:
2017 if (get_attr_mode (insn) == MODE_TI)
2018 return "%vmovdqa\t{%1, %0|%0, %1}";
2019 /* Handle broken assemblers that require movd instead of movq. */
2020 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2021 return "%vmovd\t{%1, %0|%0, %1}";
2022 else
2023 return "%vmovq\t{%1, %0|%0, %1}";
2024
2025 case TYPE_MMXMOV:
2026 /* Handle broken assemblers that require movd instead of movq. */
2027 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2028 return "movd\t{%1, %0|%0, %1}";
2029 else
2030 return "movq\t{%1, %0|%0, %1}";
2031
2032 case TYPE_SSELOG1:
2033 return standard_sse_constant_opcode (insn, operands[1]);
2034
2035 case TYPE_MMX:
2036 return "pxor\t%0, %0";
2037
2038 case TYPE_MULTI:
2039 return "#";
2040
2041 case TYPE_LEA:
2042 return "lea{q}\t{%a1, %0|%0, %a1}";
2043
2044 default:
2045 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2046 if (get_attr_mode (insn) == MODE_SI)
2047 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2048 else if (which_alternative == 2)
2049 return "movabs{q}\t{%1, %0|%0, %1}";
2050 else
2051 return "mov{q}\t{%1, %0|%0, %1}";
2052 }
2053 }
2054 [(set (attr "type")
2055 (cond [(eq_attr "alternative" "4")
2056 (const_string "multi")
2057 (eq_attr "alternative" "5")
2058 (const_string "mmx")
2059 (eq_attr "alternative" "6,7,8,9")
2060 (const_string "mmxmov")
2061 (eq_attr "alternative" "10")
2062 (const_string "sselog1")
2063 (eq_attr "alternative" "11,12,13,14,15")
2064 (const_string "ssemov")
2065 (eq_attr "alternative" "16,17")
2066 (const_string "ssecvt")
2067 (match_operand 1 "pic_32bit_operand" "")
2068 (const_string "lea")
2069 ]
2070 (const_string "imov")))
2071 (set (attr "modrm")
2072 (if_then_else
2073 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2074 (const_string "0")
2075 (const_string "*")))
2076 (set (attr "length_immediate")
2077 (if_then_else
2078 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2079 (const_string "8")
2080 (const_string "*")))
2081 (set (attr "prefix_rex")
2082 (if_then_else (eq_attr "alternative" "8,9")
2083 (const_string "1")
2084 (const_string "*")))
2085 (set (attr "prefix_data16")
2086 (if_then_else (eq_attr "alternative" "11")
2087 (const_string "1")
2088 (const_string "*")))
2089 (set (attr "prefix")
2090 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2091 (const_string "maybe_vex")
2092 (const_string "orig")))
2093 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2094
2095 ;; Reload patterns to support multi-word load/store
2096 ;; with non-offsetable address.
2097 (define_expand "reload_noff_store"
2098 [(parallel [(match_operand 0 "memory_operand" "=m")
2099 (match_operand 1 "register_operand" "r")
2100 (match_operand:DI 2 "register_operand" "=&r")])]
2101 "TARGET_64BIT"
2102 {
2103 rtx mem = operands[0];
2104 rtx addr = XEXP (mem, 0);
2105
2106 emit_move_insn (operands[2], addr);
2107 mem = replace_equiv_address_nv (mem, operands[2]);
2108
2109 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2110 DONE;
2111 })
2112
2113 (define_expand "reload_noff_load"
2114 [(parallel [(match_operand 0 "register_operand" "=r")
2115 (match_operand 1 "memory_operand" "m")
2116 (match_operand:DI 2 "register_operand" "=r")])]
2117 "TARGET_64BIT"
2118 {
2119 rtx mem = operands[1];
2120 rtx addr = XEXP (mem, 0);
2121
2122 emit_move_insn (operands[2], addr);
2123 mem = replace_equiv_address_nv (mem, operands[2]);
2124
2125 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2126 DONE;
2127 })
2128
2129 ;; Convert impossible stores of immediate to existing instructions.
2130 ;; First try to get scratch register and go through it. In case this
2131 ;; fails, move by 32bit parts.
2132 (define_peephole2
2133 [(match_scratch:DI 2 "r")
2134 (set (match_operand:DI 0 "memory_operand" "")
2135 (match_operand:DI 1 "immediate_operand" ""))]
2136 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2137 && !x86_64_immediate_operand (operands[1], DImode)"
2138 [(set (match_dup 2) (match_dup 1))
2139 (set (match_dup 0) (match_dup 2))])
2140
2141 ;; We need to define this as both peepholer and splitter for case
2142 ;; peephole2 pass is not run.
2143 ;; "&& 1" is needed to keep it from matching the previous pattern.
2144 (define_peephole2
2145 [(set (match_operand:DI 0 "memory_operand" "")
2146 (match_operand:DI 1 "immediate_operand" ""))]
2147 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2148 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2149 [(set (match_dup 2) (match_dup 3))
2150 (set (match_dup 4) (match_dup 5))]
2151 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2152
2153 (define_split
2154 [(set (match_operand:DI 0 "memory_operand" "")
2155 (match_operand:DI 1 "immediate_operand" ""))]
2156 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2157 ? epilogue_completed : reload_completed)
2158 && !symbolic_operand (operands[1], DImode)
2159 && !x86_64_immediate_operand (operands[1], DImode)"
2160 [(set (match_dup 2) (match_dup 3))
2161 (set (match_dup 4) (match_dup 5))]
2162 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2163
2164 (define_insn "*movdi_internal"
2165 [(set (match_operand:DI 0 "nonimmediate_operand"
2166 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2167 (match_operand:DI 1 "general_operand"
2168 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2169 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2170 {
2171 switch (get_attr_type (insn))
2172 {
2173 case TYPE_SSECVT:
2174 if (SSE_REG_P (operands[0]))
2175 return "movq2dq\t{%1, %0|%0, %1}";
2176 else
2177 return "movdq2q\t{%1, %0|%0, %1}";
2178
2179 case TYPE_SSEMOV:
2180 switch (get_attr_mode (insn))
2181 {
2182 case MODE_TI:
2183 return "%vmovdqa\t{%1, %0|%0, %1}";
2184 case MODE_DI:
2185 return "%vmovq\t{%1, %0|%0, %1}";
2186 case MODE_V4SF:
2187 return "movaps\t{%1, %0|%0, %1}";
2188 case MODE_V2SF:
2189 return "movlps\t{%1, %0|%0, %1}";
2190 default:
2191 gcc_unreachable ();
2192 }
2193
2194 case TYPE_MMXMOV:
2195 return "movq\t{%1, %0|%0, %1}";
2196
2197 case TYPE_SSELOG1:
2198 return standard_sse_constant_opcode (insn, operands[1]);
2199
2200 case TYPE_MMX:
2201 return "pxor\t%0, %0";
2202
2203 case TYPE_MULTI:
2204 return "#";
2205
2206 default:
2207 gcc_unreachable ();
2208 }
2209 }
2210 [(set (attr "isa")
2211 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2212 (const_string "sse2")
2213 (eq_attr "alternative" "9,10,11,12")
2214 (const_string "noavx")
2215 ]
2216 (const_string "*")))
2217 (set (attr "type")
2218 (cond [(eq_attr "alternative" "0,1")
2219 (const_string "multi")
2220 (eq_attr "alternative" "2")
2221 (const_string "mmx")
2222 (eq_attr "alternative" "3,4")
2223 (const_string "mmxmov")
2224 (eq_attr "alternative" "5,9")
2225 (const_string "sselog1")
2226 (eq_attr "alternative" "13,14")
2227 (const_string "ssecvt")
2228 ]
2229 (const_string "ssemov")))
2230 (set (attr "prefix")
2231 (if_then_else (eq_attr "alternative" "5,6,7,8")
2232 (const_string "maybe_vex")
2233 (const_string "orig")))
2234 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2235
2236 (define_split
2237 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2238 (match_operand:DI 1 "general_operand" ""))]
2239 "!TARGET_64BIT && reload_completed
2240 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2241 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2242 [(const_int 0)]
2243 "ix86_split_long_move (operands); DONE;")
2244
2245 (define_insn "*movsi_internal"
2246 [(set (match_operand:SI 0 "nonimmediate_operand"
2247 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2248 (match_operand:SI 1 "general_operand"
2249 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2250 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2251 {
2252 switch (get_attr_type (insn))
2253 {
2254 case TYPE_SSELOG1:
2255 return standard_sse_constant_opcode (insn, operands[1]);
2256
2257 case TYPE_SSEMOV:
2258 switch (get_attr_mode (insn))
2259 {
2260 case MODE_TI:
2261 return "%vmovdqa\t{%1, %0|%0, %1}";
2262 case MODE_V4SF:
2263 return "%vmovaps\t{%1, %0|%0, %1}";
2264 case MODE_SI:
2265 return "%vmovd\t{%1, %0|%0, %1}";
2266 case MODE_SF:
2267 return "%vmovss\t{%1, %0|%0, %1}";
2268 default:
2269 gcc_unreachable ();
2270 }
2271
2272 case TYPE_MMX:
2273 return "pxor\t%0, %0";
2274
2275 case TYPE_MMXMOV:
2276 if (get_attr_mode (insn) == MODE_DI)
2277 return "movq\t{%1, %0|%0, %1}";
2278 return "movd\t{%1, %0|%0, %1}";
2279
2280 case TYPE_LEA:
2281 return "lea{l}\t{%a1, %0|%0, %a1}";
2282
2283 default:
2284 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2285 return "mov{l}\t{%1, %0|%0, %1}";
2286 }
2287 }
2288 [(set (attr "type")
2289 (cond [(eq_attr "alternative" "2")
2290 (const_string "mmx")
2291 (eq_attr "alternative" "3,4,5")
2292 (const_string "mmxmov")
2293 (eq_attr "alternative" "6")
2294 (const_string "sselog1")
2295 (eq_attr "alternative" "7,8,9,10,11")
2296 (const_string "ssemov")
2297 (match_operand 1 "pic_32bit_operand" "")
2298 (const_string "lea")
2299 ]
2300 (const_string "imov")))
2301 (set (attr "prefix")
2302 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2303 (const_string "orig")
2304 (const_string "maybe_vex")))
2305 (set (attr "prefix_data16")
2306 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2307 (const_string "1")
2308 (const_string "*")))
2309 (set (attr "mode")
2310 (cond [(eq_attr "alternative" "2,3")
2311 (const_string "DI")
2312 (eq_attr "alternative" "6,7")
2313 (if_then_else
2314 (not (match_test "TARGET_SSE2"))
2315 (const_string "V4SF")
2316 (const_string "TI"))
2317 (and (eq_attr "alternative" "8,9,10,11")
2318 (not (match_test "TARGET_SSE2")))
2319 (const_string "SF")
2320 ]
2321 (const_string "SI")))])
2322
2323 (define_insn "*movhi_internal"
2324 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2325 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2326 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2327 {
2328 switch (get_attr_type (insn))
2329 {
2330 case TYPE_IMOVX:
2331 /* movzwl is faster than movw on p2 due to partial word stalls,
2332 though not as fast as an aligned movl. */
2333 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2334 default:
2335 if (get_attr_mode (insn) == MODE_SI)
2336 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2337 else
2338 return "mov{w}\t{%1, %0|%0, %1}";
2339 }
2340 }
2341 [(set (attr "type")
2342 (cond [(match_test "optimize_function_for_size_p (cfun)")
2343 (const_string "imov")
2344 (and (eq_attr "alternative" "0")
2345 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2346 (not (match_test "TARGET_HIMODE_MATH"))))
2347 (const_string "imov")
2348 (and (eq_attr "alternative" "1,2")
2349 (match_operand:HI 1 "aligned_operand" ""))
2350 (const_string "imov")
2351 (and (match_test "TARGET_MOVX")
2352 (eq_attr "alternative" "0,2"))
2353 (const_string "imovx")
2354 ]
2355 (const_string "imov")))
2356 (set (attr "mode")
2357 (cond [(eq_attr "type" "imovx")
2358 (const_string "SI")
2359 (and (eq_attr "alternative" "1,2")
2360 (match_operand:HI 1 "aligned_operand" ""))
2361 (const_string "SI")
2362 (and (eq_attr "alternative" "0")
2363 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2364 (not (match_test "TARGET_HIMODE_MATH"))))
2365 (const_string "SI")
2366 ]
2367 (const_string "HI")))])
2368
2369 ;; Situation is quite tricky about when to choose full sized (SImode) move
2370 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2371 ;; partial register dependency machines (such as AMD Athlon), where QImode
2372 ;; moves issue extra dependency and for partial register stalls machines
2373 ;; that don't use QImode patterns (and QImode move cause stall on the next
2374 ;; instruction).
2375 ;;
2376 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2377 ;; register stall machines with, where we use QImode instructions, since
2378 ;; partial register stall can be caused there. Then we use movzx.
2379 (define_insn "*movqi_internal"
2380 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2381 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2382 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2383 {
2384 switch (get_attr_type (insn))
2385 {
2386 case TYPE_IMOVX:
2387 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2388 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2389 default:
2390 if (get_attr_mode (insn) == MODE_SI)
2391 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2392 else
2393 return "mov{b}\t{%1, %0|%0, %1}";
2394 }
2395 }
2396 [(set (attr "type")
2397 (cond [(and (eq_attr "alternative" "5")
2398 (not (match_operand:QI 1 "aligned_operand" "")))
2399 (const_string "imovx")
2400 (match_test "optimize_function_for_size_p (cfun)")
2401 (const_string "imov")
2402 (and (eq_attr "alternative" "3")
2403 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2404 (not (match_test "TARGET_QIMODE_MATH"))))
2405 (const_string "imov")
2406 (eq_attr "alternative" "3,5")
2407 (const_string "imovx")
2408 (and (match_test "TARGET_MOVX")
2409 (eq_attr "alternative" "2"))
2410 (const_string "imovx")
2411 ]
2412 (const_string "imov")))
2413 (set (attr "mode")
2414 (cond [(eq_attr "alternative" "3,4,5")
2415 (const_string "SI")
2416 (eq_attr "alternative" "6")
2417 (const_string "QI")
2418 (eq_attr "type" "imovx")
2419 (const_string "SI")
2420 (and (eq_attr "type" "imov")
2421 (and (eq_attr "alternative" "0,1")
2422 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2423 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2424 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2425 (const_string "SI")
2426 ;; Avoid partial register stalls when not using QImode arithmetic
2427 (and (eq_attr "type" "imov")
2428 (and (eq_attr "alternative" "0,1")
2429 (and (match_test "TARGET_PARTIAL_REG_STALL")
2430 (not (match_test "TARGET_QIMODE_MATH")))))
2431 (const_string "SI")
2432 ]
2433 (const_string "QI")))])
2434
2435 ;; Stores and loads of ax to arbitrary constant address.
2436 ;; We fake an second form of instruction to force reload to load address
2437 ;; into register when rax is not available
2438 (define_insn "*movabs<mode>_1"
2439 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2440 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2441 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2442 "@
2443 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2444 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2445 [(set_attr "type" "imov")
2446 (set_attr "modrm" "0,*")
2447 (set_attr "length_address" "8,0")
2448 (set_attr "length_immediate" "0,*")
2449 (set_attr "memory" "store")
2450 (set_attr "mode" "<MODE>")])
2451
2452 (define_insn "*movabs<mode>_2"
2453 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2454 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2455 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2456 "@
2457 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2458 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2459 [(set_attr "type" "imov")
2460 (set_attr "modrm" "0,*")
2461 (set_attr "length_address" "8,0")
2462 (set_attr "length_immediate" "0")
2463 (set_attr "memory" "load")
2464 (set_attr "mode" "<MODE>")])
2465
2466 (define_insn "*swap<mode>"
2467 [(set (match_operand:SWI48 0 "register_operand" "+r")
2468 (match_operand:SWI48 1 "register_operand" "+r"))
2469 (set (match_dup 1)
2470 (match_dup 0))]
2471 ""
2472 "xchg{<imodesuffix>}\t%1, %0"
2473 [(set_attr "type" "imov")
2474 (set_attr "mode" "<MODE>")
2475 (set_attr "pent_pair" "np")
2476 (set_attr "athlon_decode" "vector")
2477 (set_attr "amdfam10_decode" "double")
2478 (set_attr "bdver1_decode" "double")])
2479
2480 (define_insn "*swap<mode>_1"
2481 [(set (match_operand:SWI12 0 "register_operand" "+r")
2482 (match_operand:SWI12 1 "register_operand" "+r"))
2483 (set (match_dup 1)
2484 (match_dup 0))]
2485 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2486 "xchg{l}\t%k1, %k0"
2487 [(set_attr "type" "imov")
2488 (set_attr "mode" "SI")
2489 (set_attr "pent_pair" "np")
2490 (set_attr "athlon_decode" "vector")
2491 (set_attr "amdfam10_decode" "double")
2492 (set_attr "bdver1_decode" "double")])
2493
2494 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2495 ;; is disabled for AMDFAM10
2496 (define_insn "*swap<mode>_2"
2497 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2498 (match_operand:SWI12 1 "register_operand" "+<r>"))
2499 (set (match_dup 1)
2500 (match_dup 0))]
2501 "TARGET_PARTIAL_REG_STALL"
2502 "xchg{<imodesuffix>}\t%1, %0"
2503 [(set_attr "type" "imov")
2504 (set_attr "mode" "<MODE>")
2505 (set_attr "pent_pair" "np")
2506 (set_attr "athlon_decode" "vector")])
2507
2508 (define_expand "movstrict<mode>"
2509 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2510 (match_operand:SWI12 1 "general_operand" ""))]
2511 ""
2512 {
2513 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2514 FAIL;
2515 if (GET_CODE (operands[0]) == SUBREG
2516 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2517 FAIL;
2518 /* Don't generate memory->memory moves, go through a register */
2519 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2520 operands[1] = force_reg (<MODE>mode, operands[1]);
2521 })
2522
2523 (define_insn "*movstrict<mode>_1"
2524 [(set (strict_low_part
2525 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2526 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2527 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2528 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2529 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2530 [(set_attr "type" "imov")
2531 (set_attr "mode" "<MODE>")])
2532
2533 (define_insn "*movstrict<mode>_xor"
2534 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2535 (match_operand:SWI12 1 "const0_operand" ""))
2536 (clobber (reg:CC FLAGS_REG))]
2537 "reload_completed"
2538 "xor{<imodesuffix>}\t%0, %0"
2539 [(set_attr "type" "alu1")
2540 (set_attr "mode" "<MODE>")
2541 (set_attr "length_immediate" "0")])
2542
2543 (define_insn "*mov<mode>_extv_1"
2544 [(set (match_operand:SWI24 0 "register_operand" "=R")
2545 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2546 (const_int 8)
2547 (const_int 8)))]
2548 ""
2549 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2550 [(set_attr "type" "imovx")
2551 (set_attr "mode" "SI")])
2552
2553 (define_insn "*movqi_extv_1_rex64"
2554 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2555 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2556 (const_int 8)
2557 (const_int 8)))]
2558 "TARGET_64BIT"
2559 {
2560 switch (get_attr_type (insn))
2561 {
2562 case TYPE_IMOVX:
2563 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2564 default:
2565 return "mov{b}\t{%h1, %0|%0, %h1}";
2566 }
2567 }
2568 [(set (attr "type")
2569 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2570 (match_test "TARGET_MOVX"))
2571 (const_string "imovx")
2572 (const_string "imov")))
2573 (set (attr "mode")
2574 (if_then_else (eq_attr "type" "imovx")
2575 (const_string "SI")
2576 (const_string "QI")))])
2577
2578 (define_insn "*movqi_extv_1"
2579 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2580 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2581 (const_int 8)
2582 (const_int 8)))]
2583 "!TARGET_64BIT"
2584 {
2585 switch (get_attr_type (insn))
2586 {
2587 case TYPE_IMOVX:
2588 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2589 default:
2590 return "mov{b}\t{%h1, %0|%0, %h1}";
2591 }
2592 }
2593 [(set (attr "type")
2594 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2595 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2596 (match_test "TARGET_MOVX")))
2597 (const_string "imovx")
2598 (const_string "imov")))
2599 (set (attr "mode")
2600 (if_then_else (eq_attr "type" "imovx")
2601 (const_string "SI")
2602 (const_string "QI")))])
2603
2604 (define_insn "*mov<mode>_extzv_1"
2605 [(set (match_operand:SWI48 0 "register_operand" "=R")
2606 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2607 (const_int 8)
2608 (const_int 8)))]
2609 ""
2610 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2611 [(set_attr "type" "imovx")
2612 (set_attr "mode" "SI")])
2613
2614 (define_insn "*movqi_extzv_2_rex64"
2615 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2616 (subreg:QI
2617 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2618 (const_int 8)
2619 (const_int 8)) 0))]
2620 "TARGET_64BIT"
2621 {
2622 switch (get_attr_type (insn))
2623 {
2624 case TYPE_IMOVX:
2625 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2626 default:
2627 return "mov{b}\t{%h1, %0|%0, %h1}";
2628 }
2629 }
2630 [(set (attr "type")
2631 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2632 (match_test "TARGET_MOVX"))
2633 (const_string "imovx")
2634 (const_string "imov")))
2635 (set (attr "mode")
2636 (if_then_else (eq_attr "type" "imovx")
2637 (const_string "SI")
2638 (const_string "QI")))])
2639
2640 (define_insn "*movqi_extzv_2"
2641 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2642 (subreg:QI
2643 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2644 (const_int 8)
2645 (const_int 8)) 0))]
2646 "!TARGET_64BIT"
2647 {
2648 switch (get_attr_type (insn))
2649 {
2650 case TYPE_IMOVX:
2651 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2652 default:
2653 return "mov{b}\t{%h1, %0|%0, %h1}";
2654 }
2655 }
2656 [(set (attr "type")
2657 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2658 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2659 (match_test "TARGET_MOVX")))
2660 (const_string "imovx")
2661 (const_string "imov")))
2662 (set (attr "mode")
2663 (if_then_else (eq_attr "type" "imovx")
2664 (const_string "SI")
2665 (const_string "QI")))])
2666
2667 (define_expand "mov<mode>_insv_1"
2668 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2669 (const_int 8)
2670 (const_int 8))
2671 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2672
2673 (define_insn "*mov<mode>_insv_1_rex64"
2674 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2675 (const_int 8)
2676 (const_int 8))
2677 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2678 "TARGET_64BIT"
2679 "mov{b}\t{%b1, %h0|%h0, %b1}"
2680 [(set_attr "type" "imov")
2681 (set_attr "mode" "QI")])
2682
2683 (define_insn "*movsi_insv_1"
2684 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2685 (const_int 8)
2686 (const_int 8))
2687 (match_operand:SI 1 "general_operand" "Qmn"))]
2688 "!TARGET_64BIT"
2689 "mov{b}\t{%b1, %h0|%h0, %b1}"
2690 [(set_attr "type" "imov")
2691 (set_attr "mode" "QI")])
2692
2693 (define_insn "*movqi_insv_2"
2694 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2695 (const_int 8)
2696 (const_int 8))
2697 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2698 (const_int 8)))]
2699 ""
2700 "mov{b}\t{%h1, %h0|%h0, %h1}"
2701 [(set_attr "type" "imov")
2702 (set_attr "mode" "QI")])
2703 \f
2704 ;; Floating point push instructions.
2705
2706 (define_insn "*pushtf"
2707 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2708 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2709 "TARGET_SSE2"
2710 {
2711 /* This insn should be already split before reg-stack. */
2712 gcc_unreachable ();
2713 }
2714 [(set_attr "type" "multi")
2715 (set_attr "unit" "sse,*,*")
2716 (set_attr "mode" "TF,SI,SI")])
2717
2718 ;; %%% Kill this when call knows how to work this out.
2719 (define_split
2720 [(set (match_operand:TF 0 "push_operand" "")
2721 (match_operand:TF 1 "sse_reg_operand" ""))]
2722 "TARGET_SSE2 && reload_completed"
2723 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2724 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2725
2726 (define_insn "*pushxf"
2727 [(set (match_operand:XF 0 "push_operand" "=<,<")
2728 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2729 "optimize_function_for_speed_p (cfun)"
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" "XF,SI")])
2737
2738 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2739 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2740 ;; Pushing using integer instructions is longer except for constants
2741 ;; and direct memory references (assuming that any given constant is pushed
2742 ;; only once, but this ought to be handled elsewhere).
2743
2744 (define_insn "*pushxf_nointeger"
2745 [(set (match_operand:XF 0 "push_operand" "=<,<")
2746 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2747 "optimize_function_for_size_p (cfun)"
2748 {
2749 /* This insn should be already split before reg-stack. */
2750 gcc_unreachable ();
2751 }
2752 [(set_attr "type" "multi")
2753 (set_attr "unit" "i387,*")
2754 (set_attr "mode" "XF,SI")])
2755
2756 ;; %%% Kill this when call knows how to work this out.
2757 (define_split
2758 [(set (match_operand:XF 0 "push_operand" "")
2759 (match_operand:XF 1 "fp_register_operand" ""))]
2760 "reload_completed"
2761 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2762 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2763 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2764
2765 (define_insn "*pushdf_rex64"
2766 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2767 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2768 "TARGET_64BIT"
2769 {
2770 /* This insn should be already split before reg-stack. */
2771 gcc_unreachable ();
2772 }
2773 [(set_attr "type" "multi")
2774 (set_attr "unit" "i387,*,*")
2775 (set_attr "mode" "DF,DI,DF")])
2776
2777 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2778 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2779 ;; On the average, pushdf using integers can be still shorter.
2780
2781 (define_insn "*pushdf"
2782 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2783 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2784 "!TARGET_64BIT"
2785 {
2786 /* This insn should be already split before reg-stack. */
2787 gcc_unreachable ();
2788 }
2789 [(set_attr "isa" "*,*,sse2")
2790 (set_attr "type" "multi")
2791 (set_attr "unit" "i387,*,*")
2792 (set_attr "mode" "DF,DI,DF")])
2793
2794 ;; %%% Kill this when call knows how to work this out.
2795 (define_split
2796 [(set (match_operand:DF 0 "push_operand" "")
2797 (match_operand:DF 1 "any_fp_register_operand" ""))]
2798 "reload_completed"
2799 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2800 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2801
2802 (define_insn "*pushsf_rex64"
2803 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2804 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2805 "TARGET_64BIT"
2806 {
2807 /* Anything else should be already split before reg-stack. */
2808 gcc_assert (which_alternative == 1);
2809 return "push{q}\t%q1";
2810 }
2811 [(set_attr "type" "multi,push,multi")
2812 (set_attr "unit" "i387,*,*")
2813 (set_attr "mode" "SF,DI,SF")])
2814
2815 (define_insn "*pushsf"
2816 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2817 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2818 "!TARGET_64BIT"
2819 {
2820 /* Anything else should be already split before reg-stack. */
2821 gcc_assert (which_alternative == 1);
2822 return "push{l}\t%1";
2823 }
2824 [(set_attr "type" "multi,push,multi")
2825 (set_attr "unit" "i387,*,*")
2826 (set_attr "mode" "SF,SI,SF")])
2827
2828 ;; %%% Kill this when call knows how to work this out.
2829 (define_split
2830 [(set (match_operand:SF 0 "push_operand" "")
2831 (match_operand:SF 1 "any_fp_register_operand" ""))]
2832 "reload_completed"
2833 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2834 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2835 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2836
2837 (define_split
2838 [(set (match_operand:SF 0 "push_operand" "")
2839 (match_operand:SF 1 "memory_operand" ""))]
2840 "reload_completed
2841 && (operands[2] = find_constant_src (insn))"
2842 [(set (match_dup 0) (match_dup 2))])
2843
2844 (define_split
2845 [(set (match_operand 0 "push_operand" "")
2846 (match_operand 1 "general_operand" ""))]
2847 "reload_completed
2848 && (GET_MODE (operands[0]) == TFmode
2849 || GET_MODE (operands[0]) == XFmode
2850 || GET_MODE (operands[0]) == DFmode)
2851 && !ANY_FP_REG_P (operands[1])"
2852 [(const_int 0)]
2853 "ix86_split_long_move (operands); DONE;")
2854 \f
2855 ;; Floating point move instructions.
2856
2857 (define_expand "movtf"
2858 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2859 (match_operand:TF 1 "nonimmediate_operand" ""))]
2860 "TARGET_SSE2"
2861 {
2862 ix86_expand_move (TFmode, operands);
2863 DONE;
2864 })
2865
2866 (define_expand "mov<mode>"
2867 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2868 (match_operand:X87MODEF 1 "general_operand" ""))]
2869 ""
2870 "ix86_expand_move (<MODE>mode, operands); DONE;")
2871
2872 (define_insn "*movtf_internal"
2873 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2874 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2875 "TARGET_SSE2
2876 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2877 && (!can_create_pseudo_p ()
2878 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2879 || GET_CODE (operands[1]) != CONST_DOUBLE
2880 || (optimize_function_for_size_p (cfun)
2881 && standard_sse_constant_p (operands[1])
2882 && !memory_operand (operands[0], TFmode))
2883 || (!TARGET_MEMORY_MISMATCH_STALL
2884 && memory_operand (operands[0], TFmode)))"
2885 {
2886 switch (which_alternative)
2887 {
2888 case 0:
2889 case 1:
2890 /* Handle misaligned load/store since we
2891 don't have movmisaligntf pattern. */
2892 if (misaligned_operand (operands[0], TFmode)
2893 || misaligned_operand (operands[1], TFmode))
2894 {
2895 if (get_attr_mode (insn) == MODE_V4SF)
2896 return "%vmovups\t{%1, %0|%0, %1}";
2897 else
2898 return "%vmovdqu\t{%1, %0|%0, %1}";
2899 }
2900 else
2901 {
2902 if (get_attr_mode (insn) == MODE_V4SF)
2903 return "%vmovaps\t{%1, %0|%0, %1}";
2904 else
2905 return "%vmovdqa\t{%1, %0|%0, %1}";
2906 }
2907
2908 case 2:
2909 return standard_sse_constant_opcode (insn, operands[1]);
2910
2911 case 3:
2912 case 4:
2913 return "#";
2914
2915 default:
2916 gcc_unreachable ();
2917 }
2918 }
2919 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2920 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2921 (set (attr "mode")
2922 (cond [(eq_attr "alternative" "0,2")
2923 (if_then_else
2924 (match_test "optimize_function_for_size_p (cfun)")
2925 (const_string "V4SF")
2926 (const_string "TI"))
2927 (eq_attr "alternative" "1")
2928 (if_then_else
2929 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2930 (match_test "optimize_function_for_size_p (cfun)"))
2931 (const_string "V4SF")
2932 (const_string "TI"))]
2933 (const_string "DI")))])
2934
2935 ;; Possible store forwarding (partial memory) stall in alternative 4.
2936 (define_insn "*movxf_internal"
2937 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2938 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2939 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2940 && (!can_create_pseudo_p ()
2941 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2942 || GET_CODE (operands[1]) != CONST_DOUBLE
2943 || (optimize_function_for_size_p (cfun)
2944 && standard_80387_constant_p (operands[1]) > 0
2945 && !memory_operand (operands[0], XFmode))
2946 || (!TARGET_MEMORY_MISMATCH_STALL
2947 && memory_operand (operands[0], XFmode)))"
2948 {
2949 switch (which_alternative)
2950 {
2951 case 0:
2952 case 1:
2953 return output_387_reg_move (insn, operands);
2954
2955 case 2:
2956 return standard_80387_constant_opcode (operands[1]);
2957
2958 case 3:
2959 case 4:
2960 return "#";
2961
2962 default:
2963 gcc_unreachable ();
2964 }
2965 }
2966 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2967 (set_attr "mode" "XF,XF,XF,SI,SI")])
2968
2969 (define_insn "*movdf_internal_rex64"
2970 [(set (match_operand:DF 0 "nonimmediate_operand"
2971 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2972 (match_operand:DF 1 "general_operand"
2973 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2974 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2975 && (!can_create_pseudo_p ()
2976 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2977 || GET_CODE (operands[1]) != CONST_DOUBLE
2978 || (optimize_function_for_size_p (cfun)
2979 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2980 && standard_80387_constant_p (operands[1]) > 0)
2981 || (TARGET_SSE2 && TARGET_SSE_MATH
2982 && standard_sse_constant_p (operands[1]))))
2983 || memory_operand (operands[0], DFmode))"
2984 {
2985 switch (which_alternative)
2986 {
2987 case 0:
2988 case 1:
2989 return output_387_reg_move (insn, operands);
2990
2991 case 2:
2992 return standard_80387_constant_opcode (operands[1]);
2993
2994 case 3:
2995 case 4:
2996 return "mov{q}\t{%1, %0|%0, %1}";
2997
2998 case 5:
2999 return "movabs{q}\t{%1, %0|%0, %1}";
3000
3001 case 6:
3002 return "#";
3003
3004 case 7:
3005 return standard_sse_constant_opcode (insn, operands[1]);
3006
3007 case 8:
3008 case 9:
3009 case 10:
3010 switch (get_attr_mode (insn))
3011 {
3012 case MODE_V2DF:
3013 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3014 return "%vmovapd\t{%1, %0|%0, %1}";
3015 case MODE_V4SF:
3016 return "%vmovaps\t{%1, %0|%0, %1}";
3017
3018 case MODE_DI:
3019 return "%vmovq\t{%1, %0|%0, %1}";
3020 case MODE_DF:
3021 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3022 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3023 return "%vmovsd\t{%1, %0|%0, %1}";
3024 case MODE_V1DF:
3025 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3026 case MODE_V2SF:
3027 return "%vmovlps\t{%1, %d0|%d0, %1}";
3028 default:
3029 gcc_unreachable ();
3030 }
3031
3032 case 11:
3033 case 12:
3034 /* Handle broken assemblers that require movd instead of movq. */
3035 return "%vmovd\t{%1, %0|%0, %1}";
3036
3037 default:
3038 gcc_unreachable();
3039 }
3040 }
3041 [(set (attr "type")
3042 (cond [(eq_attr "alternative" "0,1,2")
3043 (const_string "fmov")
3044 (eq_attr "alternative" "3,4,5")
3045 (const_string "imov")
3046 (eq_attr "alternative" "6")
3047 (const_string "multi")
3048 (eq_attr "alternative" "7")
3049 (const_string "sselog1")
3050 ]
3051 (const_string "ssemov")))
3052 (set (attr "modrm")
3053 (if_then_else
3054 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3055 (const_string "0")
3056 (const_string "*")))
3057 (set (attr "length_immediate")
3058 (if_then_else
3059 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3060 (const_string "8")
3061 (const_string "*")))
3062 (set (attr "prefix")
3063 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3064 (const_string "orig")
3065 (const_string "maybe_vex")))
3066 (set (attr "prefix_data16")
3067 (if_then_else (eq_attr "mode" "V1DF")
3068 (const_string "1")
3069 (const_string "*")))
3070 (set (attr "mode")
3071 (cond [(eq_attr "alternative" "0,1,2")
3072 (const_string "DF")
3073 (eq_attr "alternative" "3,4,5,6,11,12")
3074 (const_string "DI")
3075
3076 /* xorps is one byte shorter. */
3077 (eq_attr "alternative" "7")
3078 (cond [(match_test "optimize_function_for_size_p (cfun)")
3079 (const_string "V4SF")
3080 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3081 (const_string "TI")
3082 ]
3083 (const_string "V2DF"))
3084
3085 /* For architectures resolving dependencies on
3086 whole SSE registers use APD move to break dependency
3087 chains, otherwise use short move to avoid extra work.
3088
3089 movaps encodes one byte shorter. */
3090 (eq_attr "alternative" "8")
3091 (cond
3092 [(match_test "optimize_function_for_size_p (cfun)")
3093 (const_string "V4SF")
3094 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3095 (const_string "V2DF")
3096 ]
3097 (const_string "DF"))
3098 /* For architectures resolving dependencies on register
3099 parts we may avoid extra work to zero out upper part
3100 of register. */
3101 (eq_attr "alternative" "9")
3102 (if_then_else
3103 (match_test "TARGET_SSE_SPLIT_REGS")
3104 (const_string "V1DF")
3105 (const_string "DF"))
3106 ]
3107 (const_string "DF")))])
3108
3109 ;; Possible store forwarding (partial memory) stall in alternative 4.
3110 (define_insn "*movdf_internal"
3111 [(set (match_operand:DF 0 "nonimmediate_operand"
3112 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3113 (match_operand:DF 1 "general_operand"
3114 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3115 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3116 && (!can_create_pseudo_p ()
3117 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3118 || GET_CODE (operands[1]) != CONST_DOUBLE
3119 || (optimize_function_for_size_p (cfun)
3120 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3121 && standard_80387_constant_p (operands[1]) > 0)
3122 || (TARGET_SSE2 && TARGET_SSE_MATH
3123 && standard_sse_constant_p (operands[1])))
3124 && !memory_operand (operands[0], DFmode))
3125 || (!TARGET_MEMORY_MISMATCH_STALL
3126 && memory_operand (operands[0], DFmode)))"
3127 {
3128 switch (which_alternative)
3129 {
3130 case 0:
3131 case 1:
3132 return output_387_reg_move (insn, operands);
3133
3134 case 2:
3135 return standard_80387_constant_opcode (operands[1]);
3136
3137 case 3:
3138 case 4:
3139 return "#";
3140
3141 case 5:
3142 case 9:
3143 return standard_sse_constant_opcode (insn, operands[1]);
3144
3145 case 6:
3146 case 7:
3147 case 8:
3148 case 10:
3149 case 11:
3150 case 12:
3151 switch (get_attr_mode (insn))
3152 {
3153 case MODE_V2DF:
3154 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3155 return "%vmovapd\t{%1, %0|%0, %1}";
3156 case MODE_V4SF:
3157 return "%vmovaps\t{%1, %0|%0, %1}";
3158
3159 case MODE_DI:
3160 return "%vmovq\t{%1, %0|%0, %1}";
3161 case MODE_DF:
3162 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3163 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3164 return "%vmovsd\t{%1, %0|%0, %1}";
3165 case MODE_V1DF:
3166 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3167 case MODE_V2SF:
3168 return "%vmovlps\t{%1, %d0|%d0, %1}";
3169 default:
3170 gcc_unreachable ();
3171 }
3172
3173 default:
3174 gcc_unreachable ();
3175 }
3176 }
3177 [(set (attr "isa")
3178 (if_then_else (eq_attr "alternative" "5,6,7,8")
3179 (const_string "sse2")
3180 (const_string "*")))
3181 (set (attr "type")
3182 (cond [(eq_attr "alternative" "0,1,2")
3183 (const_string "fmov")
3184 (eq_attr "alternative" "3,4")
3185 (const_string "multi")
3186 (eq_attr "alternative" "5,9")
3187 (const_string "sselog1")
3188 ]
3189 (const_string "ssemov")))
3190 (set (attr "prefix")
3191 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3192 (const_string "orig")
3193 (const_string "maybe_vex")))
3194 (set (attr "prefix_data16")
3195 (if_then_else (eq_attr "mode" "V1DF")
3196 (const_string "1")
3197 (const_string "*")))
3198 (set (attr "mode")
3199 (cond [(eq_attr "alternative" "0,1,2")
3200 (const_string "DF")
3201 (eq_attr "alternative" "3,4")
3202 (const_string "SI")
3203
3204 /* For SSE1, we have many fewer alternatives. */
3205 (not (match_test "TARGET_SSE2"))
3206 (if_then_else
3207 (eq_attr "alternative" "5,6,9,10")
3208 (const_string "V4SF")
3209 (const_string "V2SF"))
3210
3211 /* xorps is one byte shorter. */
3212 (eq_attr "alternative" "5,9")
3213 (cond [(match_test "optimize_function_for_size_p (cfun)")
3214 (const_string "V4SF")
3215 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3216 (const_string "TI")
3217 ]
3218 (const_string "V2DF"))
3219
3220 /* For architectures resolving dependencies on
3221 whole SSE registers use APD move to break dependency
3222 chains, otherwise use short move to avoid extra work.
3223
3224 movaps encodes one byte shorter. */
3225 (eq_attr "alternative" "6,10")
3226 (cond
3227 [(match_test "optimize_function_for_size_p (cfun)")
3228 (const_string "V4SF")
3229 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3230 (const_string "V2DF")
3231 ]
3232 (const_string "DF"))
3233 /* For architectures resolving dependencies on register
3234 parts we may avoid extra work to zero out upper part
3235 of register. */
3236 (eq_attr "alternative" "7,11")
3237 (if_then_else
3238 (match_test "TARGET_SSE_SPLIT_REGS")
3239 (const_string "V1DF")
3240 (const_string "DF"))
3241 ]
3242 (const_string "DF")))])
3243
3244 (define_insn "*movsf_internal"
3245 [(set (match_operand:SF 0 "nonimmediate_operand"
3246 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3247 (match_operand:SF 1 "general_operand"
3248 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3249 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3250 && (!can_create_pseudo_p ()
3251 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3252 || GET_CODE (operands[1]) != CONST_DOUBLE
3253 || (optimize_function_for_size_p (cfun)
3254 && ((!TARGET_SSE_MATH
3255 && standard_80387_constant_p (operands[1]) > 0)
3256 || (TARGET_SSE_MATH
3257 && standard_sse_constant_p (operands[1]))))
3258 || memory_operand (operands[0], SFmode))"
3259 {
3260 switch (which_alternative)
3261 {
3262 case 0:
3263 case 1:
3264 return output_387_reg_move (insn, operands);
3265
3266 case 2:
3267 return standard_80387_constant_opcode (operands[1]);
3268
3269 case 3:
3270 case 4:
3271 return "mov{l}\t{%1, %0|%0, %1}";
3272
3273 case 5:
3274 return standard_sse_constant_opcode (insn, operands[1]);
3275
3276 case 6:
3277 if (get_attr_mode (insn) == MODE_V4SF)
3278 return "%vmovaps\t{%1, %0|%0, %1}";
3279 if (TARGET_AVX)
3280 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3281
3282 case 7:
3283 case 8:
3284 return "%vmovss\t{%1, %0|%0, %1}";
3285
3286 case 9:
3287 case 10:
3288 case 14:
3289 case 15:
3290 return "movd\t{%1, %0|%0, %1}";
3291
3292 case 11:
3293 return "movq\t{%1, %0|%0, %1}";
3294
3295 case 12:
3296 case 13:
3297 return "%vmovd\t{%1, %0|%0, %1}";
3298
3299 default:
3300 gcc_unreachable ();
3301 }
3302 }
3303 [(set (attr "type")
3304 (cond [(eq_attr "alternative" "0,1,2")
3305 (const_string "fmov")
3306 (eq_attr "alternative" "3,4")
3307 (const_string "multi")
3308 (eq_attr "alternative" "5")
3309 (const_string "sselog1")
3310 (eq_attr "alternative" "9,10,11,14,15")
3311 (const_string "mmxmov")
3312 ]
3313 (const_string "ssemov")))
3314 (set (attr "prefix")
3315 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3316 (const_string "maybe_vex")
3317 (const_string "orig")))
3318 (set (attr "mode")
3319 (cond [(eq_attr "alternative" "3,4,9,10")
3320 (const_string "SI")
3321 (eq_attr "alternative" "5")
3322 (if_then_else
3323 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3324 (match_test "TARGET_SSE2"))
3325 (not (match_test "optimize_function_for_size_p (cfun)")))
3326 (const_string "TI")
3327 (const_string "V4SF"))
3328 /* For architectures resolving dependencies on
3329 whole SSE registers use APS move to break dependency
3330 chains, otherwise use short move to avoid extra work.
3331
3332 Do the same for architectures resolving dependencies on
3333 the parts. While in DF mode it is better to always handle
3334 just register parts, the SF mode is different due to lack
3335 of instructions to load just part of the register. It is
3336 better to maintain the whole registers in single format
3337 to avoid problems on using packed logical operations. */
3338 (eq_attr "alternative" "6")
3339 (if_then_else
3340 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3341 (match_test "TARGET_SSE_SPLIT_REGS"))
3342 (const_string "V4SF")
3343 (const_string "SF"))
3344 (eq_attr "alternative" "11")
3345 (const_string "DI")]
3346 (const_string "SF")))])
3347
3348 (define_split
3349 [(set (match_operand 0 "any_fp_register_operand" "")
3350 (match_operand 1 "memory_operand" ""))]
3351 "reload_completed
3352 && (GET_MODE (operands[0]) == TFmode
3353 || GET_MODE (operands[0]) == XFmode
3354 || GET_MODE (operands[0]) == DFmode
3355 || GET_MODE (operands[0]) == SFmode)
3356 && (operands[2] = find_constant_src (insn))"
3357 [(set (match_dup 0) (match_dup 2))]
3358 {
3359 rtx c = operands[2];
3360 int r = REGNO (operands[0]);
3361
3362 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3363 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3364 FAIL;
3365 })
3366
3367 (define_split
3368 [(set (match_operand 0 "any_fp_register_operand" "")
3369 (float_extend (match_operand 1 "memory_operand" "")))]
3370 "reload_completed
3371 && (GET_MODE (operands[0]) == TFmode
3372 || GET_MODE (operands[0]) == XFmode
3373 || GET_MODE (operands[0]) == DFmode)
3374 && (operands[2] = find_constant_src (insn))"
3375 [(set (match_dup 0) (match_dup 2))]
3376 {
3377 rtx c = operands[2];
3378 int r = REGNO (operands[0]);
3379
3380 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3381 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3382 FAIL;
3383 })
3384
3385 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3386 (define_split
3387 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3388 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3389 "reload_completed
3390 && (standard_80387_constant_p (operands[1]) == 8
3391 || standard_80387_constant_p (operands[1]) == 9)"
3392 [(set (match_dup 0)(match_dup 1))
3393 (set (match_dup 0)
3394 (neg:X87MODEF (match_dup 0)))]
3395 {
3396 REAL_VALUE_TYPE r;
3397
3398 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3399 if (real_isnegzero (&r))
3400 operands[1] = CONST0_RTX (<MODE>mode);
3401 else
3402 operands[1] = CONST1_RTX (<MODE>mode);
3403 })
3404
3405 (define_split
3406 [(set (match_operand 0 "nonimmediate_operand" "")
3407 (match_operand 1 "general_operand" ""))]
3408 "reload_completed
3409 && (GET_MODE (operands[0]) == TFmode
3410 || GET_MODE (operands[0]) == XFmode
3411 || GET_MODE (operands[0]) == DFmode)
3412 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3413 [(const_int 0)]
3414 "ix86_split_long_move (operands); DONE;")
3415
3416 (define_insn "swapxf"
3417 [(set (match_operand:XF 0 "register_operand" "+f")
3418 (match_operand:XF 1 "register_operand" "+f"))
3419 (set (match_dup 1)
3420 (match_dup 0))]
3421 "TARGET_80387"
3422 {
3423 if (STACK_TOP_P (operands[0]))
3424 return "fxch\t%1";
3425 else
3426 return "fxch\t%0";
3427 }
3428 [(set_attr "type" "fxch")
3429 (set_attr "mode" "XF")])
3430
3431 (define_insn "*swap<mode>"
3432 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3433 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3434 (set (match_dup 1)
3435 (match_dup 0))]
3436 "TARGET_80387 || reload_completed"
3437 {
3438 if (STACK_TOP_P (operands[0]))
3439 return "fxch\t%1";
3440 else
3441 return "fxch\t%0";
3442 }
3443 [(set_attr "type" "fxch")
3444 (set_attr "mode" "<MODE>")])
3445 \f
3446 ;; Zero extension instructions
3447
3448 (define_expand "zero_extendsidi2"
3449 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3450 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3451 ""
3452 {
3453 if (!TARGET_64BIT)
3454 {
3455 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3456 DONE;
3457 }
3458 })
3459
3460 (define_insn "*zero_extendsidi2_rex64"
3461 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3462 (zero_extend:DI
3463 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3464 "TARGET_64BIT"
3465 "@
3466 mov\t{%k1, %k0|%k0, %k1}
3467 #
3468 movd\t{%1, %0|%0, %1}
3469 movd\t{%1, %0|%0, %1}
3470 %vmovd\t{%1, %0|%0, %1}
3471 %vmovd\t{%1, %0|%0, %1}"
3472 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3473 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3474 (set_attr "prefix_0f" "0,*,*,*,*,*")
3475 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3476
3477 (define_split
3478 [(set (match_operand:DI 0 "memory_operand" "")
3479 (zero_extend:DI (match_dup 0)))]
3480 "TARGET_64BIT"
3481 [(set (match_dup 4) (const_int 0))]
3482 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3483
3484 ;; %%% Kill me once multi-word ops are sane.
3485 (define_insn "zero_extendsidi2_1"
3486 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3487 (zero_extend:DI
3488 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3489 (clobber (reg:CC FLAGS_REG))]
3490 "!TARGET_64BIT"
3491 "@
3492 #
3493 #
3494 #
3495 movd\t{%1, %0|%0, %1}
3496 movd\t{%1, %0|%0, %1}
3497 %vmovd\t{%1, %0|%0, %1}
3498 %vmovd\t{%1, %0|%0, %1}"
3499 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3500 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3501 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3502 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3503
3504 (define_split
3505 [(set (match_operand:DI 0 "register_operand" "")
3506 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3507 (clobber (reg:CC FLAGS_REG))]
3508 "!TARGET_64BIT && reload_completed
3509 && true_regnum (operands[0]) == true_regnum (operands[1])"
3510 [(set (match_dup 4) (const_int 0))]
3511 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3512
3513 (define_split
3514 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3515 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3516 (clobber (reg:CC FLAGS_REG))]
3517 "!TARGET_64BIT && reload_completed
3518 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3519 [(set (match_dup 3) (match_dup 1))
3520 (set (match_dup 4) (const_int 0))]
3521 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3522
3523 (define_insn "zero_extend<mode>di2"
3524 [(set (match_operand:DI 0 "register_operand" "=r")
3525 (zero_extend:DI
3526 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3527 "TARGET_64BIT"
3528 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3529 [(set_attr "type" "imovx")
3530 (set_attr "mode" "SI")])
3531
3532 (define_expand "zero_extendhisi2"
3533 [(set (match_operand:SI 0 "register_operand" "")
3534 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3535 ""
3536 {
3537 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3538 {
3539 operands[1] = force_reg (HImode, operands[1]);
3540 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3541 DONE;
3542 }
3543 })
3544
3545 (define_insn_and_split "zero_extendhisi2_and"
3546 [(set (match_operand:SI 0 "register_operand" "=r")
3547 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3548 (clobber (reg:CC FLAGS_REG))]
3549 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3550 "#"
3551 "&& reload_completed"
3552 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3553 (clobber (reg:CC FLAGS_REG))])]
3554 ""
3555 [(set_attr "type" "alu1")
3556 (set_attr "mode" "SI")])
3557
3558 (define_insn "*zero_extendhisi2_movzwl"
3559 [(set (match_operand:SI 0 "register_operand" "=r")
3560 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3561 "!TARGET_ZERO_EXTEND_WITH_AND
3562 || optimize_function_for_size_p (cfun)"
3563 "movz{wl|x}\t{%1, %0|%0, %1}"
3564 [(set_attr "type" "imovx")
3565 (set_attr "mode" "SI")])
3566
3567 (define_expand "zero_extendqi<mode>2"
3568 [(parallel
3569 [(set (match_operand:SWI24 0 "register_operand" "")
3570 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3571 (clobber (reg:CC FLAGS_REG))])])
3572
3573 (define_insn "*zero_extendqi<mode>2_and"
3574 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3575 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3576 (clobber (reg:CC FLAGS_REG))]
3577 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3578 "#"
3579 [(set_attr "type" "alu1")
3580 (set_attr "mode" "<MODE>")])
3581
3582 ;; When source and destination does not overlap, clear destination
3583 ;; first and then do the movb
3584 (define_split
3585 [(set (match_operand:SWI24 0 "register_operand" "")
3586 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3587 (clobber (reg:CC FLAGS_REG))]
3588 "reload_completed
3589 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3590 && ANY_QI_REG_P (operands[0])
3591 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3592 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3593 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3594 {
3595 operands[2] = gen_lowpart (QImode, operands[0]);
3596 ix86_expand_clear (operands[0]);
3597 })
3598
3599 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3600 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3601 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3602 (clobber (reg:CC FLAGS_REG))]
3603 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3604 "#"
3605 [(set_attr "type" "imovx,alu1")
3606 (set_attr "mode" "<MODE>")])
3607
3608 ;; For the movzbl case strip only the clobber
3609 (define_split
3610 [(set (match_operand:SWI24 0 "register_operand" "")
3611 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3612 (clobber (reg:CC FLAGS_REG))]
3613 "reload_completed
3614 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3615 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3616 [(set (match_dup 0)
3617 (zero_extend:SWI24 (match_dup 1)))])
3618
3619 ; zero extend to SImode to avoid partial register stalls
3620 (define_insn "*zero_extendqi<mode>2_movzbl"
3621 [(set (match_operand:SWI24 0 "register_operand" "=r")
3622 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3623 "reload_completed
3624 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3625 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3626 [(set_attr "type" "imovx")
3627 (set_attr "mode" "SI")])
3628
3629 ;; Rest is handled by single and.
3630 (define_split
3631 [(set (match_operand:SWI24 0 "register_operand" "")
3632 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3633 (clobber (reg:CC FLAGS_REG))]
3634 "reload_completed
3635 && true_regnum (operands[0]) == true_regnum (operands[1])"
3636 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3637 (clobber (reg:CC FLAGS_REG))])])
3638 \f
3639 ;; Sign extension instructions
3640
3641 (define_expand "extendsidi2"
3642 [(set (match_operand:DI 0 "register_operand" "")
3643 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3644 ""
3645 {
3646 if (!TARGET_64BIT)
3647 {
3648 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3649 DONE;
3650 }
3651 })
3652
3653 (define_insn "*extendsidi2_rex64"
3654 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3655 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3656 "TARGET_64BIT"
3657 "@
3658 {cltq|cdqe}
3659 movs{lq|x}\t{%1, %0|%0, %1}"
3660 [(set_attr "type" "imovx")
3661 (set_attr "mode" "DI")
3662 (set_attr "prefix_0f" "0")
3663 (set_attr "modrm" "0,1")])
3664
3665 (define_insn "extendsidi2_1"
3666 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3667 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3668 (clobber (reg:CC FLAGS_REG))
3669 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3670 "!TARGET_64BIT"
3671 "#")
3672
3673 ;; Extend to memory case when source register does die.
3674 (define_split
3675 [(set (match_operand:DI 0 "memory_operand" "")
3676 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3677 (clobber (reg:CC FLAGS_REG))
3678 (clobber (match_operand:SI 2 "register_operand" ""))]
3679 "(reload_completed
3680 && dead_or_set_p (insn, operands[1])
3681 && !reg_mentioned_p (operands[1], operands[0]))"
3682 [(set (match_dup 3) (match_dup 1))
3683 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3684 (clobber (reg:CC FLAGS_REG))])
3685 (set (match_dup 4) (match_dup 1))]
3686 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3687
3688 ;; Extend to memory case when source register does not die.
3689 (define_split
3690 [(set (match_operand:DI 0 "memory_operand" "")
3691 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3692 (clobber (reg:CC FLAGS_REG))
3693 (clobber (match_operand:SI 2 "register_operand" ""))]
3694 "reload_completed"
3695 [(const_int 0)]
3696 {
3697 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3698
3699 emit_move_insn (operands[3], operands[1]);
3700
3701 /* Generate a cltd if possible and doing so it profitable. */
3702 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3703 && true_regnum (operands[1]) == AX_REG
3704 && true_regnum (operands[2]) == DX_REG)
3705 {
3706 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3707 }
3708 else
3709 {
3710 emit_move_insn (operands[2], operands[1]);
3711 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3712 }
3713 emit_move_insn (operands[4], operands[2]);
3714 DONE;
3715 })
3716
3717 ;; Extend to register case. Optimize case where source and destination
3718 ;; registers match and cases where we can use cltd.
3719 (define_split
3720 [(set (match_operand:DI 0 "register_operand" "")
3721 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3722 (clobber (reg:CC FLAGS_REG))
3723 (clobber (match_scratch:SI 2 ""))]
3724 "reload_completed"
3725 [(const_int 0)]
3726 {
3727 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3728
3729 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3730 emit_move_insn (operands[3], operands[1]);
3731
3732 /* Generate a cltd if possible and doing so it profitable. */
3733 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3734 && true_regnum (operands[3]) == AX_REG
3735 && true_regnum (operands[4]) == DX_REG)
3736 {
3737 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3738 DONE;
3739 }
3740
3741 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3742 emit_move_insn (operands[4], operands[1]);
3743
3744 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3745 DONE;
3746 })
3747
3748 (define_insn "extend<mode>di2"
3749 [(set (match_operand:DI 0 "register_operand" "=r")
3750 (sign_extend:DI
3751 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3752 "TARGET_64BIT"
3753 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3754 [(set_attr "type" "imovx")
3755 (set_attr "mode" "DI")])
3756
3757 (define_insn "extendhisi2"
3758 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3759 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3760 ""
3761 {
3762 switch (get_attr_prefix_0f (insn))
3763 {
3764 case 0:
3765 return "{cwtl|cwde}";
3766 default:
3767 return "movs{wl|x}\t{%1, %0|%0, %1}";
3768 }
3769 }
3770 [(set_attr "type" "imovx")
3771 (set_attr "mode" "SI")
3772 (set (attr "prefix_0f")
3773 ;; movsx is short decodable while cwtl is vector decoded.
3774 (if_then_else (and (eq_attr "cpu" "!k6")
3775 (eq_attr "alternative" "0"))
3776 (const_string "0")
3777 (const_string "1")))
3778 (set (attr "modrm")
3779 (if_then_else (eq_attr "prefix_0f" "0")
3780 (const_string "0")
3781 (const_string "1")))])
3782
3783 (define_insn "*extendhisi2_zext"
3784 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3785 (zero_extend:DI
3786 (sign_extend:SI
3787 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3788 "TARGET_64BIT"
3789 {
3790 switch (get_attr_prefix_0f (insn))
3791 {
3792 case 0:
3793 return "{cwtl|cwde}";
3794 default:
3795 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3796 }
3797 }
3798 [(set_attr "type" "imovx")
3799 (set_attr "mode" "SI")
3800 (set (attr "prefix_0f")
3801 ;; movsx is short decodable while cwtl is vector decoded.
3802 (if_then_else (and (eq_attr "cpu" "!k6")
3803 (eq_attr "alternative" "0"))
3804 (const_string "0")
3805 (const_string "1")))
3806 (set (attr "modrm")
3807 (if_then_else (eq_attr "prefix_0f" "0")
3808 (const_string "0")
3809 (const_string "1")))])
3810
3811 (define_insn "extendqisi2"
3812 [(set (match_operand:SI 0 "register_operand" "=r")
3813 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3814 ""
3815 "movs{bl|x}\t{%1, %0|%0, %1}"
3816 [(set_attr "type" "imovx")
3817 (set_attr "mode" "SI")])
3818
3819 (define_insn "*extendqisi2_zext"
3820 [(set (match_operand:DI 0 "register_operand" "=r")
3821 (zero_extend:DI
3822 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3823 "TARGET_64BIT"
3824 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3825 [(set_attr "type" "imovx")
3826 (set_attr "mode" "SI")])
3827
3828 (define_insn "extendqihi2"
3829 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3830 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3831 ""
3832 {
3833 switch (get_attr_prefix_0f (insn))
3834 {
3835 case 0:
3836 return "{cbtw|cbw}";
3837 default:
3838 return "movs{bw|x}\t{%1, %0|%0, %1}";
3839 }
3840 }
3841 [(set_attr "type" "imovx")
3842 (set_attr "mode" "HI")
3843 (set (attr "prefix_0f")
3844 ;; movsx is short decodable while cwtl is vector decoded.
3845 (if_then_else (and (eq_attr "cpu" "!k6")
3846 (eq_attr "alternative" "0"))
3847 (const_string "0")
3848 (const_string "1")))
3849 (set (attr "modrm")
3850 (if_then_else (eq_attr "prefix_0f" "0")
3851 (const_string "0")
3852 (const_string "1")))])
3853 \f
3854 ;; Conversions between float and double.
3855
3856 ;; These are all no-ops in the model used for the 80387.
3857 ;; So just emit moves.
3858
3859 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3860 (define_split
3861 [(set (match_operand:DF 0 "push_operand" "")
3862 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3863 "reload_completed"
3864 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3865 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3866
3867 (define_split
3868 [(set (match_operand:XF 0 "push_operand" "")
3869 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3870 "reload_completed"
3871 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3872 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3873 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3874
3875 (define_expand "extendsfdf2"
3876 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3877 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3878 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3879 {
3880 /* ??? Needed for compress_float_constant since all fp constants
3881 are TARGET_LEGITIMATE_CONSTANT_P. */
3882 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3883 {
3884 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3885 && standard_80387_constant_p (operands[1]) > 0)
3886 {
3887 operands[1] = simplify_const_unary_operation
3888 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3889 emit_move_insn_1 (operands[0], operands[1]);
3890 DONE;
3891 }
3892 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3893 }
3894 })
3895
3896 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3897 cvtss2sd:
3898 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3899 cvtps2pd xmm2,xmm1
3900 We do the conversion post reload to avoid producing of 128bit spills
3901 that might lead to ICE on 32bit target. The sequence unlikely combine
3902 anyway. */
3903 (define_split
3904 [(set (match_operand:DF 0 "register_operand" "")
3905 (float_extend:DF
3906 (match_operand:SF 1 "nonimmediate_operand" "")))]
3907 "TARGET_USE_VECTOR_FP_CONVERTS
3908 && optimize_insn_for_speed_p ()
3909 && reload_completed && SSE_REG_P (operands[0])"
3910 [(set (match_dup 2)
3911 (float_extend:V2DF
3912 (vec_select:V2SF
3913 (match_dup 3)
3914 (parallel [(const_int 0) (const_int 1)]))))]
3915 {
3916 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3917 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3918 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3919 Try to avoid move when unpacking can be done in source. */
3920 if (REG_P (operands[1]))
3921 {
3922 /* If it is unsafe to overwrite upper half of source, we need
3923 to move to destination and unpack there. */
3924 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3925 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3926 && true_regnum (operands[0]) != true_regnum (operands[1]))
3927 {
3928 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3929 emit_move_insn (tmp, operands[1]);
3930 }
3931 else
3932 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3933 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3934 operands[3]));
3935 }
3936 else
3937 emit_insn (gen_vec_setv4sf_0 (operands[3],
3938 CONST0_RTX (V4SFmode), operands[1]));
3939 })
3940
3941 (define_insn "*extendsfdf2_mixed"
3942 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3943 (float_extend:DF
3944 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3945 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3946 {
3947 switch (which_alternative)
3948 {
3949 case 0:
3950 case 1:
3951 return output_387_reg_move (insn, operands);
3952
3953 case 2:
3954 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3955
3956 default:
3957 gcc_unreachable ();
3958 }
3959 }
3960 [(set_attr "type" "fmov,fmov,ssecvt")
3961 (set_attr "prefix" "orig,orig,maybe_vex")
3962 (set_attr "mode" "SF,XF,DF")])
3963
3964 (define_insn "*extendsfdf2_sse"
3965 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3966 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3967 "TARGET_SSE2 && TARGET_SSE_MATH"
3968 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3969 [(set_attr "type" "ssecvt")
3970 (set_attr "prefix" "maybe_vex")
3971 (set_attr "mode" "DF")])
3972
3973 (define_insn "*extendsfdf2_i387"
3974 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3975 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3976 "TARGET_80387"
3977 "* return output_387_reg_move (insn, operands);"
3978 [(set_attr "type" "fmov")
3979 (set_attr "mode" "SF,XF")])
3980
3981 (define_expand "extend<mode>xf2"
3982 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3983 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3984 "TARGET_80387"
3985 {
3986 /* ??? Needed for compress_float_constant since all fp constants
3987 are TARGET_LEGITIMATE_CONSTANT_P. */
3988 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3989 {
3990 if (standard_80387_constant_p (operands[1]) > 0)
3991 {
3992 operands[1] = simplify_const_unary_operation
3993 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3994 emit_move_insn_1 (operands[0], operands[1]);
3995 DONE;
3996 }
3997 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3998 }
3999 })
4000
4001 (define_insn "*extend<mode>xf2_i387"
4002 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4003 (float_extend:XF
4004 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4005 "TARGET_80387"
4006 "* return output_387_reg_move (insn, operands);"
4007 [(set_attr "type" "fmov")
4008 (set_attr "mode" "<MODE>,XF")])
4009
4010 ;; %%% This seems bad bad news.
4011 ;; This cannot output into an f-reg because there is no way to be sure
4012 ;; of truncating in that case. Otherwise this is just like a simple move
4013 ;; insn. So we pretend we can output to a reg in order to get better
4014 ;; register preferencing, but we really use a stack slot.
4015
4016 ;; Conversion from DFmode to SFmode.
4017
4018 (define_expand "truncdfsf2"
4019 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4020 (float_truncate:SF
4021 (match_operand:DF 1 "nonimmediate_operand" "")))]
4022 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4023 {
4024 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4025 ;
4026 else if (flag_unsafe_math_optimizations)
4027 ;
4028 else
4029 {
4030 enum ix86_stack_slot slot = (virtuals_instantiated
4031 ? SLOT_TEMP
4032 : SLOT_VIRTUAL);
4033 rtx temp = assign_386_stack_local (SFmode, slot);
4034 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4035 DONE;
4036 }
4037 })
4038
4039 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4040 cvtsd2ss:
4041 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4042 cvtpd2ps xmm2,xmm1
4043 We do the conversion post reload to avoid producing of 128bit spills
4044 that might lead to ICE on 32bit target. The sequence unlikely combine
4045 anyway. */
4046 (define_split
4047 [(set (match_operand:SF 0 "register_operand" "")
4048 (float_truncate:SF
4049 (match_operand:DF 1 "nonimmediate_operand" "")))]
4050 "TARGET_USE_VECTOR_FP_CONVERTS
4051 && optimize_insn_for_speed_p ()
4052 && reload_completed && SSE_REG_P (operands[0])"
4053 [(set (match_dup 2)
4054 (vec_concat:V4SF
4055 (float_truncate:V2SF
4056 (match_dup 4))
4057 (match_dup 3)))]
4058 {
4059 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4060 operands[3] = CONST0_RTX (V2SFmode);
4061 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4062 /* Use movsd for loading from memory, unpcklpd for registers.
4063 Try to avoid move when unpacking can be done in source, or SSE3
4064 movddup is available. */
4065 if (REG_P (operands[1]))
4066 {
4067 if (!TARGET_SSE3
4068 && true_regnum (operands[0]) != true_regnum (operands[1])
4069 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4070 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4071 {
4072 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4073 emit_move_insn (tmp, operands[1]);
4074 operands[1] = tmp;
4075 }
4076 else if (!TARGET_SSE3)
4077 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4078 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4079 }
4080 else
4081 emit_insn (gen_sse2_loadlpd (operands[4],
4082 CONST0_RTX (V2DFmode), operands[1]));
4083 })
4084
4085 (define_expand "truncdfsf2_with_temp"
4086 [(parallel [(set (match_operand:SF 0 "" "")
4087 (float_truncate:SF (match_operand:DF 1 "" "")))
4088 (clobber (match_operand:SF 2 "" ""))])])
4089
4090 (define_insn "*truncdfsf_fast_mixed"
4091 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4092 (float_truncate:SF
4093 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4094 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4095 {
4096 switch (which_alternative)
4097 {
4098 case 0:
4099 return output_387_reg_move (insn, operands);
4100 case 1:
4101 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4102 default:
4103 gcc_unreachable ();
4104 }
4105 }
4106 [(set_attr "type" "fmov,ssecvt")
4107 (set_attr "prefix" "orig,maybe_vex")
4108 (set_attr "mode" "SF")])
4109
4110 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4111 ;; because nothing we do here is unsafe.
4112 (define_insn "*truncdfsf_fast_sse"
4113 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4114 (float_truncate:SF
4115 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4116 "TARGET_SSE2 && TARGET_SSE_MATH"
4117 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4118 [(set_attr "type" "ssecvt")
4119 (set_attr "prefix" "maybe_vex")
4120 (set_attr "mode" "SF")])
4121
4122 (define_insn "*truncdfsf_fast_i387"
4123 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4124 (float_truncate:SF
4125 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4126 "TARGET_80387 && flag_unsafe_math_optimizations"
4127 "* return output_387_reg_move (insn, operands);"
4128 [(set_attr "type" "fmov")
4129 (set_attr "mode" "SF")])
4130
4131 (define_insn "*truncdfsf_mixed"
4132 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4133 (float_truncate:SF
4134 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4135 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4136 "TARGET_MIX_SSE_I387"
4137 {
4138 switch (which_alternative)
4139 {
4140 case 0:
4141 return output_387_reg_move (insn, operands);
4142 case 1:
4143 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4144
4145 default:
4146 return "#";
4147 }
4148 }
4149 [(set_attr "isa" "*,sse2,*,*,*")
4150 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4151 (set_attr "unit" "*,*,i387,i387,i387")
4152 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4153 (set_attr "mode" "SF")])
4154
4155 (define_insn "*truncdfsf_i387"
4156 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4157 (float_truncate:SF
4158 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4159 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4160 "TARGET_80387"
4161 {
4162 switch (which_alternative)
4163 {
4164 case 0:
4165 return output_387_reg_move (insn, operands);
4166
4167 default:
4168 return "#";
4169 }
4170 }
4171 [(set_attr "type" "fmov,multi,multi,multi")
4172 (set_attr "unit" "*,i387,i387,i387")
4173 (set_attr "mode" "SF")])
4174
4175 (define_insn "*truncdfsf2_i387_1"
4176 [(set (match_operand:SF 0 "memory_operand" "=m")
4177 (float_truncate:SF
4178 (match_operand:DF 1 "register_operand" "f")))]
4179 "TARGET_80387
4180 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4181 && !TARGET_MIX_SSE_I387"
4182 "* return output_387_reg_move (insn, operands);"
4183 [(set_attr "type" "fmov")
4184 (set_attr "mode" "SF")])
4185
4186 (define_split
4187 [(set (match_operand:SF 0 "register_operand" "")
4188 (float_truncate:SF
4189 (match_operand:DF 1 "fp_register_operand" "")))
4190 (clobber (match_operand 2 "" ""))]
4191 "reload_completed"
4192 [(set (match_dup 2) (match_dup 1))
4193 (set (match_dup 0) (match_dup 2))]
4194 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4195
4196 ;; Conversion from XFmode to {SF,DF}mode
4197
4198 (define_expand "truncxf<mode>2"
4199 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4200 (float_truncate:MODEF
4201 (match_operand:XF 1 "register_operand" "")))
4202 (clobber (match_dup 2))])]
4203 "TARGET_80387"
4204 {
4205 if (flag_unsafe_math_optimizations)
4206 {
4207 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4208 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4209 if (reg != operands[0])
4210 emit_move_insn (operands[0], reg);
4211 DONE;
4212 }
4213 else
4214 {
4215 enum ix86_stack_slot slot = (virtuals_instantiated
4216 ? SLOT_TEMP
4217 : SLOT_VIRTUAL);
4218 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4219 }
4220 })
4221
4222 (define_insn "*truncxfsf2_mixed"
4223 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4224 (float_truncate:SF
4225 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4226 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4227 "TARGET_80387"
4228 {
4229 gcc_assert (!which_alternative);
4230 return output_387_reg_move (insn, operands);
4231 }
4232 [(set_attr "type" "fmov,multi,multi,multi")
4233 (set_attr "unit" "*,i387,i387,i387")
4234 (set_attr "mode" "SF")])
4235
4236 (define_insn "*truncxfdf2_mixed"
4237 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4238 (float_truncate:DF
4239 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4240 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4241 "TARGET_80387"
4242 {
4243 gcc_assert (!which_alternative);
4244 return output_387_reg_move (insn, operands);
4245 }
4246 [(set_attr "isa" "*,*,sse2,*")
4247 (set_attr "type" "fmov,multi,multi,multi")
4248 (set_attr "unit" "*,i387,i387,i387")
4249 (set_attr "mode" "DF")])
4250
4251 (define_insn "truncxf<mode>2_i387_noop"
4252 [(set (match_operand:MODEF 0 "register_operand" "=f")
4253 (float_truncate:MODEF
4254 (match_operand:XF 1 "register_operand" "f")))]
4255 "TARGET_80387 && flag_unsafe_math_optimizations"
4256 "* return output_387_reg_move (insn, operands);"
4257 [(set_attr "type" "fmov")
4258 (set_attr "mode" "<MODE>")])
4259
4260 (define_insn "*truncxf<mode>2_i387"
4261 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4262 (float_truncate:MODEF
4263 (match_operand:XF 1 "register_operand" "f")))]
4264 "TARGET_80387"
4265 "* return output_387_reg_move (insn, operands);"
4266 [(set_attr "type" "fmov")
4267 (set_attr "mode" "<MODE>")])
4268
4269 (define_split
4270 [(set (match_operand:MODEF 0 "register_operand" "")
4271 (float_truncate:MODEF
4272 (match_operand:XF 1 "register_operand" "")))
4273 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4274 "TARGET_80387 && reload_completed"
4275 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4276 (set (match_dup 0) (match_dup 2))])
4277
4278 (define_split
4279 [(set (match_operand:MODEF 0 "memory_operand" "")
4280 (float_truncate:MODEF
4281 (match_operand:XF 1 "register_operand" "")))
4282 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4283 "TARGET_80387"
4284 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4285 \f
4286 ;; Signed conversion to DImode.
4287
4288 (define_expand "fix_truncxfdi2"
4289 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4290 (fix:DI (match_operand:XF 1 "register_operand" "")))
4291 (clobber (reg:CC FLAGS_REG))])]
4292 "TARGET_80387"
4293 {
4294 if (TARGET_FISTTP)
4295 {
4296 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4297 DONE;
4298 }
4299 })
4300
4301 (define_expand "fix_trunc<mode>di2"
4302 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4303 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4304 (clobber (reg:CC FLAGS_REG))])]
4305 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4306 {
4307 if (TARGET_FISTTP
4308 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4309 {
4310 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4311 DONE;
4312 }
4313 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4314 {
4315 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4316 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4317 if (out != operands[0])
4318 emit_move_insn (operands[0], out);
4319 DONE;
4320 }
4321 })
4322
4323 ;; Signed conversion to SImode.
4324
4325 (define_expand "fix_truncxfsi2"
4326 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4327 (fix:SI (match_operand:XF 1 "register_operand" "")))
4328 (clobber (reg:CC FLAGS_REG))])]
4329 "TARGET_80387"
4330 {
4331 if (TARGET_FISTTP)
4332 {
4333 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4334 DONE;
4335 }
4336 })
4337
4338 (define_expand "fix_trunc<mode>si2"
4339 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4340 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4341 (clobber (reg:CC FLAGS_REG))])]
4342 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4343 {
4344 if (TARGET_FISTTP
4345 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4346 {
4347 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4348 DONE;
4349 }
4350 if (SSE_FLOAT_MODE_P (<MODE>mode))
4351 {
4352 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4353 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4354 if (out != operands[0])
4355 emit_move_insn (operands[0], out);
4356 DONE;
4357 }
4358 })
4359
4360 ;; Signed conversion to HImode.
4361
4362 (define_expand "fix_trunc<mode>hi2"
4363 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4364 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4365 (clobber (reg:CC FLAGS_REG))])]
4366 "TARGET_80387
4367 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4368 {
4369 if (TARGET_FISTTP)
4370 {
4371 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4372 DONE;
4373 }
4374 })
4375
4376 ;; Unsigned conversion to SImode.
4377
4378 (define_expand "fixuns_trunc<mode>si2"
4379 [(parallel
4380 [(set (match_operand:SI 0 "register_operand" "")
4381 (unsigned_fix:SI
4382 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4383 (use (match_dup 2))
4384 (clobber (match_scratch:<ssevecmode> 3 ""))
4385 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4386 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4387 {
4388 enum machine_mode mode = <MODE>mode;
4389 enum machine_mode vecmode = <ssevecmode>mode;
4390 REAL_VALUE_TYPE TWO31r;
4391 rtx two31;
4392
4393 if (optimize_insn_for_size_p ())
4394 FAIL;
4395
4396 real_ldexp (&TWO31r, &dconst1, 31);
4397 two31 = const_double_from_real_value (TWO31r, mode);
4398 two31 = ix86_build_const_vector (vecmode, true, two31);
4399 operands[2] = force_reg (vecmode, two31);
4400 })
4401
4402 (define_insn_and_split "*fixuns_trunc<mode>_1"
4403 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4404 (unsigned_fix:SI
4405 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4406 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4407 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4408 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4409 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4410 && optimize_function_for_speed_p (cfun)"
4411 "#"
4412 "&& reload_completed"
4413 [(const_int 0)]
4414 {
4415 ix86_split_convert_uns_si_sse (operands);
4416 DONE;
4417 })
4418
4419 ;; Unsigned conversion to HImode.
4420 ;; Without these patterns, we'll try the unsigned SI conversion which
4421 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4422
4423 (define_expand "fixuns_trunc<mode>hi2"
4424 [(set (match_dup 2)
4425 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4426 (set (match_operand:HI 0 "nonimmediate_operand" "")
4427 (subreg:HI (match_dup 2) 0))]
4428 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4429 "operands[2] = gen_reg_rtx (SImode);")
4430
4431 ;; When SSE is available, it is always faster to use it!
4432 (define_insn "fix_trunc<mode>di_sse"
4433 [(set (match_operand:DI 0 "register_operand" "=r,r")
4434 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4435 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4436 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4437 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4438 [(set_attr "type" "sseicvt")
4439 (set_attr "prefix" "maybe_vex")
4440 (set_attr "prefix_rex" "1")
4441 (set_attr "mode" "<MODE>")
4442 (set_attr "athlon_decode" "double,vector")
4443 (set_attr "amdfam10_decode" "double,double")
4444 (set_attr "bdver1_decode" "double,double")])
4445
4446 (define_insn "fix_trunc<mode>si_sse"
4447 [(set (match_operand:SI 0 "register_operand" "=r,r")
4448 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4449 "SSE_FLOAT_MODE_P (<MODE>mode)
4450 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4451 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4452 [(set_attr "type" "sseicvt")
4453 (set_attr "prefix" "maybe_vex")
4454 (set_attr "mode" "<MODE>")
4455 (set_attr "athlon_decode" "double,vector")
4456 (set_attr "amdfam10_decode" "double,double")
4457 (set_attr "bdver1_decode" "double,double")])
4458
4459 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4460 (define_peephole2
4461 [(set (match_operand:MODEF 0 "register_operand" "")
4462 (match_operand:MODEF 1 "memory_operand" ""))
4463 (set (match_operand:SWI48x 2 "register_operand" "")
4464 (fix:SWI48x (match_dup 0)))]
4465 "TARGET_SHORTEN_X87_SSE
4466 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4467 && peep2_reg_dead_p (2, operands[0])"
4468 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4469
4470 ;; Avoid vector decoded forms of the instruction.
4471 (define_peephole2
4472 [(match_scratch:DF 2 "x")
4473 (set (match_operand:SWI48x 0 "register_operand" "")
4474 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4475 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4476 [(set (match_dup 2) (match_dup 1))
4477 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4478
4479 (define_peephole2
4480 [(match_scratch:SF 2 "x")
4481 (set (match_operand:SWI48x 0 "register_operand" "")
4482 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4483 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4484 [(set (match_dup 2) (match_dup 1))
4485 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4486
4487 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4488 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4489 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4490 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4491 && TARGET_FISTTP
4492 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4493 && (TARGET_64BIT || <MODE>mode != DImode))
4494 && TARGET_SSE_MATH)
4495 && can_create_pseudo_p ()"
4496 "#"
4497 "&& 1"
4498 [(const_int 0)]
4499 {
4500 if (memory_operand (operands[0], VOIDmode))
4501 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4502 else
4503 {
4504 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4505 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4506 operands[1],
4507 operands[2]));
4508 }
4509 DONE;
4510 }
4511 [(set_attr "type" "fisttp")
4512 (set_attr "mode" "<MODE>")])
4513
4514 (define_insn "fix_trunc<mode>_i387_fisttp"
4515 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4516 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4517 (clobber (match_scratch:XF 2 "=&1f"))]
4518 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4519 && TARGET_FISTTP
4520 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4521 && (TARGET_64BIT || <MODE>mode != DImode))
4522 && TARGET_SSE_MATH)"
4523 "* return output_fix_trunc (insn, operands, true);"
4524 [(set_attr "type" "fisttp")
4525 (set_attr "mode" "<MODE>")])
4526
4527 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4528 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4529 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4530 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4531 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4532 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && TARGET_FISTTP
4534 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4535 && (TARGET_64BIT || <MODE>mode != DImode))
4536 && TARGET_SSE_MATH)"
4537 "#"
4538 [(set_attr "type" "fisttp")
4539 (set_attr "mode" "<MODE>")])
4540
4541 (define_split
4542 [(set (match_operand:SWI248x 0 "register_operand" "")
4543 (fix:SWI248x (match_operand 1 "register_operand" "")))
4544 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4545 (clobber (match_scratch 3 ""))]
4546 "reload_completed"
4547 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4548 (clobber (match_dup 3))])
4549 (set (match_dup 0) (match_dup 2))])
4550
4551 (define_split
4552 [(set (match_operand:SWI248x 0 "memory_operand" "")
4553 (fix:SWI248x (match_operand 1 "register_operand" "")))
4554 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4555 (clobber (match_scratch 3 ""))]
4556 "reload_completed"
4557 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4558 (clobber (match_dup 3))])])
4559
4560 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4561 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4562 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4563 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4564 ;; function in i386.c.
4565 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4566 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4567 (fix:SWI248x (match_operand 1 "register_operand" "")))
4568 (clobber (reg:CC FLAGS_REG))]
4569 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4570 && !TARGET_FISTTP
4571 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4572 && (TARGET_64BIT || <MODE>mode != DImode))
4573 && can_create_pseudo_p ()"
4574 "#"
4575 "&& 1"
4576 [(const_int 0)]
4577 {
4578 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4579
4580 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4581 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4582 if (memory_operand (operands[0], VOIDmode))
4583 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4584 operands[2], operands[3]));
4585 else
4586 {
4587 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4588 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4589 operands[2], operands[3],
4590 operands[4]));
4591 }
4592 DONE;
4593 }
4594 [(set_attr "type" "fistp")
4595 (set_attr "i387_cw" "trunc")
4596 (set_attr "mode" "<MODE>")])
4597
4598 (define_insn "fix_truncdi_i387"
4599 [(set (match_operand:DI 0 "memory_operand" "=m")
4600 (fix:DI (match_operand 1 "register_operand" "f")))
4601 (use (match_operand:HI 2 "memory_operand" "m"))
4602 (use (match_operand:HI 3 "memory_operand" "m"))
4603 (clobber (match_scratch:XF 4 "=&1f"))]
4604 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4605 && !TARGET_FISTTP
4606 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4607 "* return output_fix_trunc (insn, operands, false);"
4608 [(set_attr "type" "fistp")
4609 (set_attr "i387_cw" "trunc")
4610 (set_attr "mode" "DI")])
4611
4612 (define_insn "fix_truncdi_i387_with_temp"
4613 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4614 (fix:DI (match_operand 1 "register_operand" "f,f")))
4615 (use (match_operand:HI 2 "memory_operand" "m,m"))
4616 (use (match_operand:HI 3 "memory_operand" "m,m"))
4617 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4618 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4619 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4620 && !TARGET_FISTTP
4621 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4622 "#"
4623 [(set_attr "type" "fistp")
4624 (set_attr "i387_cw" "trunc")
4625 (set_attr "mode" "DI")])
4626
4627 (define_split
4628 [(set (match_operand:DI 0 "register_operand" "")
4629 (fix:DI (match_operand 1 "register_operand" "")))
4630 (use (match_operand:HI 2 "memory_operand" ""))
4631 (use (match_operand:HI 3 "memory_operand" ""))
4632 (clobber (match_operand:DI 4 "memory_operand" ""))
4633 (clobber (match_scratch 5 ""))]
4634 "reload_completed"
4635 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4636 (use (match_dup 2))
4637 (use (match_dup 3))
4638 (clobber (match_dup 5))])
4639 (set (match_dup 0) (match_dup 4))])
4640
4641 (define_split
4642 [(set (match_operand:DI 0 "memory_operand" "")
4643 (fix:DI (match_operand 1 "register_operand" "")))
4644 (use (match_operand:HI 2 "memory_operand" ""))
4645 (use (match_operand:HI 3 "memory_operand" ""))
4646 (clobber (match_operand:DI 4 "memory_operand" ""))
4647 (clobber (match_scratch 5 ""))]
4648 "reload_completed"
4649 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4650 (use (match_dup 2))
4651 (use (match_dup 3))
4652 (clobber (match_dup 5))])])
4653
4654 (define_insn "fix_trunc<mode>_i387"
4655 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4656 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4657 (use (match_operand:HI 2 "memory_operand" "m"))
4658 (use (match_operand:HI 3 "memory_operand" "m"))]
4659 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4660 && !TARGET_FISTTP
4661 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4662 "* return output_fix_trunc (insn, operands, false);"
4663 [(set_attr "type" "fistp")
4664 (set_attr "i387_cw" "trunc")
4665 (set_attr "mode" "<MODE>")])
4666
4667 (define_insn "fix_trunc<mode>_i387_with_temp"
4668 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4669 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4670 (use (match_operand:HI 2 "memory_operand" "m,m"))
4671 (use (match_operand:HI 3 "memory_operand" "m,m"))
4672 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4673 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4674 && !TARGET_FISTTP
4675 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4676 "#"
4677 [(set_attr "type" "fistp")
4678 (set_attr "i387_cw" "trunc")
4679 (set_attr "mode" "<MODE>")])
4680
4681 (define_split
4682 [(set (match_operand:SWI24 0 "register_operand" "")
4683 (fix:SWI24 (match_operand 1 "register_operand" "")))
4684 (use (match_operand:HI 2 "memory_operand" ""))
4685 (use (match_operand:HI 3 "memory_operand" ""))
4686 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4687 "reload_completed"
4688 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4689 (use (match_dup 2))
4690 (use (match_dup 3))])
4691 (set (match_dup 0) (match_dup 4))])
4692
4693 (define_split
4694 [(set (match_operand:SWI24 0 "memory_operand" "")
4695 (fix:SWI24 (match_operand 1 "register_operand" "")))
4696 (use (match_operand:HI 2 "memory_operand" ""))
4697 (use (match_operand:HI 3 "memory_operand" ""))
4698 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4699 "reload_completed"
4700 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4701 (use (match_dup 2))
4702 (use (match_dup 3))])])
4703
4704 (define_insn "x86_fnstcw_1"
4705 [(set (match_operand:HI 0 "memory_operand" "=m")
4706 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4707 "TARGET_80387"
4708 "fnstcw\t%0"
4709 [(set (attr "length")
4710 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4711 (set_attr "mode" "HI")
4712 (set_attr "unit" "i387")
4713 (set_attr "bdver1_decode" "vector")])
4714
4715 (define_insn "x86_fldcw_1"
4716 [(set (reg:HI FPCR_REG)
4717 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4718 "TARGET_80387"
4719 "fldcw\t%0"
4720 [(set (attr "length")
4721 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4722 (set_attr "mode" "HI")
4723 (set_attr "unit" "i387")
4724 (set_attr "athlon_decode" "vector")
4725 (set_attr "amdfam10_decode" "vector")
4726 (set_attr "bdver1_decode" "vector")])
4727 \f
4728 ;; Conversion between fixed point and floating point.
4729
4730 ;; Even though we only accept memory inputs, the backend _really_
4731 ;; wants to be able to do this between registers.
4732
4733 (define_expand "floathi<mode>2"
4734 [(set (match_operand:X87MODEF 0 "register_operand" "")
4735 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4736 "TARGET_80387
4737 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4738 || TARGET_MIX_SSE_I387)")
4739
4740 ;; Pre-reload splitter to add memory clobber to the pattern.
4741 (define_insn_and_split "*floathi<mode>2_1"
4742 [(set (match_operand:X87MODEF 0 "register_operand" "")
4743 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4744 "TARGET_80387
4745 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4746 || TARGET_MIX_SSE_I387)
4747 && can_create_pseudo_p ()"
4748 "#"
4749 "&& 1"
4750 [(parallel [(set (match_dup 0)
4751 (float:X87MODEF (match_dup 1)))
4752 (clobber (match_dup 2))])]
4753 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4754
4755 (define_insn "*floathi<mode>2_i387_with_temp"
4756 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4757 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4758 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4759 "TARGET_80387
4760 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4761 || TARGET_MIX_SSE_I387)"
4762 "#"
4763 [(set_attr "type" "fmov,multi")
4764 (set_attr "mode" "<MODE>")
4765 (set_attr "unit" "*,i387")
4766 (set_attr "fp_int_src" "true")])
4767
4768 (define_insn "*floathi<mode>2_i387"
4769 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4770 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4771 "TARGET_80387
4772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4773 || TARGET_MIX_SSE_I387)"
4774 "fild%Z1\t%1"
4775 [(set_attr "type" "fmov")
4776 (set_attr "mode" "<MODE>")
4777 (set_attr "fp_int_src" "true")])
4778
4779 (define_split
4780 [(set (match_operand:X87MODEF 0 "register_operand" "")
4781 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4782 (clobber (match_operand:HI 2 "memory_operand" ""))]
4783 "TARGET_80387
4784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4785 || TARGET_MIX_SSE_I387)
4786 && reload_completed"
4787 [(set (match_dup 2) (match_dup 1))
4788 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4789
4790 (define_split
4791 [(set (match_operand:X87MODEF 0 "register_operand" "")
4792 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4793 (clobber (match_operand:HI 2 "memory_operand" ""))]
4794 "TARGET_80387
4795 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4796 || TARGET_MIX_SSE_I387)
4797 && reload_completed"
4798 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4799
4800 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4801 [(set (match_operand:X87MODEF 0 "register_operand" "")
4802 (float:X87MODEF
4803 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4804 "TARGET_80387
4805 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4806 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4807 {
4808 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4809 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4810 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4811 {
4812 rtx reg = gen_reg_rtx (XFmode);
4813 rtx (*insn)(rtx, rtx);
4814
4815 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4816
4817 if (<X87MODEF:MODE>mode == SFmode)
4818 insn = gen_truncxfsf2;
4819 else if (<X87MODEF:MODE>mode == DFmode)
4820 insn = gen_truncxfdf2;
4821 else
4822 gcc_unreachable ();
4823
4824 emit_insn (insn (operands[0], reg));
4825 DONE;
4826 }
4827 })
4828
4829 ;; Pre-reload splitter to add memory clobber to the pattern.
4830 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4831 [(set (match_operand:X87MODEF 0 "register_operand" "")
4832 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4833 "((TARGET_80387
4834 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4835 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4836 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4837 || TARGET_MIX_SSE_I387))
4838 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4839 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4840 && ((<SWI48x:MODE>mode == SImode
4841 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4842 && optimize_function_for_speed_p (cfun)
4843 && flag_trapping_math)
4844 || !(TARGET_INTER_UNIT_CONVERSIONS
4845 || optimize_function_for_size_p (cfun)))))
4846 && can_create_pseudo_p ()"
4847 "#"
4848 "&& 1"
4849 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4850 (clobber (match_dup 2))])]
4851 {
4852 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4853
4854 /* Avoid store forwarding (partial memory) stall penalty
4855 by passing DImode value through XMM registers. */
4856 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4857 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4858 && optimize_function_for_speed_p (cfun))
4859 {
4860 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4861 operands[1],
4862 operands[2]));
4863 DONE;
4864 }
4865 })
4866
4867 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4868 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4869 (float:MODEF
4870 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4871 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4872 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4873 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4874 "#"
4875 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4876 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4877 (set_attr "unit" "*,i387,*,*,*")
4878 (set_attr "athlon_decode" "*,*,double,direct,double")
4879 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4880 (set_attr "bdver1_decode" "*,*,double,direct,double")
4881 (set_attr "fp_int_src" "true")])
4882
4883 (define_insn "*floatsi<mode>2_vector_mixed"
4884 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4885 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4886 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4887 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4888 "@
4889 fild%Z1\t%1
4890 #"
4891 [(set_attr "type" "fmov,sseicvt")
4892 (set_attr "mode" "<MODE>,<ssevecmode>")
4893 (set_attr "unit" "i387,*")
4894 (set_attr "athlon_decode" "*,direct")
4895 (set_attr "amdfam10_decode" "*,double")
4896 (set_attr "bdver1_decode" "*,direct")
4897 (set_attr "fp_int_src" "true")])
4898
4899 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4900 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4901 (float:MODEF
4902 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4903 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4904 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4905 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4906 "#"
4907 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4908 (set_attr "mode" "<MODEF:MODE>")
4909 (set_attr "unit" "*,i387,*,*")
4910 (set_attr "athlon_decode" "*,*,double,direct")
4911 (set_attr "amdfam10_decode" "*,*,vector,double")
4912 (set_attr "bdver1_decode" "*,*,double,direct")
4913 (set_attr "fp_int_src" "true")])
4914
4915 (define_split
4916 [(set (match_operand:MODEF 0 "register_operand" "")
4917 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4918 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4919 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4920 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4921 && TARGET_INTER_UNIT_CONVERSIONS
4922 && reload_completed
4923 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
4924 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4925
4926 (define_split
4927 [(set (match_operand:MODEF 0 "register_operand" "")
4928 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4929 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4930 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4931 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4932 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4933 && reload_completed
4934 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
4935 [(set (match_dup 2) (match_dup 1))
4936 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4937
4938 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4939 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4940 (float:MODEF
4941 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4942 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4943 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4944 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4945 "@
4946 fild%Z1\t%1
4947 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4948 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4949 [(set_attr "type" "fmov,sseicvt,sseicvt")
4950 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4951 (set_attr "mode" "<MODEF:MODE>")
4952 (set (attr "prefix_rex")
4953 (if_then_else
4954 (and (eq_attr "prefix" "maybe_vex")
4955 (match_test "<SWI48x:MODE>mode == DImode"))
4956 (const_string "1")
4957 (const_string "*")))
4958 (set_attr "unit" "i387,*,*")
4959 (set_attr "athlon_decode" "*,double,direct")
4960 (set_attr "amdfam10_decode" "*,vector,double")
4961 (set_attr "bdver1_decode" "*,double,direct")
4962 (set_attr "fp_int_src" "true")])
4963
4964 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4965 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4966 (float:MODEF
4967 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4968 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4969 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4970 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4971 "@
4972 fild%Z1\t%1
4973 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4974 [(set_attr "type" "fmov,sseicvt")
4975 (set_attr "prefix" "orig,maybe_vex")
4976 (set_attr "mode" "<MODEF:MODE>")
4977 (set (attr "prefix_rex")
4978 (if_then_else
4979 (and (eq_attr "prefix" "maybe_vex")
4980 (match_test "<SWI48x:MODE>mode == DImode"))
4981 (const_string "1")
4982 (const_string "*")))
4983 (set_attr "athlon_decode" "*,direct")
4984 (set_attr "amdfam10_decode" "*,double")
4985 (set_attr "bdver1_decode" "*,direct")
4986 (set_attr "fp_int_src" "true")])
4987
4988 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4989 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4990 (float:MODEF
4991 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4992 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4993 "TARGET_SSE2 && TARGET_SSE_MATH
4994 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4995 "#"
4996 [(set_attr "type" "sseicvt")
4997 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4998 (set_attr "athlon_decode" "double,direct,double")
4999 (set_attr "amdfam10_decode" "vector,double,double")
5000 (set_attr "bdver1_decode" "double,direct,double")
5001 (set_attr "fp_int_src" "true")])
5002
5003 (define_insn "*floatsi<mode>2_vector_sse"
5004 [(set (match_operand:MODEF 0 "register_operand" "=x")
5005 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5006 "TARGET_SSE2 && TARGET_SSE_MATH
5007 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5008 "#"
5009 [(set_attr "type" "sseicvt")
5010 (set_attr "mode" "<MODE>")
5011 (set_attr "athlon_decode" "direct")
5012 (set_attr "amdfam10_decode" "double")
5013 (set_attr "bdver1_decode" "direct")
5014 (set_attr "fp_int_src" "true")])
5015
5016 (define_split
5017 [(set (match_operand:MODEF 0 "register_operand" "")
5018 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5019 (clobber (match_operand:SI 2 "memory_operand" ""))]
5020 "TARGET_SSE2 && TARGET_SSE_MATH
5021 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5022 && reload_completed
5023 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5024 [(const_int 0)]
5025 {
5026 rtx op1 = operands[1];
5027
5028 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5029 <MODE>mode, 0);
5030 if (GET_CODE (op1) == SUBREG)
5031 op1 = SUBREG_REG (op1);
5032
5033 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5034 {
5035 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5036 emit_insn (gen_sse2_loadld (operands[4],
5037 CONST0_RTX (V4SImode), operands[1]));
5038 }
5039 /* We can ignore possible trapping value in the
5040 high part of SSE register for non-trapping math. */
5041 else if (SSE_REG_P (op1) && !flag_trapping_math)
5042 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5043 else
5044 {
5045 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5046 emit_move_insn (operands[2], operands[1]);
5047 emit_insn (gen_sse2_loadld (operands[4],
5048 CONST0_RTX (V4SImode), operands[2]));
5049 }
5050 if (<ssevecmode>mode == V4SFmode)
5051 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5052 else
5053 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5054 DONE;
5055 })
5056
5057 (define_split
5058 [(set (match_operand:MODEF 0 "register_operand" "")
5059 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5060 (clobber (match_operand:SI 2 "memory_operand" ""))]
5061 "TARGET_SSE2 && TARGET_SSE_MATH
5062 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5063 && reload_completed
5064 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5065 [(const_int 0)]
5066 {
5067 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5068 <MODE>mode, 0);
5069 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5070
5071 emit_insn (gen_sse2_loadld (operands[4],
5072 CONST0_RTX (V4SImode), operands[1]));
5073 if (<ssevecmode>mode == V4SFmode)
5074 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5075 else
5076 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5077 DONE;
5078 })
5079
5080 (define_split
5081 [(set (match_operand:MODEF 0 "register_operand" "")
5082 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5083 "TARGET_SSE2 && TARGET_SSE_MATH
5084 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5085 && reload_completed
5086 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5087 [(const_int 0)]
5088 {
5089 rtx op1 = operands[1];
5090
5091 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5092 <MODE>mode, 0);
5093 if (GET_CODE (op1) == SUBREG)
5094 op1 = SUBREG_REG (op1);
5095
5096 if (GENERAL_REG_P (op1))
5097 {
5098 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5099 if (TARGET_INTER_UNIT_MOVES)
5100 emit_insn (gen_sse2_loadld (operands[4],
5101 CONST0_RTX (V4SImode), operands[1]));
5102 else
5103 {
5104 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5105 operands[1]);
5106 emit_insn (gen_sse2_loadld (operands[4],
5107 CONST0_RTX (V4SImode), operands[5]));
5108 ix86_free_from_memory (GET_MODE (operands[1]));
5109 }
5110 }
5111 /* We can ignore possible trapping value in the
5112 high part of SSE register for non-trapping math. */
5113 else if (SSE_REG_P (op1) && !flag_trapping_math)
5114 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5115 else
5116 gcc_unreachable ();
5117 if (<ssevecmode>mode == V4SFmode)
5118 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5119 else
5120 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5121 DONE;
5122 })
5123
5124 (define_split
5125 [(set (match_operand:MODEF 0 "register_operand" "")
5126 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5127 "TARGET_SSE2 && TARGET_SSE_MATH
5128 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5129 && reload_completed
5130 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5131 [(const_int 0)]
5132 {
5133 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5134 <MODE>mode, 0);
5135 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5136
5137 emit_insn (gen_sse2_loadld (operands[4],
5138 CONST0_RTX (V4SImode), operands[1]));
5139 if (<ssevecmode>mode == V4SFmode)
5140 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5141 else
5142 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5143 DONE;
5144 })
5145
5146 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5147 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5148 (float:MODEF
5149 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5150 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5151 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5152 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5153 "#"
5154 [(set_attr "type" "sseicvt")
5155 (set_attr "mode" "<MODEF:MODE>")
5156 (set_attr "athlon_decode" "double,direct")
5157 (set_attr "amdfam10_decode" "vector,double")
5158 (set_attr "bdver1_decode" "double,direct")
5159 (set_attr "fp_int_src" "true")])
5160
5161 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5162 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5163 (float:MODEF
5164 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5165 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5166 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5167 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5168 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5169 [(set_attr "type" "sseicvt")
5170 (set_attr "prefix" "maybe_vex")
5171 (set_attr "mode" "<MODEF:MODE>")
5172 (set (attr "prefix_rex")
5173 (if_then_else
5174 (and (eq_attr "prefix" "maybe_vex")
5175 (match_test "<SWI48x:MODE>mode == DImode"))
5176 (const_string "1")
5177 (const_string "*")))
5178 (set_attr "athlon_decode" "double,direct")
5179 (set_attr "amdfam10_decode" "vector,double")
5180 (set_attr "bdver1_decode" "double,direct")
5181 (set_attr "fp_int_src" "true")])
5182
5183 (define_split
5184 [(set (match_operand:MODEF 0 "register_operand" "")
5185 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5186 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5187 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5188 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5189 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5190 && reload_completed
5191 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5192 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5193
5194 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5195 [(set (match_operand:MODEF 0 "register_operand" "=x")
5196 (float:MODEF
5197 (match_operand:SWI48x 1 "memory_operand" "m")))]
5198 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5199 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5200 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5201 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5202 [(set_attr "type" "sseicvt")
5203 (set_attr "prefix" "maybe_vex")
5204 (set_attr "mode" "<MODEF:MODE>")
5205 (set (attr "prefix_rex")
5206 (if_then_else
5207 (and (eq_attr "prefix" "maybe_vex")
5208 (match_test "<SWI48x:MODE>mode == DImode"))
5209 (const_string "1")
5210 (const_string "*")))
5211 (set_attr "athlon_decode" "direct")
5212 (set_attr "amdfam10_decode" "double")
5213 (set_attr "bdver1_decode" "direct")
5214 (set_attr "fp_int_src" "true")])
5215
5216 (define_split
5217 [(set (match_operand:MODEF 0 "register_operand" "")
5218 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5219 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5220 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5221 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5222 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5223 && reload_completed
5224 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5225 [(set (match_dup 2) (match_dup 1))
5226 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5227
5228 (define_split
5229 [(set (match_operand:MODEF 0 "register_operand" "")
5230 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5231 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5232 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5233 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5234 && reload_completed
5235 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5236 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5237
5238 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5239 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5240 (float:X87MODEF
5241 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5242 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5243 "TARGET_80387
5244 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5245 "@
5246 fild%Z1\t%1
5247 #"
5248 [(set_attr "type" "fmov,multi")
5249 (set_attr "mode" "<X87MODEF:MODE>")
5250 (set_attr "unit" "*,i387")
5251 (set_attr "fp_int_src" "true")])
5252
5253 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5254 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5255 (float:X87MODEF
5256 (match_operand:SWI48x 1 "memory_operand" "m")))]
5257 "TARGET_80387
5258 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5259 "fild%Z1\t%1"
5260 [(set_attr "type" "fmov")
5261 (set_attr "mode" "<X87MODEF:MODE>")
5262 (set_attr "fp_int_src" "true")])
5263
5264 (define_split
5265 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5266 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5267 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5268 "TARGET_80387
5269 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5270 && reload_completed"
5271 [(set (match_dup 2) (match_dup 1))
5272 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5273
5274 (define_split
5275 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5276 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5277 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5278 "TARGET_80387
5279 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5280 && reload_completed"
5281 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5282
5283 ;; Avoid store forwarding (partial memory) stall penalty
5284 ;; by passing DImode value through XMM registers. */
5285
5286 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5287 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5288 (float:X87MODEF
5289 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5290 (clobber (match_scratch:V4SI 3 "=X,x"))
5291 (clobber (match_scratch:V4SI 4 "=X,x"))
5292 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5293 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5294 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5295 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5296 "#"
5297 [(set_attr "type" "multi")
5298 (set_attr "mode" "<X87MODEF:MODE>")
5299 (set_attr "unit" "i387")
5300 (set_attr "fp_int_src" "true")])
5301
5302 (define_split
5303 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5304 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5305 (clobber (match_scratch:V4SI 3 ""))
5306 (clobber (match_scratch:V4SI 4 ""))
5307 (clobber (match_operand:DI 2 "memory_operand" ""))]
5308 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5309 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5310 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5311 && reload_completed"
5312 [(set (match_dup 2) (match_dup 3))
5313 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5314 {
5315 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5316 Assemble the 64-bit DImode value in an xmm register. */
5317 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5318 gen_rtx_SUBREG (SImode, operands[1], 0)));
5319 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5320 gen_rtx_SUBREG (SImode, operands[1], 4)));
5321 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5322 operands[4]));
5323
5324 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5325 })
5326
5327 (define_split
5328 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5329 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5330 (clobber (match_scratch:V4SI 3 ""))
5331 (clobber (match_scratch:V4SI 4 ""))
5332 (clobber (match_operand:DI 2 "memory_operand" ""))]
5333 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5334 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5335 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5336 && reload_completed"
5337 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5338
5339 ;; Avoid store forwarding (partial memory) stall penalty by extending
5340 ;; SImode value to DImode through XMM register instead of pushing two
5341 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5342 ;; targets benefit from this optimization. Also note that fild
5343 ;; loads from memory only.
5344
5345 (define_insn "*floatunssi<mode>2_1"
5346 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5347 (unsigned_float:X87MODEF
5348 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5349 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5350 (clobber (match_scratch:SI 3 "=X,x"))]
5351 "!TARGET_64BIT
5352 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5353 && TARGET_SSE"
5354 "#"
5355 [(set_attr "type" "multi")
5356 (set_attr "mode" "<MODE>")])
5357
5358 (define_split
5359 [(set (match_operand:X87MODEF 0 "register_operand" "")
5360 (unsigned_float:X87MODEF
5361 (match_operand:SI 1 "register_operand" "")))
5362 (clobber (match_operand:DI 2 "memory_operand" ""))
5363 (clobber (match_scratch:SI 3 ""))]
5364 "!TARGET_64BIT
5365 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5366 && TARGET_SSE
5367 && reload_completed"
5368 [(set (match_dup 2) (match_dup 1))
5369 (set (match_dup 0)
5370 (float:X87MODEF (match_dup 2)))]
5371 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5372
5373 (define_split
5374 [(set (match_operand:X87MODEF 0 "register_operand" "")
5375 (unsigned_float:X87MODEF
5376 (match_operand:SI 1 "memory_operand" "")))
5377 (clobber (match_operand:DI 2 "memory_operand" ""))
5378 (clobber (match_scratch:SI 3 ""))]
5379 "!TARGET_64BIT
5380 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5381 && TARGET_SSE
5382 && reload_completed"
5383 [(set (match_dup 2) (match_dup 3))
5384 (set (match_dup 0)
5385 (float:X87MODEF (match_dup 2)))]
5386 {
5387 emit_move_insn (operands[3], operands[1]);
5388 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5389 })
5390
5391 (define_expand "floatunssi<mode>2"
5392 [(parallel
5393 [(set (match_operand:X87MODEF 0 "register_operand" "")
5394 (unsigned_float:X87MODEF
5395 (match_operand:SI 1 "nonimmediate_operand" "")))
5396 (clobber (match_dup 2))
5397 (clobber (match_scratch:SI 3 ""))])]
5398 "!TARGET_64BIT
5399 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5400 && TARGET_SSE)
5401 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5402 {
5403 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5404 {
5405 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5406 DONE;
5407 }
5408 else
5409 {
5410 enum ix86_stack_slot slot = (virtuals_instantiated
5411 ? SLOT_TEMP
5412 : SLOT_VIRTUAL);
5413 operands[2] = assign_386_stack_local (DImode, slot);
5414 }
5415 })
5416
5417 (define_expand "floatunsdisf2"
5418 [(use (match_operand:SF 0 "register_operand" ""))
5419 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5420 "TARGET_64BIT && TARGET_SSE_MATH"
5421 "x86_emit_floatuns (operands); DONE;")
5422
5423 (define_expand "floatunsdidf2"
5424 [(use (match_operand:DF 0 "register_operand" ""))
5425 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5426 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5427 && TARGET_SSE2 && TARGET_SSE_MATH"
5428 {
5429 if (TARGET_64BIT)
5430 x86_emit_floatuns (operands);
5431 else
5432 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5433 DONE;
5434 })
5435 \f
5436 ;; Add instructions
5437
5438 (define_expand "add<mode>3"
5439 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5440 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5441 (match_operand:SDWIM 2 "<general_operand>" "")))]
5442 ""
5443 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5444
5445 (define_insn_and_split "*add<dwi>3_doubleword"
5446 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5447 (plus:<DWI>
5448 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5449 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5450 (clobber (reg:CC FLAGS_REG))]
5451 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5452 "#"
5453 "reload_completed"
5454 [(parallel [(set (reg:CC FLAGS_REG)
5455 (unspec:CC [(match_dup 1) (match_dup 2)]
5456 UNSPEC_ADD_CARRY))
5457 (set (match_dup 0)
5458 (plus:DWIH (match_dup 1) (match_dup 2)))])
5459 (parallel [(set (match_dup 3)
5460 (plus:DWIH
5461 (match_dup 4)
5462 (plus:DWIH
5463 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5464 (match_dup 5))))
5465 (clobber (reg:CC FLAGS_REG))])]
5466 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5467
5468 (define_insn "*add<mode>3_cc"
5469 [(set (reg:CC FLAGS_REG)
5470 (unspec:CC
5471 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5472 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5473 UNSPEC_ADD_CARRY))
5474 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5475 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5476 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5477 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5478 [(set_attr "type" "alu")
5479 (set_attr "mode" "<MODE>")])
5480
5481 (define_insn "addqi3_cc"
5482 [(set (reg:CC FLAGS_REG)
5483 (unspec:CC
5484 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5485 (match_operand:QI 2 "general_operand" "qn,qm")]
5486 UNSPEC_ADD_CARRY))
5487 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5488 (plus:QI (match_dup 1) (match_dup 2)))]
5489 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5490 "add{b}\t{%2, %0|%0, %2}"
5491 [(set_attr "type" "alu")
5492 (set_attr "mode" "QI")])
5493
5494 (define_insn_and_split "*lea_1"
5495 [(set (match_operand:SI 0 "register_operand" "=r")
5496 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5497 "TARGET_64BIT"
5498 "lea{l}\t{%a1, %0|%0, %a1}"
5499 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5500 [(const_int 0)]
5501 {
5502 ix86_split_lea_for_addr (operands, SImode);
5503 DONE;
5504 }
5505 [(set_attr "type" "lea")
5506 (set_attr "mode" "SI")])
5507
5508 (define_insn_and_split "*lea<mode>_2"
5509 [(set (match_operand:SWI48 0 "register_operand" "=r")
5510 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5511 ""
5512 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5513 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5514 [(const_int 0)]
5515 {
5516 ix86_split_lea_for_addr (operands, <MODE>mode);
5517 DONE;
5518 }
5519 [(set_attr "type" "lea")
5520 (set_attr "mode" "<MODE>")])
5521
5522 (define_insn "*lea_3_zext"
5523 [(set (match_operand:DI 0 "register_operand" "=r")
5524 (zero_extend:DI
5525 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
5526 "TARGET_64BIT"
5527 "lea{l}\t{%a1, %k0|%k0, %a1}"
5528 [(set_attr "type" "lea")
5529 (set_attr "mode" "SI")])
5530
5531 (define_insn "*lea_4_zext"
5532 [(set (match_operand:DI 0 "register_operand" "=r")
5533 (zero_extend:DI
5534 (match_operand:SI 1 "lea_address_operand" "p")))]
5535 "TARGET_64BIT"
5536 "lea{l}\t{%a1, %k0|%k0, %a1}"
5537 [(set_attr "type" "lea")
5538 (set_attr "mode" "SI")])
5539
5540 (define_insn "*lea_5_zext"
5541 [(set (match_operand:DI 0 "register_operand" "=r")
5542 (and:DI
5543 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5544 (match_operand:DI 2 "const_32bit_mask" "n")))]
5545 "TARGET_64BIT"
5546 "lea{l}\t{%a1, %k0|%k0, %a1}"
5547 [(set_attr "type" "lea")
5548 (set_attr "mode" "SI")])
5549
5550 (define_insn "*lea_6_zext"
5551 [(set (match_operand:DI 0 "register_operand" "=r")
5552 (and:DI
5553 (match_operand:DI 1 "lea_address_operand" "p")
5554 (match_operand:DI 2 "const_32bit_mask" "n")))]
5555 "TARGET_64BIT"
5556 "lea{l}\t{%a1, %k0|%k0, %a1}"
5557 [(set_attr "type" "lea")
5558 (set_attr "mode" "SI")])
5559
5560 (define_insn "*add<mode>_1"
5561 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5562 (plus:SWI48
5563 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5564 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5565 (clobber (reg:CC FLAGS_REG))]
5566 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5567 {
5568 switch (get_attr_type (insn))
5569 {
5570 case TYPE_LEA:
5571 return "#";
5572
5573 case TYPE_INCDEC:
5574 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5575 if (operands[2] == const1_rtx)
5576 return "inc{<imodesuffix>}\t%0";
5577 else
5578 {
5579 gcc_assert (operands[2] == constm1_rtx);
5580 return "dec{<imodesuffix>}\t%0";
5581 }
5582
5583 default:
5584 /* For most processors, ADD is faster than LEA. This alternative
5585 was added to use ADD as much as possible. */
5586 if (which_alternative == 2)
5587 {
5588 rtx tmp;
5589 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5590 }
5591
5592 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5593 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5594 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5595
5596 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5597 }
5598 }
5599 [(set (attr "type")
5600 (cond [(eq_attr "alternative" "3")
5601 (const_string "lea")
5602 (match_operand:SWI48 2 "incdec_operand" "")
5603 (const_string "incdec")
5604 ]
5605 (const_string "alu")))
5606 (set (attr "length_immediate")
5607 (if_then_else
5608 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5609 (const_string "1")
5610 (const_string "*")))
5611 (set_attr "mode" "<MODE>")])
5612
5613 ;; It may seem that nonimmediate operand is proper one for operand 1.
5614 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5615 ;; we take care in ix86_binary_operator_ok to not allow two memory
5616 ;; operands so proper swapping will be done in reload. This allow
5617 ;; patterns constructed from addsi_1 to match.
5618
5619 (define_insn "addsi_1_zext"
5620 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5621 (zero_extend:DI
5622 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5623 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5624 (clobber (reg:CC FLAGS_REG))]
5625 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5626 {
5627 switch (get_attr_type (insn))
5628 {
5629 case TYPE_LEA:
5630 return "#";
5631
5632 case TYPE_INCDEC:
5633 if (operands[2] == const1_rtx)
5634 return "inc{l}\t%k0";
5635 else
5636 {
5637 gcc_assert (operands[2] == constm1_rtx);
5638 return "dec{l}\t%k0";
5639 }
5640
5641 default:
5642 /* For most processors, ADD is faster than LEA. This alternative
5643 was added to use ADD as much as possible. */
5644 if (which_alternative == 1)
5645 {
5646 rtx tmp;
5647 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5648 }
5649
5650 if (x86_maybe_negate_const_int (&operands[2], SImode))
5651 return "sub{l}\t{%2, %k0|%k0, %2}";
5652
5653 return "add{l}\t{%2, %k0|%k0, %2}";
5654 }
5655 }
5656 [(set (attr "type")
5657 (cond [(eq_attr "alternative" "2")
5658 (const_string "lea")
5659 (match_operand:SI 2 "incdec_operand" "")
5660 (const_string "incdec")
5661 ]
5662 (const_string "alu")))
5663 (set (attr "length_immediate")
5664 (if_then_else
5665 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5666 (const_string "1")
5667 (const_string "*")))
5668 (set_attr "mode" "SI")])
5669
5670 (define_insn "*addhi_1"
5671 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5672 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5673 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5674 (clobber (reg:CC FLAGS_REG))]
5675 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5676 {
5677 switch (get_attr_type (insn))
5678 {
5679 case TYPE_LEA:
5680 return "#";
5681
5682 case TYPE_INCDEC:
5683 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5684 if (operands[2] == const1_rtx)
5685 return "inc{w}\t%0";
5686 else
5687 {
5688 gcc_assert (operands[2] == constm1_rtx);
5689 return "dec{w}\t%0";
5690 }
5691
5692 default:
5693 /* For most processors, ADD is faster than LEA. This alternative
5694 was added to use ADD as much as possible. */
5695 if (which_alternative == 2)
5696 {
5697 rtx tmp;
5698 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5699 }
5700
5701 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5702 if (x86_maybe_negate_const_int (&operands[2], HImode))
5703 return "sub{w}\t{%2, %0|%0, %2}";
5704
5705 return "add{w}\t{%2, %0|%0, %2}";
5706 }
5707 }
5708 [(set (attr "type")
5709 (cond [(eq_attr "alternative" "3")
5710 (const_string "lea")
5711 (match_operand:HI 2 "incdec_operand" "")
5712 (const_string "incdec")
5713 ]
5714 (const_string "alu")))
5715 (set (attr "length_immediate")
5716 (if_then_else
5717 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5718 (const_string "1")
5719 (const_string "*")))
5720 (set_attr "mode" "HI,HI,HI,SI")])
5721
5722 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5723 (define_insn "*addqi_1"
5724 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5725 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5726 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5727 (clobber (reg:CC FLAGS_REG))]
5728 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5729 {
5730 bool widen = (which_alternative == 3 || which_alternative == 4);
5731
5732 switch (get_attr_type (insn))
5733 {
5734 case TYPE_LEA:
5735 return "#";
5736
5737 case TYPE_INCDEC:
5738 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5739 if (operands[2] == const1_rtx)
5740 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5741 else
5742 {
5743 gcc_assert (operands[2] == constm1_rtx);
5744 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5745 }
5746
5747 default:
5748 /* For most processors, ADD is faster than LEA. These alternatives
5749 were added to use ADD as much as possible. */
5750 if (which_alternative == 2 || which_alternative == 4)
5751 {
5752 rtx tmp;
5753 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5754 }
5755
5756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5757 if (x86_maybe_negate_const_int (&operands[2], QImode))
5758 {
5759 if (widen)
5760 return "sub{l}\t{%2, %k0|%k0, %2}";
5761 else
5762 return "sub{b}\t{%2, %0|%0, %2}";
5763 }
5764 if (widen)
5765 return "add{l}\t{%k2, %k0|%k0, %k2}";
5766 else
5767 return "add{b}\t{%2, %0|%0, %2}";
5768 }
5769 }
5770 [(set (attr "type")
5771 (cond [(eq_attr "alternative" "5")
5772 (const_string "lea")
5773 (match_operand:QI 2 "incdec_operand" "")
5774 (const_string "incdec")
5775 ]
5776 (const_string "alu")))
5777 (set (attr "length_immediate")
5778 (if_then_else
5779 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5780 (const_string "1")
5781 (const_string "*")))
5782 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5783
5784 (define_insn "*addqi_1_slp"
5785 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5786 (plus:QI (match_dup 0)
5787 (match_operand:QI 1 "general_operand" "qn,qm")))
5788 (clobber (reg:CC FLAGS_REG))]
5789 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5790 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5791 {
5792 switch (get_attr_type (insn))
5793 {
5794 case TYPE_INCDEC:
5795 if (operands[1] == const1_rtx)
5796 return "inc{b}\t%0";
5797 else
5798 {
5799 gcc_assert (operands[1] == constm1_rtx);
5800 return "dec{b}\t%0";
5801 }
5802
5803 default:
5804 if (x86_maybe_negate_const_int (&operands[1], QImode))
5805 return "sub{b}\t{%1, %0|%0, %1}";
5806
5807 return "add{b}\t{%1, %0|%0, %1}";
5808 }
5809 }
5810 [(set (attr "type")
5811 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5812 (const_string "incdec")
5813 (const_string "alu1")))
5814 (set (attr "memory")
5815 (if_then_else (match_operand 1 "memory_operand" "")
5816 (const_string "load")
5817 (const_string "none")))
5818 (set_attr "mode" "QI")])
5819
5820 ;; Split non destructive adds if we cannot use lea.
5821 (define_split
5822 [(set (match_operand:SWI48 0 "register_operand" "")
5823 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5824 (match_operand:SWI48 2 "nonmemory_operand" "")))
5825 (clobber (reg:CC FLAGS_REG))]
5826 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5827 [(set (match_dup 0) (match_dup 1))
5828 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5829 (clobber (reg:CC FLAGS_REG))])])
5830
5831 ;; Convert add to the lea pattern to avoid flags dependency.
5832 (define_split
5833 [(set (match_operand:SWI 0 "register_operand" "")
5834 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5835 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5836 (clobber (reg:CC FLAGS_REG))]
5837 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5838 [(const_int 0)]
5839 {
5840 enum machine_mode mode = <MODE>mode;
5841 rtx pat;
5842
5843 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5844 {
5845 mode = SImode;
5846 operands[0] = gen_lowpart (mode, operands[0]);
5847 operands[1] = gen_lowpart (mode, operands[1]);
5848 operands[2] = gen_lowpart (mode, operands[2]);
5849 }
5850
5851 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5852
5853 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5854 DONE;
5855 })
5856
5857 ;; Convert add to the lea pattern to avoid flags dependency.
5858 (define_split
5859 [(set (match_operand:DI 0 "register_operand" "")
5860 (zero_extend:DI
5861 (plus:SI (match_operand:SI 1 "register_operand" "")
5862 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5863 (clobber (reg:CC FLAGS_REG))]
5864 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5865 [(set (match_dup 0)
5866 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5867
5868 (define_insn "*add<mode>_2"
5869 [(set (reg FLAGS_REG)
5870 (compare
5871 (plus:SWI
5872 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5873 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5874 (const_int 0)))
5875 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5876 (plus:SWI (match_dup 1) (match_dup 2)))]
5877 "ix86_match_ccmode (insn, CCGOCmode)
5878 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5879 {
5880 switch (get_attr_type (insn))
5881 {
5882 case TYPE_INCDEC:
5883 if (operands[2] == const1_rtx)
5884 return "inc{<imodesuffix>}\t%0";
5885 else
5886 {
5887 gcc_assert (operands[2] == constm1_rtx);
5888 return "dec{<imodesuffix>}\t%0";
5889 }
5890
5891 default:
5892 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5893 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5894
5895 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5896 }
5897 }
5898 [(set (attr "type")
5899 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5900 (const_string "incdec")
5901 (const_string "alu")))
5902 (set (attr "length_immediate")
5903 (if_then_else
5904 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5905 (const_string "1")
5906 (const_string "*")))
5907 (set_attr "mode" "<MODE>")])
5908
5909 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5910 (define_insn "*addsi_2_zext"
5911 [(set (reg FLAGS_REG)
5912 (compare
5913 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5914 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5915 (const_int 0)))
5916 (set (match_operand:DI 0 "register_operand" "=r")
5917 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5918 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5919 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5920 {
5921 switch (get_attr_type (insn))
5922 {
5923 case TYPE_INCDEC:
5924 if (operands[2] == const1_rtx)
5925 return "inc{l}\t%k0";
5926 else
5927 {
5928 gcc_assert (operands[2] == constm1_rtx);
5929 return "dec{l}\t%k0";
5930 }
5931
5932 default:
5933 if (x86_maybe_negate_const_int (&operands[2], SImode))
5934 return "sub{l}\t{%2, %k0|%k0, %2}";
5935
5936 return "add{l}\t{%2, %k0|%k0, %2}";
5937 }
5938 }
5939 [(set (attr "type")
5940 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5941 (const_string "incdec")
5942 (const_string "alu")))
5943 (set (attr "length_immediate")
5944 (if_then_else
5945 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5946 (const_string "1")
5947 (const_string "*")))
5948 (set_attr "mode" "SI")])
5949
5950 (define_insn "*add<mode>_3"
5951 [(set (reg FLAGS_REG)
5952 (compare
5953 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5954 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5955 (clobber (match_scratch:SWI 0 "=<r>"))]
5956 "ix86_match_ccmode (insn, CCZmode)
5957 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5958 {
5959 switch (get_attr_type (insn))
5960 {
5961 case TYPE_INCDEC:
5962 if (operands[2] == const1_rtx)
5963 return "inc{<imodesuffix>}\t%0";
5964 else
5965 {
5966 gcc_assert (operands[2] == constm1_rtx);
5967 return "dec{<imodesuffix>}\t%0";
5968 }
5969
5970 default:
5971 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5972 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5973
5974 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5975 }
5976 }
5977 [(set (attr "type")
5978 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5979 (const_string "incdec")
5980 (const_string "alu")))
5981 (set (attr "length_immediate")
5982 (if_then_else
5983 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5984 (const_string "1")
5985 (const_string "*")))
5986 (set_attr "mode" "<MODE>")])
5987
5988 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5989 (define_insn "*addsi_3_zext"
5990 [(set (reg FLAGS_REG)
5991 (compare
5992 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5993 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5994 (set (match_operand:DI 0 "register_operand" "=r")
5995 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5996 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5997 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5998 {
5999 switch (get_attr_type (insn))
6000 {
6001 case TYPE_INCDEC:
6002 if (operands[2] == const1_rtx)
6003 return "inc{l}\t%k0";
6004 else
6005 {
6006 gcc_assert (operands[2] == constm1_rtx);
6007 return "dec{l}\t%k0";
6008 }
6009
6010 default:
6011 if (x86_maybe_negate_const_int (&operands[2], SImode))
6012 return "sub{l}\t{%2, %k0|%k0, %2}";
6013
6014 return "add{l}\t{%2, %k0|%k0, %2}";
6015 }
6016 }
6017 [(set (attr "type")
6018 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6019 (const_string "incdec")
6020 (const_string "alu")))
6021 (set (attr "length_immediate")
6022 (if_then_else
6023 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6024 (const_string "1")
6025 (const_string "*")))
6026 (set_attr "mode" "SI")])
6027
6028 ; For comparisons against 1, -1 and 128, we may generate better code
6029 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6030 ; is matched then. We can't accept general immediate, because for
6031 ; case of overflows, the result is messed up.
6032 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6033 ; only for comparisons not depending on it.
6034
6035 (define_insn "*adddi_4"
6036 [(set (reg FLAGS_REG)
6037 (compare
6038 (match_operand:DI 1 "nonimmediate_operand" "0")
6039 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6040 (clobber (match_scratch:DI 0 "=rm"))]
6041 "TARGET_64BIT
6042 && ix86_match_ccmode (insn, CCGCmode)"
6043 {
6044 switch (get_attr_type (insn))
6045 {
6046 case TYPE_INCDEC:
6047 if (operands[2] == constm1_rtx)
6048 return "inc{q}\t%0";
6049 else
6050 {
6051 gcc_assert (operands[2] == const1_rtx);
6052 return "dec{q}\t%0";
6053 }
6054
6055 default:
6056 if (x86_maybe_negate_const_int (&operands[2], DImode))
6057 return "add{q}\t{%2, %0|%0, %2}";
6058
6059 return "sub{q}\t{%2, %0|%0, %2}";
6060 }
6061 }
6062 [(set (attr "type")
6063 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6064 (const_string "incdec")
6065 (const_string "alu")))
6066 (set (attr "length_immediate")
6067 (if_then_else
6068 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6069 (const_string "1")
6070 (const_string "*")))
6071 (set_attr "mode" "DI")])
6072
6073 ; For comparisons against 1, -1 and 128, we may generate better code
6074 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6075 ; is matched then. We can't accept general immediate, because for
6076 ; case of overflows, the result is messed up.
6077 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6078 ; only for comparisons not depending on it.
6079
6080 (define_insn "*add<mode>_4"
6081 [(set (reg FLAGS_REG)
6082 (compare
6083 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6084 (match_operand:SWI124 2 "const_int_operand" "n")))
6085 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6086 "ix86_match_ccmode (insn, CCGCmode)"
6087 {
6088 switch (get_attr_type (insn))
6089 {
6090 case TYPE_INCDEC:
6091 if (operands[2] == constm1_rtx)
6092 return "inc{<imodesuffix>}\t%0";
6093 else
6094 {
6095 gcc_assert (operands[2] == const1_rtx);
6096 return "dec{<imodesuffix>}\t%0";
6097 }
6098
6099 default:
6100 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6101 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6102
6103 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6104 }
6105 }
6106 [(set (attr "type")
6107 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6108 (const_string "incdec")
6109 (const_string "alu")))
6110 (set (attr "length_immediate")
6111 (if_then_else
6112 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6113 (const_string "1")
6114 (const_string "*")))
6115 (set_attr "mode" "<MODE>")])
6116
6117 (define_insn "*add<mode>_5"
6118 [(set (reg FLAGS_REG)
6119 (compare
6120 (plus:SWI
6121 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6122 (match_operand:SWI 2 "<general_operand>" "<g>"))
6123 (const_int 0)))
6124 (clobber (match_scratch:SWI 0 "=<r>"))]
6125 "ix86_match_ccmode (insn, CCGOCmode)
6126 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6127 {
6128 switch (get_attr_type (insn))
6129 {
6130 case TYPE_INCDEC:
6131 if (operands[2] == const1_rtx)
6132 return "inc{<imodesuffix>}\t%0";
6133 else
6134 {
6135 gcc_assert (operands[2] == constm1_rtx);
6136 return "dec{<imodesuffix>}\t%0";
6137 }
6138
6139 default:
6140 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6141 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6142
6143 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6144 }
6145 }
6146 [(set (attr "type")
6147 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6148 (const_string "incdec")
6149 (const_string "alu")))
6150 (set (attr "length_immediate")
6151 (if_then_else
6152 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6153 (const_string "1")
6154 (const_string "*")))
6155 (set_attr "mode" "<MODE>")])
6156
6157 (define_insn "*addqi_ext_1_rex64"
6158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6159 (const_int 8)
6160 (const_int 8))
6161 (plus:SI
6162 (zero_extract:SI
6163 (match_operand 1 "ext_register_operand" "0")
6164 (const_int 8)
6165 (const_int 8))
6166 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6167 (clobber (reg:CC FLAGS_REG))]
6168 "TARGET_64BIT"
6169 {
6170 switch (get_attr_type (insn))
6171 {
6172 case TYPE_INCDEC:
6173 if (operands[2] == const1_rtx)
6174 return "inc{b}\t%h0";
6175 else
6176 {
6177 gcc_assert (operands[2] == constm1_rtx);
6178 return "dec{b}\t%h0";
6179 }
6180
6181 default:
6182 return "add{b}\t{%2, %h0|%h0, %2}";
6183 }
6184 }
6185 [(set (attr "type")
6186 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6187 (const_string "incdec")
6188 (const_string "alu")))
6189 (set_attr "modrm" "1")
6190 (set_attr "mode" "QI")])
6191
6192 (define_insn "addqi_ext_1"
6193 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6194 (const_int 8)
6195 (const_int 8))
6196 (plus:SI
6197 (zero_extract:SI
6198 (match_operand 1 "ext_register_operand" "0")
6199 (const_int 8)
6200 (const_int 8))
6201 (match_operand:QI 2 "general_operand" "Qmn")))
6202 (clobber (reg:CC FLAGS_REG))]
6203 "!TARGET_64BIT"
6204 {
6205 switch (get_attr_type (insn))
6206 {
6207 case TYPE_INCDEC:
6208 if (operands[2] == const1_rtx)
6209 return "inc{b}\t%h0";
6210 else
6211 {
6212 gcc_assert (operands[2] == constm1_rtx);
6213 return "dec{b}\t%h0";
6214 }
6215
6216 default:
6217 return "add{b}\t{%2, %h0|%h0, %2}";
6218 }
6219 }
6220 [(set (attr "type")
6221 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6222 (const_string "incdec")
6223 (const_string "alu")))
6224 (set_attr "modrm" "1")
6225 (set_attr "mode" "QI")])
6226
6227 (define_insn "*addqi_ext_2"
6228 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6229 (const_int 8)
6230 (const_int 8))
6231 (plus:SI
6232 (zero_extract:SI
6233 (match_operand 1 "ext_register_operand" "%0")
6234 (const_int 8)
6235 (const_int 8))
6236 (zero_extract:SI
6237 (match_operand 2 "ext_register_operand" "Q")
6238 (const_int 8)
6239 (const_int 8))))
6240 (clobber (reg:CC FLAGS_REG))]
6241 ""
6242 "add{b}\t{%h2, %h0|%h0, %h2}"
6243 [(set_attr "type" "alu")
6244 (set_attr "mode" "QI")])
6245
6246 ;; The lea patterns for modes less than 32 bits need to be matched by
6247 ;; several insns converted to real lea by splitters.
6248
6249 (define_insn_and_split "*lea_general_1"
6250 [(set (match_operand 0 "register_operand" "=r")
6251 (plus (plus (match_operand 1 "index_register_operand" "l")
6252 (match_operand 2 "register_operand" "r"))
6253 (match_operand 3 "immediate_operand" "i")))]
6254 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6255 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6256 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6257 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6258 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6259 || GET_MODE (operands[3]) == VOIDmode)"
6260 "#"
6261 "&& reload_completed"
6262 [(const_int 0)]
6263 {
6264 enum machine_mode mode = SImode;
6265 rtx pat;
6266
6267 operands[0] = gen_lowpart (mode, operands[0]);
6268 operands[1] = gen_lowpart (mode, operands[1]);
6269 operands[2] = gen_lowpart (mode, operands[2]);
6270 operands[3] = gen_lowpart (mode, operands[3]);
6271
6272 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6273 operands[3]);
6274
6275 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6276 DONE;
6277 }
6278 [(set_attr "type" "lea")
6279 (set_attr "mode" "SI")])
6280
6281 (define_insn_and_split "*lea_general_2"
6282 [(set (match_operand 0 "register_operand" "=r")
6283 (plus (mult (match_operand 1 "index_register_operand" "l")
6284 (match_operand 2 "const248_operand" "n"))
6285 (match_operand 3 "nonmemory_operand" "ri")))]
6286 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6287 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6288 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6289 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6290 || GET_MODE (operands[3]) == VOIDmode)"
6291 "#"
6292 "&& reload_completed"
6293 [(const_int 0)]
6294 {
6295 enum machine_mode mode = SImode;
6296 rtx pat;
6297
6298 operands[0] = gen_lowpart (mode, operands[0]);
6299 operands[1] = gen_lowpart (mode, operands[1]);
6300 operands[3] = gen_lowpart (mode, operands[3]);
6301
6302 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6303 operands[3]);
6304
6305 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6306 DONE;
6307 }
6308 [(set_attr "type" "lea")
6309 (set_attr "mode" "SI")])
6310
6311 (define_insn_and_split "*lea_general_3"
6312 [(set (match_operand 0 "register_operand" "=r")
6313 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6314 (match_operand 2 "const248_operand" "n"))
6315 (match_operand 3 "register_operand" "r"))
6316 (match_operand 4 "immediate_operand" "i")))]
6317 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6318 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6319 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6320 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6321 "#"
6322 "&& reload_completed"
6323 [(const_int 0)]
6324 {
6325 enum machine_mode mode = SImode;
6326 rtx pat;
6327
6328 operands[0] = gen_lowpart (mode, operands[0]);
6329 operands[1] = gen_lowpart (mode, operands[1]);
6330 operands[3] = gen_lowpart (mode, operands[3]);
6331 operands[4] = gen_lowpart (mode, operands[4]);
6332
6333 pat = gen_rtx_PLUS (mode,
6334 gen_rtx_PLUS (mode,
6335 gen_rtx_MULT (mode, operands[1],
6336 operands[2]),
6337 operands[3]),
6338 operands[4]);
6339
6340 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6341 DONE;
6342 }
6343 [(set_attr "type" "lea")
6344 (set_attr "mode" "SI")])
6345
6346 (define_insn_and_split "*lea_general_4"
6347 [(set (match_operand 0 "register_operand" "=r")
6348 (any_or (ashift
6349 (match_operand 1 "index_register_operand" "l")
6350 (match_operand 2 "const_int_operand" "n"))
6351 (match_operand 3 "const_int_operand" "n")))]
6352 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6353 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6354 || GET_MODE (operands[0]) == SImode
6355 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6356 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6357 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6358 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6359 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6360 "#"
6361 "&& reload_completed"
6362 [(const_int 0)]
6363 {
6364 enum machine_mode mode = GET_MODE (operands[0]);
6365 rtx pat;
6366
6367 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6368 {
6369 mode = SImode;
6370 operands[0] = gen_lowpart (mode, operands[0]);
6371 operands[1] = gen_lowpart (mode, operands[1]);
6372 }
6373
6374 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6375
6376 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6377 INTVAL (operands[3]));
6378
6379 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6380 DONE;
6381 }
6382 [(set_attr "type" "lea")
6383 (set (attr "mode")
6384 (if_then_else (match_operand:DI 0 "" "")
6385 (const_string "DI")
6386 (const_string "SI")))])
6387 \f
6388 ;; Subtract instructions
6389
6390 (define_expand "sub<mode>3"
6391 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6392 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6393 (match_operand:SDWIM 2 "<general_operand>" "")))]
6394 ""
6395 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6396
6397 (define_insn_and_split "*sub<dwi>3_doubleword"
6398 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6399 (minus:<DWI>
6400 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6401 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6402 (clobber (reg:CC FLAGS_REG))]
6403 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6404 "#"
6405 "reload_completed"
6406 [(parallel [(set (reg:CC FLAGS_REG)
6407 (compare:CC (match_dup 1) (match_dup 2)))
6408 (set (match_dup 0)
6409 (minus:DWIH (match_dup 1) (match_dup 2)))])
6410 (parallel [(set (match_dup 3)
6411 (minus:DWIH
6412 (match_dup 4)
6413 (plus:DWIH
6414 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6415 (match_dup 5))))
6416 (clobber (reg:CC FLAGS_REG))])]
6417 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6418
6419 (define_insn "*sub<mode>_1"
6420 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6421 (minus:SWI
6422 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6423 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6424 (clobber (reg:CC FLAGS_REG))]
6425 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6426 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6427 [(set_attr "type" "alu")
6428 (set_attr "mode" "<MODE>")])
6429
6430 (define_insn "*subsi_1_zext"
6431 [(set (match_operand:DI 0 "register_operand" "=r")
6432 (zero_extend:DI
6433 (minus:SI (match_operand:SI 1 "register_operand" "0")
6434 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6435 (clobber (reg:CC FLAGS_REG))]
6436 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6437 "sub{l}\t{%2, %k0|%k0, %2}"
6438 [(set_attr "type" "alu")
6439 (set_attr "mode" "SI")])
6440
6441 (define_insn "*subqi_1_slp"
6442 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6443 (minus:QI (match_dup 0)
6444 (match_operand:QI 1 "general_operand" "qn,qm")))
6445 (clobber (reg:CC FLAGS_REG))]
6446 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6447 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6448 "sub{b}\t{%1, %0|%0, %1}"
6449 [(set_attr "type" "alu1")
6450 (set_attr "mode" "QI")])
6451
6452 (define_insn "*sub<mode>_2"
6453 [(set (reg FLAGS_REG)
6454 (compare
6455 (minus:SWI
6456 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6457 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6458 (const_int 0)))
6459 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6460 (minus:SWI (match_dup 1) (match_dup 2)))]
6461 "ix86_match_ccmode (insn, CCGOCmode)
6462 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6463 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6464 [(set_attr "type" "alu")
6465 (set_attr "mode" "<MODE>")])
6466
6467 (define_insn "*subsi_2_zext"
6468 [(set (reg FLAGS_REG)
6469 (compare
6470 (minus:SI (match_operand:SI 1 "register_operand" "0")
6471 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6472 (const_int 0)))
6473 (set (match_operand:DI 0 "register_operand" "=r")
6474 (zero_extend:DI
6475 (minus:SI (match_dup 1)
6476 (match_dup 2))))]
6477 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6478 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6479 "sub{l}\t{%2, %k0|%k0, %2}"
6480 [(set_attr "type" "alu")
6481 (set_attr "mode" "SI")])
6482
6483 (define_insn "*sub<mode>_3"
6484 [(set (reg FLAGS_REG)
6485 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6486 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6487 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6488 (minus:SWI (match_dup 1) (match_dup 2)))]
6489 "ix86_match_ccmode (insn, CCmode)
6490 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6491 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6492 [(set_attr "type" "alu")
6493 (set_attr "mode" "<MODE>")])
6494
6495 (define_insn "*subsi_3_zext"
6496 [(set (reg FLAGS_REG)
6497 (compare (match_operand:SI 1 "register_operand" "0")
6498 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6499 (set (match_operand:DI 0 "register_operand" "=r")
6500 (zero_extend:DI
6501 (minus:SI (match_dup 1)
6502 (match_dup 2))))]
6503 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6504 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6505 "sub{l}\t{%2, %1|%1, %2}"
6506 [(set_attr "type" "alu")
6507 (set_attr "mode" "SI")])
6508 \f
6509 ;; Add with carry and subtract with borrow
6510
6511 (define_expand "<plusminus_insn><mode>3_carry"
6512 [(parallel
6513 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6514 (plusminus:SWI
6515 (match_operand:SWI 1 "nonimmediate_operand" "")
6516 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6517 [(match_operand 3 "flags_reg_operand" "")
6518 (const_int 0)])
6519 (match_operand:SWI 2 "<general_operand>" ""))))
6520 (clobber (reg:CC FLAGS_REG))])]
6521 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6522
6523 (define_insn "*<plusminus_insn><mode>3_carry"
6524 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6525 (plusminus:SWI
6526 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6527 (plus:SWI
6528 (match_operator 3 "ix86_carry_flag_operator"
6529 [(reg FLAGS_REG) (const_int 0)])
6530 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6531 (clobber (reg:CC FLAGS_REG))]
6532 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6533 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6534 [(set_attr "type" "alu")
6535 (set_attr "use_carry" "1")
6536 (set_attr "pent_pair" "pu")
6537 (set_attr "mode" "<MODE>")])
6538
6539 (define_insn "*addsi3_carry_zext"
6540 [(set (match_operand:DI 0 "register_operand" "=r")
6541 (zero_extend:DI
6542 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6543 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6544 [(reg FLAGS_REG) (const_int 0)])
6545 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6546 (clobber (reg:CC FLAGS_REG))]
6547 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6548 "adc{l}\t{%2, %k0|%k0, %2}"
6549 [(set_attr "type" "alu")
6550 (set_attr "use_carry" "1")
6551 (set_attr "pent_pair" "pu")
6552 (set_attr "mode" "SI")])
6553
6554 (define_insn "*subsi3_carry_zext"
6555 [(set (match_operand:DI 0 "register_operand" "=r")
6556 (zero_extend:DI
6557 (minus:SI (match_operand:SI 1 "register_operand" "0")
6558 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6559 [(reg FLAGS_REG) (const_int 0)])
6560 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6561 (clobber (reg:CC FLAGS_REG))]
6562 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6563 "sbb{l}\t{%2, %k0|%k0, %2}"
6564 [(set_attr "type" "alu")
6565 (set_attr "pent_pair" "pu")
6566 (set_attr "mode" "SI")])
6567 \f
6568 ;; Overflow setting add and subtract instructions
6569
6570 (define_insn "*add<mode>3_cconly_overflow"
6571 [(set (reg:CCC FLAGS_REG)
6572 (compare:CCC
6573 (plus:SWI
6574 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6575 (match_operand:SWI 2 "<general_operand>" "<g>"))
6576 (match_dup 1)))
6577 (clobber (match_scratch:SWI 0 "=<r>"))]
6578 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6579 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6580 [(set_attr "type" "alu")
6581 (set_attr "mode" "<MODE>")])
6582
6583 (define_insn "*sub<mode>3_cconly_overflow"
6584 [(set (reg:CCC FLAGS_REG)
6585 (compare:CCC
6586 (minus:SWI
6587 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6588 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6589 (match_dup 0)))]
6590 ""
6591 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6592 [(set_attr "type" "icmp")
6593 (set_attr "mode" "<MODE>")])
6594
6595 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6596 [(set (reg:CCC FLAGS_REG)
6597 (compare:CCC
6598 (plusminus:SWI
6599 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6600 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6601 (match_dup 1)))
6602 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6603 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6604 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6605 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6606 [(set_attr "type" "alu")
6607 (set_attr "mode" "<MODE>")])
6608
6609 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6610 [(set (reg:CCC FLAGS_REG)
6611 (compare:CCC
6612 (plusminus:SI
6613 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6614 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6615 (match_dup 1)))
6616 (set (match_operand:DI 0 "register_operand" "=r")
6617 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6618 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6619 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6620 [(set_attr "type" "alu")
6621 (set_attr "mode" "SI")])
6622
6623 ;; The patterns that match these are at the end of this file.
6624
6625 (define_expand "<plusminus_insn>xf3"
6626 [(set (match_operand:XF 0 "register_operand" "")
6627 (plusminus:XF
6628 (match_operand:XF 1 "register_operand" "")
6629 (match_operand:XF 2 "register_operand" "")))]
6630 "TARGET_80387")
6631
6632 (define_expand "<plusminus_insn><mode>3"
6633 [(set (match_operand:MODEF 0 "register_operand" "")
6634 (plusminus:MODEF
6635 (match_operand:MODEF 1 "register_operand" "")
6636 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6637 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6638 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6639 \f
6640 ;; Multiply instructions
6641
6642 (define_expand "mul<mode>3"
6643 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6644 (mult:SWIM248
6645 (match_operand:SWIM248 1 "register_operand" "")
6646 (match_operand:SWIM248 2 "<general_operand>" "")))
6647 (clobber (reg:CC FLAGS_REG))])])
6648
6649 (define_expand "mulqi3"
6650 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6651 (mult:QI
6652 (match_operand:QI 1 "register_operand" "")
6653 (match_operand:QI 2 "nonimmediate_operand" "")))
6654 (clobber (reg:CC FLAGS_REG))])]
6655 "TARGET_QIMODE_MATH")
6656
6657 ;; On AMDFAM10
6658 ;; IMUL reg32/64, reg32/64, imm8 Direct
6659 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6660 ;; IMUL reg32/64, reg32/64, imm32 Direct
6661 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6662 ;; IMUL reg32/64, reg32/64 Direct
6663 ;; IMUL reg32/64, mem32/64 Direct
6664 ;;
6665 ;; On BDVER1, all above IMULs use DirectPath
6666
6667 (define_insn "*mul<mode>3_1"
6668 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6669 (mult:SWI48
6670 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6671 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6672 (clobber (reg:CC FLAGS_REG))]
6673 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6674 "@
6675 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6676 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6677 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6678 [(set_attr "type" "imul")
6679 (set_attr "prefix_0f" "0,0,1")
6680 (set (attr "athlon_decode")
6681 (cond [(eq_attr "cpu" "athlon")
6682 (const_string "vector")
6683 (eq_attr "alternative" "1")
6684 (const_string "vector")
6685 (and (eq_attr "alternative" "2")
6686 (match_operand 1 "memory_operand" ""))
6687 (const_string "vector")]
6688 (const_string "direct")))
6689 (set (attr "amdfam10_decode")
6690 (cond [(and (eq_attr "alternative" "0,1")
6691 (match_operand 1 "memory_operand" ""))
6692 (const_string "vector")]
6693 (const_string "direct")))
6694 (set_attr "bdver1_decode" "direct")
6695 (set_attr "mode" "<MODE>")])
6696
6697 (define_insn "*mulsi3_1_zext"
6698 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6699 (zero_extend:DI
6700 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6701 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6702 (clobber (reg:CC FLAGS_REG))]
6703 "TARGET_64BIT
6704 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6705 "@
6706 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6707 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6708 imul{l}\t{%2, %k0|%k0, %2}"
6709 [(set_attr "type" "imul")
6710 (set_attr "prefix_0f" "0,0,1")
6711 (set (attr "athlon_decode")
6712 (cond [(eq_attr "cpu" "athlon")
6713 (const_string "vector")
6714 (eq_attr "alternative" "1")
6715 (const_string "vector")
6716 (and (eq_attr "alternative" "2")
6717 (match_operand 1 "memory_operand" ""))
6718 (const_string "vector")]
6719 (const_string "direct")))
6720 (set (attr "amdfam10_decode")
6721 (cond [(and (eq_attr "alternative" "0,1")
6722 (match_operand 1 "memory_operand" ""))
6723 (const_string "vector")]
6724 (const_string "direct")))
6725 (set_attr "bdver1_decode" "direct")
6726 (set_attr "mode" "SI")])
6727
6728 ;; On AMDFAM10
6729 ;; IMUL reg16, reg16, imm8 VectorPath
6730 ;; IMUL reg16, mem16, imm8 VectorPath
6731 ;; IMUL reg16, reg16, imm16 VectorPath
6732 ;; IMUL reg16, mem16, imm16 VectorPath
6733 ;; IMUL reg16, reg16 Direct
6734 ;; IMUL reg16, mem16 Direct
6735 ;;
6736 ;; On BDVER1, all HI MULs use DoublePath
6737
6738 (define_insn "*mulhi3_1"
6739 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6740 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6741 (match_operand:HI 2 "general_operand" "K,n,mr")))
6742 (clobber (reg:CC FLAGS_REG))]
6743 "TARGET_HIMODE_MATH
6744 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6745 "@
6746 imul{w}\t{%2, %1, %0|%0, %1, %2}
6747 imul{w}\t{%2, %1, %0|%0, %1, %2}
6748 imul{w}\t{%2, %0|%0, %2}"
6749 [(set_attr "type" "imul")
6750 (set_attr "prefix_0f" "0,0,1")
6751 (set (attr "athlon_decode")
6752 (cond [(eq_attr "cpu" "athlon")
6753 (const_string "vector")
6754 (eq_attr "alternative" "1,2")
6755 (const_string "vector")]
6756 (const_string "direct")))
6757 (set (attr "amdfam10_decode")
6758 (cond [(eq_attr "alternative" "0,1")
6759 (const_string "vector")]
6760 (const_string "direct")))
6761 (set_attr "bdver1_decode" "double")
6762 (set_attr "mode" "HI")])
6763
6764 ;;On AMDFAM10 and BDVER1
6765 ;; MUL reg8 Direct
6766 ;; MUL mem8 Direct
6767
6768 (define_insn "*mulqi3_1"
6769 [(set (match_operand:QI 0 "register_operand" "=a")
6770 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6771 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6772 (clobber (reg:CC FLAGS_REG))]
6773 "TARGET_QIMODE_MATH
6774 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6775 "mul{b}\t%2"
6776 [(set_attr "type" "imul")
6777 (set_attr "length_immediate" "0")
6778 (set (attr "athlon_decode")
6779 (if_then_else (eq_attr "cpu" "athlon")
6780 (const_string "vector")
6781 (const_string "direct")))
6782 (set_attr "amdfam10_decode" "direct")
6783 (set_attr "bdver1_decode" "direct")
6784 (set_attr "mode" "QI")])
6785
6786 (define_expand "<u>mul<mode><dwi>3"
6787 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6788 (mult:<DWI>
6789 (any_extend:<DWI>
6790 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6791 (any_extend:<DWI>
6792 (match_operand:DWIH 2 "register_operand" ""))))
6793 (clobber (reg:CC FLAGS_REG))])])
6794
6795 (define_expand "<u>mulqihi3"
6796 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6797 (mult:HI
6798 (any_extend:HI
6799 (match_operand:QI 1 "nonimmediate_operand" ""))
6800 (any_extend:HI
6801 (match_operand:QI 2 "register_operand" ""))))
6802 (clobber (reg:CC FLAGS_REG))])]
6803 "TARGET_QIMODE_MATH")
6804
6805 (define_insn "*bmi2_umulditi3_1"
6806 [(set (match_operand:DI 0 "register_operand" "=r")
6807 (mult:DI
6808 (match_operand:DI 2 "nonimmediate_operand" "%d")
6809 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6810 (set (match_operand:DI 1 "register_operand" "=r")
6811 (truncate:DI
6812 (lshiftrt:TI
6813 (mult:TI (zero_extend:TI (match_dup 2))
6814 (zero_extend:TI (match_dup 3)))
6815 (const_int 64))))]
6816 "TARGET_64BIT && TARGET_BMI2
6817 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6818 "mulx\t{%3, %0, %1|%1, %0, %3}"
6819 [(set_attr "type" "imulx")
6820 (set_attr "prefix" "vex")
6821 (set_attr "mode" "DI")])
6822
6823 (define_insn "*bmi2_umulsidi3_1"
6824 [(set (match_operand:SI 0 "register_operand" "=r")
6825 (mult:SI
6826 (match_operand:SI 2 "nonimmediate_operand" "%d")
6827 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6828 (set (match_operand:SI 1 "register_operand" "=r")
6829 (truncate:SI
6830 (lshiftrt:DI
6831 (mult:DI (zero_extend:DI (match_dup 2))
6832 (zero_extend:DI (match_dup 3)))
6833 (const_int 32))))]
6834 "!TARGET_64BIT && TARGET_BMI2
6835 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6836 "mulx\t{%3, %0, %1|%1, %0, %3}"
6837 [(set_attr "type" "imulx")
6838 (set_attr "prefix" "vex")
6839 (set_attr "mode" "SI")])
6840
6841 (define_insn "*umul<mode><dwi>3_1"
6842 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6843 (mult:<DWI>
6844 (zero_extend:<DWI>
6845 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6846 (zero_extend:<DWI>
6847 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6848 (clobber (reg:CC FLAGS_REG))]
6849 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6850 "@
6851 mul{<imodesuffix>}\t%2
6852 #"
6853 [(set_attr "isa" "*,bmi2")
6854 (set_attr "type" "imul,imulx")
6855 (set_attr "length_immediate" "0,*")
6856 (set (attr "athlon_decode")
6857 (cond [(eq_attr "alternative" "0")
6858 (if_then_else (eq_attr "cpu" "athlon")
6859 (const_string "vector")
6860 (const_string "double"))]
6861 (const_string "*")))
6862 (set_attr "amdfam10_decode" "double,*")
6863 (set_attr "bdver1_decode" "direct,*")
6864 (set_attr "prefix" "orig,vex")
6865 (set_attr "mode" "<MODE>")])
6866
6867 ;; Convert mul to the mulx pattern to avoid flags dependency.
6868 (define_split
6869 [(set (match_operand:<DWI> 0 "register_operand" "")
6870 (mult:<DWI>
6871 (zero_extend:<DWI>
6872 (match_operand:DWIH 1 "register_operand" ""))
6873 (zero_extend:<DWI>
6874 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6875 (clobber (reg:CC FLAGS_REG))]
6876 "TARGET_BMI2 && reload_completed
6877 && true_regnum (operands[1]) == DX_REG"
6878 [(parallel [(set (match_dup 3)
6879 (mult:DWIH (match_dup 1) (match_dup 2)))
6880 (set (match_dup 4)
6881 (truncate:DWIH
6882 (lshiftrt:<DWI>
6883 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6884 (zero_extend:<DWI> (match_dup 2)))
6885 (match_dup 5))))])]
6886 {
6887 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6888
6889 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6890 })
6891
6892 (define_insn "*mul<mode><dwi>3_1"
6893 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6894 (mult:<DWI>
6895 (sign_extend:<DWI>
6896 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6897 (sign_extend:<DWI>
6898 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6899 (clobber (reg:CC FLAGS_REG))]
6900 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6901 "imul{<imodesuffix>}\t%2"
6902 [(set_attr "type" "imul")
6903 (set_attr "length_immediate" "0")
6904 (set (attr "athlon_decode")
6905 (if_then_else (eq_attr "cpu" "athlon")
6906 (const_string "vector")
6907 (const_string "double")))
6908 (set_attr "amdfam10_decode" "double")
6909 (set_attr "bdver1_decode" "direct")
6910 (set_attr "mode" "<MODE>")])
6911
6912 (define_insn "*<u>mulqihi3_1"
6913 [(set (match_operand:HI 0 "register_operand" "=a")
6914 (mult:HI
6915 (any_extend:HI
6916 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6917 (any_extend:HI
6918 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6919 (clobber (reg:CC FLAGS_REG))]
6920 "TARGET_QIMODE_MATH
6921 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6922 "<sgnprefix>mul{b}\t%2"
6923 [(set_attr "type" "imul")
6924 (set_attr "length_immediate" "0")
6925 (set (attr "athlon_decode")
6926 (if_then_else (eq_attr "cpu" "athlon")
6927 (const_string "vector")
6928 (const_string "direct")))
6929 (set_attr "amdfam10_decode" "direct")
6930 (set_attr "bdver1_decode" "direct")
6931 (set_attr "mode" "QI")])
6932
6933 (define_expand "<s>mul<mode>3_highpart"
6934 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6935 (truncate:SWI48
6936 (lshiftrt:<DWI>
6937 (mult:<DWI>
6938 (any_extend:<DWI>
6939 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6940 (any_extend:<DWI>
6941 (match_operand:SWI48 2 "register_operand" "")))
6942 (match_dup 4))))
6943 (clobber (match_scratch:SWI48 3 ""))
6944 (clobber (reg:CC FLAGS_REG))])]
6945 ""
6946 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6947
6948 (define_insn "*<s>muldi3_highpart_1"
6949 [(set (match_operand:DI 0 "register_operand" "=d")
6950 (truncate:DI
6951 (lshiftrt:TI
6952 (mult:TI
6953 (any_extend:TI
6954 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6955 (any_extend:TI
6956 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6957 (const_int 64))))
6958 (clobber (match_scratch:DI 3 "=1"))
6959 (clobber (reg:CC FLAGS_REG))]
6960 "TARGET_64BIT
6961 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6962 "<sgnprefix>mul{q}\t%2"
6963 [(set_attr "type" "imul")
6964 (set_attr "length_immediate" "0")
6965 (set (attr "athlon_decode")
6966 (if_then_else (eq_attr "cpu" "athlon")
6967 (const_string "vector")
6968 (const_string "double")))
6969 (set_attr "amdfam10_decode" "double")
6970 (set_attr "bdver1_decode" "direct")
6971 (set_attr "mode" "DI")])
6972
6973 (define_insn "*<s>mulsi3_highpart_1"
6974 [(set (match_operand:SI 0 "register_operand" "=d")
6975 (truncate:SI
6976 (lshiftrt:DI
6977 (mult:DI
6978 (any_extend:DI
6979 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6980 (any_extend:DI
6981 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6982 (const_int 32))))
6983 (clobber (match_scratch:SI 3 "=1"))
6984 (clobber (reg:CC FLAGS_REG))]
6985 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6986 "<sgnprefix>mul{l}\t%2"
6987 [(set_attr "type" "imul")
6988 (set_attr "length_immediate" "0")
6989 (set (attr "athlon_decode")
6990 (if_then_else (eq_attr "cpu" "athlon")
6991 (const_string "vector")
6992 (const_string "double")))
6993 (set_attr "amdfam10_decode" "double")
6994 (set_attr "bdver1_decode" "direct")
6995 (set_attr "mode" "SI")])
6996
6997 (define_insn "*<s>mulsi3_highpart_zext"
6998 [(set (match_operand:DI 0 "register_operand" "=d")
6999 (zero_extend:DI (truncate:SI
7000 (lshiftrt:DI
7001 (mult:DI (any_extend:DI
7002 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7003 (any_extend:DI
7004 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7005 (const_int 32)))))
7006 (clobber (match_scratch:SI 3 "=1"))
7007 (clobber (reg:CC FLAGS_REG))]
7008 "TARGET_64BIT
7009 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7010 "<sgnprefix>mul{l}\t%2"
7011 [(set_attr "type" "imul")
7012 (set_attr "length_immediate" "0")
7013 (set (attr "athlon_decode")
7014 (if_then_else (eq_attr "cpu" "athlon")
7015 (const_string "vector")
7016 (const_string "double")))
7017 (set_attr "amdfam10_decode" "double")
7018 (set_attr "bdver1_decode" "direct")
7019 (set_attr "mode" "SI")])
7020
7021 ;; The patterns that match these are at the end of this file.
7022
7023 (define_expand "mulxf3"
7024 [(set (match_operand:XF 0 "register_operand" "")
7025 (mult:XF (match_operand:XF 1 "register_operand" "")
7026 (match_operand:XF 2 "register_operand" "")))]
7027 "TARGET_80387")
7028
7029 (define_expand "mul<mode>3"
7030 [(set (match_operand:MODEF 0 "register_operand" "")
7031 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7032 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7033 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7034 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7035 \f
7036 ;; Divide instructions
7037
7038 ;; The patterns that match these are at the end of this file.
7039
7040 (define_expand "divxf3"
7041 [(set (match_operand:XF 0 "register_operand" "")
7042 (div:XF (match_operand:XF 1 "register_operand" "")
7043 (match_operand:XF 2 "register_operand" "")))]
7044 "TARGET_80387")
7045
7046 (define_expand "divdf3"
7047 [(set (match_operand:DF 0 "register_operand" "")
7048 (div:DF (match_operand:DF 1 "register_operand" "")
7049 (match_operand:DF 2 "nonimmediate_operand" "")))]
7050 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7051 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7052
7053 (define_expand "divsf3"
7054 [(set (match_operand:SF 0 "register_operand" "")
7055 (div:SF (match_operand:SF 1 "register_operand" "")
7056 (match_operand:SF 2 "nonimmediate_operand" "")))]
7057 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7058 || TARGET_SSE_MATH"
7059 {
7060 if (TARGET_SSE_MATH
7061 && TARGET_RECIP_DIV
7062 && optimize_insn_for_speed_p ()
7063 && flag_finite_math_only && !flag_trapping_math
7064 && flag_unsafe_math_optimizations)
7065 {
7066 ix86_emit_swdivsf (operands[0], operands[1],
7067 operands[2], SFmode);
7068 DONE;
7069 }
7070 })
7071 \f
7072 ;; Divmod instructions.
7073
7074 (define_expand "divmod<mode>4"
7075 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7076 (div:SWIM248
7077 (match_operand:SWIM248 1 "register_operand" "")
7078 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7079 (set (match_operand:SWIM248 3 "register_operand" "")
7080 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7081 (clobber (reg:CC FLAGS_REG))])])
7082
7083 ;; Split with 8bit unsigned divide:
7084 ;; if (dividend an divisor are in [0-255])
7085 ;; use 8bit unsigned integer divide
7086 ;; else
7087 ;; use original integer divide
7088 (define_split
7089 [(set (match_operand:SWI48 0 "register_operand" "")
7090 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7091 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7092 (set (match_operand:SWI48 1 "register_operand" "")
7093 (mod:SWI48 (match_dup 2) (match_dup 3)))
7094 (clobber (reg:CC FLAGS_REG))]
7095 "TARGET_USE_8BIT_IDIV
7096 && TARGET_QIMODE_MATH
7097 && can_create_pseudo_p ()
7098 && !optimize_insn_for_size_p ()"
7099 [(const_int 0)]
7100 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7101
7102 (define_insn_and_split "divmod<mode>4_1"
7103 [(set (match_operand:SWI48 0 "register_operand" "=a")
7104 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7105 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7106 (set (match_operand:SWI48 1 "register_operand" "=&d")
7107 (mod:SWI48 (match_dup 2) (match_dup 3)))
7108 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7109 (clobber (reg:CC FLAGS_REG))]
7110 ""
7111 "#"
7112 "reload_completed"
7113 [(parallel [(set (match_dup 1)
7114 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7115 (clobber (reg:CC FLAGS_REG))])
7116 (parallel [(set (match_dup 0)
7117 (div:SWI48 (match_dup 2) (match_dup 3)))
7118 (set (match_dup 1)
7119 (mod:SWI48 (match_dup 2) (match_dup 3)))
7120 (use (match_dup 1))
7121 (clobber (reg:CC FLAGS_REG))])]
7122 {
7123 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7124
7125 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7126 operands[4] = operands[2];
7127 else
7128 {
7129 /* Avoid use of cltd in favor of a mov+shift. */
7130 emit_move_insn (operands[1], operands[2]);
7131 operands[4] = operands[1];
7132 }
7133 }
7134 [(set_attr "type" "multi")
7135 (set_attr "mode" "<MODE>")])
7136
7137 (define_insn_and_split "*divmod<mode>4"
7138 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7139 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7140 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7141 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7142 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7143 (clobber (reg:CC FLAGS_REG))]
7144 ""
7145 "#"
7146 "reload_completed"
7147 [(parallel [(set (match_dup 1)
7148 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7149 (clobber (reg:CC FLAGS_REG))])
7150 (parallel [(set (match_dup 0)
7151 (div:SWIM248 (match_dup 2) (match_dup 3)))
7152 (set (match_dup 1)
7153 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7154 (use (match_dup 1))
7155 (clobber (reg:CC FLAGS_REG))])]
7156 {
7157 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7158
7159 if (<MODE>mode != HImode
7160 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7161 operands[4] = operands[2];
7162 else
7163 {
7164 /* Avoid use of cltd in favor of a mov+shift. */
7165 emit_move_insn (operands[1], operands[2]);
7166 operands[4] = operands[1];
7167 }
7168 }
7169 [(set_attr "type" "multi")
7170 (set_attr "mode" "<MODE>")])
7171
7172 (define_insn "*divmod<mode>4_noext"
7173 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7174 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7175 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7176 (set (match_operand:SWIM248 1 "register_operand" "=d")
7177 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7178 (use (match_operand:SWIM248 4 "register_operand" "1"))
7179 (clobber (reg:CC FLAGS_REG))]
7180 ""
7181 "idiv{<imodesuffix>}\t%3"
7182 [(set_attr "type" "idiv")
7183 (set_attr "mode" "<MODE>")])
7184
7185 (define_expand "divmodqi4"
7186 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7187 (div:QI
7188 (match_operand:QI 1 "register_operand" "")
7189 (match_operand:QI 2 "nonimmediate_operand" "")))
7190 (set (match_operand:QI 3 "register_operand" "")
7191 (mod:QI (match_dup 1) (match_dup 2)))
7192 (clobber (reg:CC FLAGS_REG))])]
7193 "TARGET_QIMODE_MATH"
7194 {
7195 rtx div, mod, insn;
7196 rtx tmp0, tmp1;
7197
7198 tmp0 = gen_reg_rtx (HImode);
7199 tmp1 = gen_reg_rtx (HImode);
7200
7201 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7202 in AX. */
7203 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7204 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7205
7206 /* Extract remainder from AH. */
7207 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7208 insn = emit_move_insn (operands[3], tmp1);
7209
7210 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7211 set_unique_reg_note (insn, REG_EQUAL, mod);
7212
7213 /* Extract quotient from AL. */
7214 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7215
7216 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7217 set_unique_reg_note (insn, REG_EQUAL, div);
7218
7219 DONE;
7220 })
7221
7222 ;; Divide AX by r/m8, with result stored in
7223 ;; AL <- Quotient
7224 ;; AH <- Remainder
7225 ;; Change div/mod to HImode and extend the second argument to HImode
7226 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7227 ;; combine may fail.
7228 (define_insn "divmodhiqi3"
7229 [(set (match_operand:HI 0 "register_operand" "=a")
7230 (ior:HI
7231 (ashift:HI
7232 (zero_extend:HI
7233 (truncate:QI
7234 (mod:HI (match_operand:HI 1 "register_operand" "0")
7235 (sign_extend:HI
7236 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7237 (const_int 8))
7238 (zero_extend:HI
7239 (truncate:QI
7240 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7241 (clobber (reg:CC FLAGS_REG))]
7242 "TARGET_QIMODE_MATH"
7243 "idiv{b}\t%2"
7244 [(set_attr "type" "idiv")
7245 (set_attr "mode" "QI")])
7246
7247 (define_expand "udivmod<mode>4"
7248 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7249 (udiv:SWIM248
7250 (match_operand:SWIM248 1 "register_operand" "")
7251 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7252 (set (match_operand:SWIM248 3 "register_operand" "")
7253 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7254 (clobber (reg:CC FLAGS_REG))])])
7255
7256 ;; Split with 8bit unsigned divide:
7257 ;; if (dividend an divisor are in [0-255])
7258 ;; use 8bit unsigned integer divide
7259 ;; else
7260 ;; use original integer divide
7261 (define_split
7262 [(set (match_operand:SWI48 0 "register_operand" "")
7263 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7264 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7265 (set (match_operand:SWI48 1 "register_operand" "")
7266 (umod:SWI48 (match_dup 2) (match_dup 3)))
7267 (clobber (reg:CC FLAGS_REG))]
7268 "TARGET_USE_8BIT_IDIV
7269 && TARGET_QIMODE_MATH
7270 && can_create_pseudo_p ()
7271 && !optimize_insn_for_size_p ()"
7272 [(const_int 0)]
7273 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7274
7275 (define_insn_and_split "udivmod<mode>4_1"
7276 [(set (match_operand:SWI48 0 "register_operand" "=a")
7277 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7278 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7279 (set (match_operand:SWI48 1 "register_operand" "=&d")
7280 (umod:SWI48 (match_dup 2) (match_dup 3)))
7281 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7282 (clobber (reg:CC FLAGS_REG))]
7283 ""
7284 "#"
7285 "reload_completed"
7286 [(set (match_dup 1) (const_int 0))
7287 (parallel [(set (match_dup 0)
7288 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7289 (set (match_dup 1)
7290 (umod:SWI48 (match_dup 2) (match_dup 3)))
7291 (use (match_dup 1))
7292 (clobber (reg:CC FLAGS_REG))])]
7293 ""
7294 [(set_attr "type" "multi")
7295 (set_attr "mode" "<MODE>")])
7296
7297 (define_insn_and_split "*udivmod<mode>4"
7298 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7299 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7300 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7301 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7302 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7303 (clobber (reg:CC FLAGS_REG))]
7304 ""
7305 "#"
7306 "reload_completed"
7307 [(set (match_dup 1) (const_int 0))
7308 (parallel [(set (match_dup 0)
7309 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7310 (set (match_dup 1)
7311 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7312 (use (match_dup 1))
7313 (clobber (reg:CC FLAGS_REG))])]
7314 ""
7315 [(set_attr "type" "multi")
7316 (set_attr "mode" "<MODE>")])
7317
7318 (define_insn "*udivmod<mode>4_noext"
7319 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7320 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7321 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7322 (set (match_operand:SWIM248 1 "register_operand" "=d")
7323 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7324 (use (match_operand:SWIM248 4 "register_operand" "1"))
7325 (clobber (reg:CC FLAGS_REG))]
7326 ""
7327 "div{<imodesuffix>}\t%3"
7328 [(set_attr "type" "idiv")
7329 (set_attr "mode" "<MODE>")])
7330
7331 (define_expand "udivmodqi4"
7332 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7333 (udiv:QI
7334 (match_operand:QI 1 "register_operand" "")
7335 (match_operand:QI 2 "nonimmediate_operand" "")))
7336 (set (match_operand:QI 3 "register_operand" "")
7337 (umod:QI (match_dup 1) (match_dup 2)))
7338 (clobber (reg:CC FLAGS_REG))])]
7339 "TARGET_QIMODE_MATH"
7340 {
7341 rtx div, mod, insn;
7342 rtx tmp0, tmp1;
7343
7344 tmp0 = gen_reg_rtx (HImode);
7345 tmp1 = gen_reg_rtx (HImode);
7346
7347 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7348 in AX. */
7349 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7350 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7351
7352 /* Extract remainder from AH. */
7353 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7354 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7355 insn = emit_move_insn (operands[3], tmp1);
7356
7357 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7358 set_unique_reg_note (insn, REG_EQUAL, mod);
7359
7360 /* Extract quotient from AL. */
7361 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7362
7363 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7364 set_unique_reg_note (insn, REG_EQUAL, div);
7365
7366 DONE;
7367 })
7368
7369 (define_insn "udivmodhiqi3"
7370 [(set (match_operand:HI 0 "register_operand" "=a")
7371 (ior:HI
7372 (ashift:HI
7373 (zero_extend:HI
7374 (truncate:QI
7375 (mod:HI (match_operand:HI 1 "register_operand" "0")
7376 (zero_extend:HI
7377 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7378 (const_int 8))
7379 (zero_extend:HI
7380 (truncate:QI
7381 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7382 (clobber (reg:CC FLAGS_REG))]
7383 "TARGET_QIMODE_MATH"
7384 "div{b}\t%2"
7385 [(set_attr "type" "idiv")
7386 (set_attr "mode" "QI")])
7387
7388 ;; We cannot use div/idiv for double division, because it causes
7389 ;; "division by zero" on the overflow and that's not what we expect
7390 ;; from truncate. Because true (non truncating) double division is
7391 ;; never generated, we can't create this insn anyway.
7392 ;
7393 ;(define_insn ""
7394 ; [(set (match_operand:SI 0 "register_operand" "=a")
7395 ; (truncate:SI
7396 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7397 ; (zero_extend:DI
7398 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7399 ; (set (match_operand:SI 3 "register_operand" "=d")
7400 ; (truncate:SI
7401 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7402 ; (clobber (reg:CC FLAGS_REG))]
7403 ; ""
7404 ; "div{l}\t{%2, %0|%0, %2}"
7405 ; [(set_attr "type" "idiv")])
7406 \f
7407 ;;- Logical AND instructions
7408
7409 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7410 ;; Note that this excludes ah.
7411
7412 (define_expand "testsi_ccno_1"
7413 [(set (reg:CCNO FLAGS_REG)
7414 (compare:CCNO
7415 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7416 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7417 (const_int 0)))])
7418
7419 (define_expand "testqi_ccz_1"
7420 [(set (reg:CCZ FLAGS_REG)
7421 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7422 (match_operand:QI 1 "nonmemory_operand" ""))
7423 (const_int 0)))])
7424
7425 (define_expand "testdi_ccno_1"
7426 [(set (reg:CCNO FLAGS_REG)
7427 (compare:CCNO
7428 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7429 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7430 (const_int 0)))]
7431 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7432
7433 (define_insn "*testdi_1"
7434 [(set (reg FLAGS_REG)
7435 (compare
7436 (and:DI
7437 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7438 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7439 (const_int 0)))]
7440 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7441 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7442 "@
7443 test{l}\t{%k1, %k0|%k0, %k1}
7444 test{l}\t{%k1, %k0|%k0, %k1}
7445 test{q}\t{%1, %0|%0, %1}
7446 test{q}\t{%1, %0|%0, %1}
7447 test{q}\t{%1, %0|%0, %1}"
7448 [(set_attr "type" "test")
7449 (set_attr "modrm" "0,1,0,1,1")
7450 (set_attr "mode" "SI,SI,DI,DI,DI")])
7451
7452 (define_insn "*testqi_1_maybe_si"
7453 [(set (reg FLAGS_REG)
7454 (compare
7455 (and:QI
7456 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7457 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7458 (const_int 0)))]
7459 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7460 && ix86_match_ccmode (insn,
7461 CONST_INT_P (operands[1])
7462 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7463 {
7464 if (which_alternative == 3)
7465 {
7466 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7467 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7468 return "test{l}\t{%1, %k0|%k0, %1}";
7469 }
7470 return "test{b}\t{%1, %0|%0, %1}";
7471 }
7472 [(set_attr "type" "test")
7473 (set_attr "modrm" "0,1,1,1")
7474 (set_attr "mode" "QI,QI,QI,SI")
7475 (set_attr "pent_pair" "uv,np,uv,np")])
7476
7477 (define_insn "*test<mode>_1"
7478 [(set (reg FLAGS_REG)
7479 (compare
7480 (and:SWI124
7481 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7482 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7483 (const_int 0)))]
7484 "ix86_match_ccmode (insn, CCNOmode)
7485 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7486 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7487 [(set_attr "type" "test")
7488 (set_attr "modrm" "0,1,1")
7489 (set_attr "mode" "<MODE>")
7490 (set_attr "pent_pair" "uv,np,uv")])
7491
7492 (define_expand "testqi_ext_ccno_0"
7493 [(set (reg:CCNO FLAGS_REG)
7494 (compare:CCNO
7495 (and:SI
7496 (zero_extract:SI
7497 (match_operand 0 "ext_register_operand" "")
7498 (const_int 8)
7499 (const_int 8))
7500 (match_operand 1 "const_int_operand" ""))
7501 (const_int 0)))])
7502
7503 (define_insn "*testqi_ext_0"
7504 [(set (reg FLAGS_REG)
7505 (compare
7506 (and:SI
7507 (zero_extract:SI
7508 (match_operand 0 "ext_register_operand" "Q")
7509 (const_int 8)
7510 (const_int 8))
7511 (match_operand 1 "const_int_operand" "n"))
7512 (const_int 0)))]
7513 "ix86_match_ccmode (insn, CCNOmode)"
7514 "test{b}\t{%1, %h0|%h0, %1}"
7515 [(set_attr "type" "test")
7516 (set_attr "mode" "QI")
7517 (set_attr "length_immediate" "1")
7518 (set_attr "modrm" "1")
7519 (set_attr "pent_pair" "np")])
7520
7521 (define_insn "*testqi_ext_1_rex64"
7522 [(set (reg FLAGS_REG)
7523 (compare
7524 (and:SI
7525 (zero_extract:SI
7526 (match_operand 0 "ext_register_operand" "Q")
7527 (const_int 8)
7528 (const_int 8))
7529 (zero_extend:SI
7530 (match_operand:QI 1 "register_operand" "Q")))
7531 (const_int 0)))]
7532 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7533 "test{b}\t{%1, %h0|%h0, %1}"
7534 [(set_attr "type" "test")
7535 (set_attr "mode" "QI")])
7536
7537 (define_insn "*testqi_ext_1"
7538 [(set (reg FLAGS_REG)
7539 (compare
7540 (and:SI
7541 (zero_extract:SI
7542 (match_operand 0 "ext_register_operand" "Q")
7543 (const_int 8)
7544 (const_int 8))
7545 (zero_extend:SI
7546 (match_operand:QI 1 "general_operand" "Qm")))
7547 (const_int 0)))]
7548 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7549 "test{b}\t{%1, %h0|%h0, %1}"
7550 [(set_attr "type" "test")
7551 (set_attr "mode" "QI")])
7552
7553 (define_insn "*testqi_ext_2"
7554 [(set (reg FLAGS_REG)
7555 (compare
7556 (and:SI
7557 (zero_extract:SI
7558 (match_operand 0 "ext_register_operand" "Q")
7559 (const_int 8)
7560 (const_int 8))
7561 (zero_extract:SI
7562 (match_operand 1 "ext_register_operand" "Q")
7563 (const_int 8)
7564 (const_int 8)))
7565 (const_int 0)))]
7566 "ix86_match_ccmode (insn, CCNOmode)"
7567 "test{b}\t{%h1, %h0|%h0, %h1}"
7568 [(set_attr "type" "test")
7569 (set_attr "mode" "QI")])
7570
7571 (define_insn "*testqi_ext_3_rex64"
7572 [(set (reg FLAGS_REG)
7573 (compare (zero_extract:DI
7574 (match_operand 0 "nonimmediate_operand" "rm")
7575 (match_operand:DI 1 "const_int_operand" "")
7576 (match_operand:DI 2 "const_int_operand" ""))
7577 (const_int 0)))]
7578 "TARGET_64BIT
7579 && ix86_match_ccmode (insn, CCNOmode)
7580 && INTVAL (operands[1]) > 0
7581 && INTVAL (operands[2]) >= 0
7582 /* Ensure that resulting mask is zero or sign extended operand. */
7583 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7584 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7585 && INTVAL (operands[1]) > 32))
7586 && (GET_MODE (operands[0]) == SImode
7587 || GET_MODE (operands[0]) == DImode
7588 || GET_MODE (operands[0]) == HImode
7589 || GET_MODE (operands[0]) == QImode)"
7590 "#")
7591
7592 ;; Combine likes to form bit extractions for some tests. Humor it.
7593 (define_insn "*testqi_ext_3"
7594 [(set (reg FLAGS_REG)
7595 (compare (zero_extract:SI
7596 (match_operand 0 "nonimmediate_operand" "rm")
7597 (match_operand:SI 1 "const_int_operand" "")
7598 (match_operand:SI 2 "const_int_operand" ""))
7599 (const_int 0)))]
7600 "ix86_match_ccmode (insn, CCNOmode)
7601 && INTVAL (operands[1]) > 0
7602 && INTVAL (operands[2]) >= 0
7603 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7604 && (GET_MODE (operands[0]) == SImode
7605 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7606 || GET_MODE (operands[0]) == HImode
7607 || GET_MODE (operands[0]) == QImode)"
7608 "#")
7609
7610 (define_split
7611 [(set (match_operand 0 "flags_reg_operand" "")
7612 (match_operator 1 "compare_operator"
7613 [(zero_extract
7614 (match_operand 2 "nonimmediate_operand" "")
7615 (match_operand 3 "const_int_operand" "")
7616 (match_operand 4 "const_int_operand" ""))
7617 (const_int 0)]))]
7618 "ix86_match_ccmode (insn, CCNOmode)"
7619 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7620 {
7621 rtx val = operands[2];
7622 HOST_WIDE_INT len = INTVAL (operands[3]);
7623 HOST_WIDE_INT pos = INTVAL (operands[4]);
7624 HOST_WIDE_INT mask;
7625 enum machine_mode mode, submode;
7626
7627 mode = GET_MODE (val);
7628 if (MEM_P (val))
7629 {
7630 /* ??? Combine likes to put non-volatile mem extractions in QImode
7631 no matter the size of the test. So find a mode that works. */
7632 if (! MEM_VOLATILE_P (val))
7633 {
7634 mode = smallest_mode_for_size (pos + len, MODE_INT);
7635 val = adjust_address (val, mode, 0);
7636 }
7637 }
7638 else if (GET_CODE (val) == SUBREG
7639 && (submode = GET_MODE (SUBREG_REG (val)),
7640 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7641 && pos + len <= GET_MODE_BITSIZE (submode)
7642 && GET_MODE_CLASS (submode) == MODE_INT)
7643 {
7644 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7645 mode = submode;
7646 val = SUBREG_REG (val);
7647 }
7648 else if (mode == HImode && pos + len <= 8)
7649 {
7650 /* Small HImode tests can be converted to QImode. */
7651 mode = QImode;
7652 val = gen_lowpart (QImode, val);
7653 }
7654
7655 if (len == HOST_BITS_PER_WIDE_INT)
7656 mask = -1;
7657 else
7658 mask = ((HOST_WIDE_INT)1 << len) - 1;
7659 mask <<= pos;
7660
7661 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7662 })
7663
7664 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7665 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7666 ;; this is relatively important trick.
7667 ;; Do the conversion only post-reload to avoid limiting of the register class
7668 ;; to QI regs.
7669 (define_split
7670 [(set (match_operand 0 "flags_reg_operand" "")
7671 (match_operator 1 "compare_operator"
7672 [(and (match_operand 2 "register_operand" "")
7673 (match_operand 3 "const_int_operand" ""))
7674 (const_int 0)]))]
7675 "reload_completed
7676 && QI_REG_P (operands[2])
7677 && GET_MODE (operands[2]) != QImode
7678 && ((ix86_match_ccmode (insn, CCZmode)
7679 && !(INTVAL (operands[3]) & ~(255 << 8)))
7680 || (ix86_match_ccmode (insn, CCNOmode)
7681 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7682 [(set (match_dup 0)
7683 (match_op_dup 1
7684 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7685 (match_dup 3))
7686 (const_int 0)]))]
7687 "operands[2] = gen_lowpart (SImode, operands[2]);
7688 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7689
7690 (define_split
7691 [(set (match_operand 0 "flags_reg_operand" "")
7692 (match_operator 1 "compare_operator"
7693 [(and (match_operand 2 "nonimmediate_operand" "")
7694 (match_operand 3 "const_int_operand" ""))
7695 (const_int 0)]))]
7696 "reload_completed
7697 && GET_MODE (operands[2]) != QImode
7698 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7699 && ((ix86_match_ccmode (insn, CCZmode)
7700 && !(INTVAL (operands[3]) & ~255))
7701 || (ix86_match_ccmode (insn, CCNOmode)
7702 && !(INTVAL (operands[3]) & ~127)))"
7703 [(set (match_dup 0)
7704 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7705 (const_int 0)]))]
7706 "operands[2] = gen_lowpart (QImode, operands[2]);
7707 operands[3] = gen_lowpart (QImode, operands[3]);")
7708
7709 ;; %%% This used to optimize known byte-wide and operations to memory,
7710 ;; and sometimes to QImode registers. If this is considered useful,
7711 ;; it should be done with splitters.
7712
7713 (define_expand "and<mode>3"
7714 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7715 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7716 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7717 ""
7718 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7719
7720 (define_insn "*anddi_1"
7721 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7722 (and:DI
7723 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7724 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7725 (clobber (reg:CC FLAGS_REG))]
7726 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7727 {
7728 switch (get_attr_type (insn))
7729 {
7730 case TYPE_IMOVX:
7731 {
7732 enum machine_mode mode;
7733
7734 gcc_assert (CONST_INT_P (operands[2]));
7735 if (INTVAL (operands[2]) == 0xff)
7736 mode = QImode;
7737 else
7738 {
7739 gcc_assert (INTVAL (operands[2]) == 0xffff);
7740 mode = HImode;
7741 }
7742
7743 operands[1] = gen_lowpart (mode, operands[1]);
7744 if (mode == QImode)
7745 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7746 else
7747 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7748 }
7749
7750 default:
7751 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7752 if (get_attr_mode (insn) == MODE_SI)
7753 return "and{l}\t{%k2, %k0|%k0, %k2}";
7754 else
7755 return "and{q}\t{%2, %0|%0, %2}";
7756 }
7757 }
7758 [(set_attr "type" "alu,alu,alu,imovx")
7759 (set_attr "length_immediate" "*,*,*,0")
7760 (set (attr "prefix_rex")
7761 (if_then_else
7762 (and (eq_attr "type" "imovx")
7763 (and (match_test "INTVAL (operands[2]) == 0xff")
7764 (match_operand 1 "ext_QIreg_operand" "")))
7765 (const_string "1")
7766 (const_string "*")))
7767 (set_attr "mode" "SI,DI,DI,SI")])
7768
7769 (define_insn "*andsi_1"
7770 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7771 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7772 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7773 (clobber (reg:CC FLAGS_REG))]
7774 "ix86_binary_operator_ok (AND, SImode, operands)"
7775 {
7776 switch (get_attr_type (insn))
7777 {
7778 case TYPE_IMOVX:
7779 {
7780 enum machine_mode mode;
7781
7782 gcc_assert (CONST_INT_P (operands[2]));
7783 if (INTVAL (operands[2]) == 0xff)
7784 mode = QImode;
7785 else
7786 {
7787 gcc_assert (INTVAL (operands[2]) == 0xffff);
7788 mode = HImode;
7789 }
7790
7791 operands[1] = gen_lowpart (mode, operands[1]);
7792 if (mode == QImode)
7793 return "movz{bl|x}\t{%1, %0|%0, %1}";
7794 else
7795 return "movz{wl|x}\t{%1, %0|%0, %1}";
7796 }
7797
7798 default:
7799 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7800 return "and{l}\t{%2, %0|%0, %2}";
7801 }
7802 }
7803 [(set_attr "type" "alu,alu,imovx")
7804 (set (attr "prefix_rex")
7805 (if_then_else
7806 (and (eq_attr "type" "imovx")
7807 (and (match_test "INTVAL (operands[2]) == 0xff")
7808 (match_operand 1 "ext_QIreg_operand" "")))
7809 (const_string "1")
7810 (const_string "*")))
7811 (set_attr "length_immediate" "*,*,0")
7812 (set_attr "mode" "SI")])
7813
7814 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7815 (define_insn "*andsi_1_zext"
7816 [(set (match_operand:DI 0 "register_operand" "=r")
7817 (zero_extend:DI
7818 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7819 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7820 (clobber (reg:CC FLAGS_REG))]
7821 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7822 "and{l}\t{%2, %k0|%k0, %2}"
7823 [(set_attr "type" "alu")
7824 (set_attr "mode" "SI")])
7825
7826 (define_insn "*andhi_1"
7827 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7828 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7829 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7830 (clobber (reg:CC FLAGS_REG))]
7831 "ix86_binary_operator_ok (AND, HImode, operands)"
7832 {
7833 switch (get_attr_type (insn))
7834 {
7835 case TYPE_IMOVX:
7836 gcc_assert (CONST_INT_P (operands[2]));
7837 gcc_assert (INTVAL (operands[2]) == 0xff);
7838 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7839
7840 default:
7841 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7842
7843 return "and{w}\t{%2, %0|%0, %2}";
7844 }
7845 }
7846 [(set_attr "type" "alu,alu,imovx")
7847 (set_attr "length_immediate" "*,*,0")
7848 (set (attr "prefix_rex")
7849 (if_then_else
7850 (and (eq_attr "type" "imovx")
7851 (match_operand 1 "ext_QIreg_operand" ""))
7852 (const_string "1")
7853 (const_string "*")))
7854 (set_attr "mode" "HI,HI,SI")])
7855
7856 ;; %%% Potential partial reg stall on alternative 2. What to do?
7857 (define_insn "*andqi_1"
7858 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7859 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7860 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7861 (clobber (reg:CC FLAGS_REG))]
7862 "ix86_binary_operator_ok (AND, QImode, operands)"
7863 "@
7864 and{b}\t{%2, %0|%0, %2}
7865 and{b}\t{%2, %0|%0, %2}
7866 and{l}\t{%k2, %k0|%k0, %k2}"
7867 [(set_attr "type" "alu")
7868 (set_attr "mode" "QI,QI,SI")])
7869
7870 (define_insn "*andqi_1_slp"
7871 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7872 (and:QI (match_dup 0)
7873 (match_operand:QI 1 "general_operand" "qn,qmn")))
7874 (clobber (reg:CC FLAGS_REG))]
7875 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7876 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7877 "and{b}\t{%1, %0|%0, %1}"
7878 [(set_attr "type" "alu1")
7879 (set_attr "mode" "QI")])
7880
7881 (define_split
7882 [(set (match_operand 0 "register_operand" "")
7883 (and (match_dup 0)
7884 (const_int -65536)))
7885 (clobber (reg:CC FLAGS_REG))]
7886 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7887 || optimize_function_for_size_p (cfun)"
7888 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7889 "operands[1] = gen_lowpart (HImode, operands[0]);")
7890
7891 (define_split
7892 [(set (match_operand 0 "ext_register_operand" "")
7893 (and (match_dup 0)
7894 (const_int -256)))
7895 (clobber (reg:CC FLAGS_REG))]
7896 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7897 && reload_completed"
7898 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7899 "operands[1] = gen_lowpart (QImode, operands[0]);")
7900
7901 (define_split
7902 [(set (match_operand 0 "ext_register_operand" "")
7903 (and (match_dup 0)
7904 (const_int -65281)))
7905 (clobber (reg:CC FLAGS_REG))]
7906 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7907 && reload_completed"
7908 [(parallel [(set (zero_extract:SI (match_dup 0)
7909 (const_int 8)
7910 (const_int 8))
7911 (xor:SI
7912 (zero_extract:SI (match_dup 0)
7913 (const_int 8)
7914 (const_int 8))
7915 (zero_extract:SI (match_dup 0)
7916 (const_int 8)
7917 (const_int 8))))
7918 (clobber (reg:CC FLAGS_REG))])]
7919 "operands[0] = gen_lowpart (SImode, operands[0]);")
7920
7921 (define_insn "*anddi_2"
7922 [(set (reg FLAGS_REG)
7923 (compare
7924 (and:DI
7925 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7926 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7927 (const_int 0)))
7928 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7929 (and:DI (match_dup 1) (match_dup 2)))]
7930 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7931 && ix86_binary_operator_ok (AND, DImode, operands)"
7932 "@
7933 and{l}\t{%k2, %k0|%k0, %k2}
7934 and{q}\t{%2, %0|%0, %2}
7935 and{q}\t{%2, %0|%0, %2}"
7936 [(set_attr "type" "alu")
7937 (set_attr "mode" "SI,DI,DI")])
7938
7939 (define_insn "*andqi_2_maybe_si"
7940 [(set (reg FLAGS_REG)
7941 (compare (and:QI
7942 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7943 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7944 (const_int 0)))
7945 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7946 (and:QI (match_dup 1) (match_dup 2)))]
7947 "ix86_binary_operator_ok (AND, QImode, operands)
7948 && ix86_match_ccmode (insn,
7949 CONST_INT_P (operands[2])
7950 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7951 {
7952 if (which_alternative == 2)
7953 {
7954 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7955 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7956 return "and{l}\t{%2, %k0|%k0, %2}";
7957 }
7958 return "and{b}\t{%2, %0|%0, %2}";
7959 }
7960 [(set_attr "type" "alu")
7961 (set_attr "mode" "QI,QI,SI")])
7962
7963 (define_insn "*and<mode>_2"
7964 [(set (reg FLAGS_REG)
7965 (compare (and:SWI124
7966 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7967 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7968 (const_int 0)))
7969 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7970 (and:SWI124 (match_dup 1) (match_dup 2)))]
7971 "ix86_match_ccmode (insn, CCNOmode)
7972 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7973 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7974 [(set_attr "type" "alu")
7975 (set_attr "mode" "<MODE>")])
7976
7977 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7978 (define_insn "*andsi_2_zext"
7979 [(set (reg FLAGS_REG)
7980 (compare (and:SI
7981 (match_operand:SI 1 "nonimmediate_operand" "%0")
7982 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7983 (const_int 0)))
7984 (set (match_operand:DI 0 "register_operand" "=r")
7985 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7986 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7987 && ix86_binary_operator_ok (AND, SImode, operands)"
7988 "and{l}\t{%2, %k0|%k0, %2}"
7989 [(set_attr "type" "alu")
7990 (set_attr "mode" "SI")])
7991
7992 (define_insn "*andqi_2_slp"
7993 [(set (reg FLAGS_REG)
7994 (compare (and:QI
7995 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7996 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7997 (const_int 0)))
7998 (set (strict_low_part (match_dup 0))
7999 (and:QI (match_dup 0) (match_dup 1)))]
8000 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8001 && ix86_match_ccmode (insn, CCNOmode)
8002 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8003 "and{b}\t{%1, %0|%0, %1}"
8004 [(set_attr "type" "alu1")
8005 (set_attr "mode" "QI")])
8006
8007 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8008 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8009 ;; for a QImode operand, which of course failed.
8010 (define_insn "andqi_ext_0"
8011 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8012 (const_int 8)
8013 (const_int 8))
8014 (and:SI
8015 (zero_extract:SI
8016 (match_operand 1 "ext_register_operand" "0")
8017 (const_int 8)
8018 (const_int 8))
8019 (match_operand 2 "const_int_operand" "n")))
8020 (clobber (reg:CC FLAGS_REG))]
8021 ""
8022 "and{b}\t{%2, %h0|%h0, %2}"
8023 [(set_attr "type" "alu")
8024 (set_attr "length_immediate" "1")
8025 (set_attr "modrm" "1")
8026 (set_attr "mode" "QI")])
8027
8028 ;; Generated by peephole translating test to and. This shows up
8029 ;; often in fp comparisons.
8030 (define_insn "*andqi_ext_0_cc"
8031 [(set (reg FLAGS_REG)
8032 (compare
8033 (and:SI
8034 (zero_extract:SI
8035 (match_operand 1 "ext_register_operand" "0")
8036 (const_int 8)
8037 (const_int 8))
8038 (match_operand 2 "const_int_operand" "n"))
8039 (const_int 0)))
8040 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8041 (const_int 8)
8042 (const_int 8))
8043 (and:SI
8044 (zero_extract:SI
8045 (match_dup 1)
8046 (const_int 8)
8047 (const_int 8))
8048 (match_dup 2)))]
8049 "ix86_match_ccmode (insn, CCNOmode)"
8050 "and{b}\t{%2, %h0|%h0, %2}"
8051 [(set_attr "type" "alu")
8052 (set_attr "length_immediate" "1")
8053 (set_attr "modrm" "1")
8054 (set_attr "mode" "QI")])
8055
8056 (define_insn "*andqi_ext_1_rex64"
8057 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8058 (const_int 8)
8059 (const_int 8))
8060 (and:SI
8061 (zero_extract:SI
8062 (match_operand 1 "ext_register_operand" "0")
8063 (const_int 8)
8064 (const_int 8))
8065 (zero_extend:SI
8066 (match_operand 2 "ext_register_operand" "Q"))))
8067 (clobber (reg:CC FLAGS_REG))]
8068 "TARGET_64BIT"
8069 "and{b}\t{%2, %h0|%h0, %2}"
8070 [(set_attr "type" "alu")
8071 (set_attr "length_immediate" "0")
8072 (set_attr "mode" "QI")])
8073
8074 (define_insn "*andqi_ext_1"
8075 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8076 (const_int 8)
8077 (const_int 8))
8078 (and:SI
8079 (zero_extract:SI
8080 (match_operand 1 "ext_register_operand" "0")
8081 (const_int 8)
8082 (const_int 8))
8083 (zero_extend:SI
8084 (match_operand:QI 2 "general_operand" "Qm"))))
8085 (clobber (reg:CC FLAGS_REG))]
8086 "!TARGET_64BIT"
8087 "and{b}\t{%2, %h0|%h0, %2}"
8088 [(set_attr "type" "alu")
8089 (set_attr "length_immediate" "0")
8090 (set_attr "mode" "QI")])
8091
8092 (define_insn "*andqi_ext_2"
8093 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8094 (const_int 8)
8095 (const_int 8))
8096 (and:SI
8097 (zero_extract:SI
8098 (match_operand 1 "ext_register_operand" "%0")
8099 (const_int 8)
8100 (const_int 8))
8101 (zero_extract:SI
8102 (match_operand 2 "ext_register_operand" "Q")
8103 (const_int 8)
8104 (const_int 8))))
8105 (clobber (reg:CC FLAGS_REG))]
8106 ""
8107 "and{b}\t{%h2, %h0|%h0, %h2}"
8108 [(set_attr "type" "alu")
8109 (set_attr "length_immediate" "0")
8110 (set_attr "mode" "QI")])
8111
8112 ;; Convert wide AND instructions with immediate operand to shorter QImode
8113 ;; equivalents when possible.
8114 ;; Don't do the splitting with memory operands, since it introduces risk
8115 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8116 ;; for size, but that can (should?) be handled by generic code instead.
8117 (define_split
8118 [(set (match_operand 0 "register_operand" "")
8119 (and (match_operand 1 "register_operand" "")
8120 (match_operand 2 "const_int_operand" "")))
8121 (clobber (reg:CC FLAGS_REG))]
8122 "reload_completed
8123 && QI_REG_P (operands[0])
8124 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8125 && !(~INTVAL (operands[2]) & ~(255 << 8))
8126 && GET_MODE (operands[0]) != QImode"
8127 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8128 (and:SI (zero_extract:SI (match_dup 1)
8129 (const_int 8) (const_int 8))
8130 (match_dup 2)))
8131 (clobber (reg:CC FLAGS_REG))])]
8132 "operands[0] = gen_lowpart (SImode, operands[0]);
8133 operands[1] = gen_lowpart (SImode, operands[1]);
8134 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8135
8136 ;; Since AND can be encoded with sign extended immediate, this is only
8137 ;; profitable when 7th bit is not set.
8138 (define_split
8139 [(set (match_operand 0 "register_operand" "")
8140 (and (match_operand 1 "general_operand" "")
8141 (match_operand 2 "const_int_operand" "")))
8142 (clobber (reg:CC FLAGS_REG))]
8143 "reload_completed
8144 && ANY_QI_REG_P (operands[0])
8145 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8146 && !(~INTVAL (operands[2]) & ~255)
8147 && !(INTVAL (operands[2]) & 128)
8148 && GET_MODE (operands[0]) != QImode"
8149 [(parallel [(set (strict_low_part (match_dup 0))
8150 (and:QI (match_dup 1)
8151 (match_dup 2)))
8152 (clobber (reg:CC FLAGS_REG))])]
8153 "operands[0] = gen_lowpart (QImode, operands[0]);
8154 operands[1] = gen_lowpart (QImode, operands[1]);
8155 operands[2] = gen_lowpart (QImode, operands[2]);")
8156 \f
8157 ;; Logical inclusive and exclusive OR instructions
8158
8159 ;; %%% This used to optimize known byte-wide and operations to memory.
8160 ;; If this is considered useful, it should be done with splitters.
8161
8162 (define_expand "<code><mode>3"
8163 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8164 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8165 (match_operand:SWIM 2 "<general_operand>" "")))]
8166 ""
8167 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8168
8169 (define_insn "*<code><mode>_1"
8170 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8171 (any_or:SWI248
8172 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8173 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8174 (clobber (reg:CC FLAGS_REG))]
8175 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8176 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8177 [(set_attr "type" "alu")
8178 (set_attr "mode" "<MODE>")])
8179
8180 ;; %%% Potential partial reg stall on alternative 2. What to do?
8181 (define_insn "*<code>qi_1"
8182 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8183 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8184 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8185 (clobber (reg:CC FLAGS_REG))]
8186 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8187 "@
8188 <logic>{b}\t{%2, %0|%0, %2}
8189 <logic>{b}\t{%2, %0|%0, %2}
8190 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8191 [(set_attr "type" "alu")
8192 (set_attr "mode" "QI,QI,SI")])
8193
8194 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8195 (define_insn "*<code>si_1_zext"
8196 [(set (match_operand:DI 0 "register_operand" "=r")
8197 (zero_extend:DI
8198 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8199 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8200 (clobber (reg:CC FLAGS_REG))]
8201 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8202 "<logic>{l}\t{%2, %k0|%k0, %2}"
8203 [(set_attr "type" "alu")
8204 (set_attr "mode" "SI")])
8205
8206 (define_insn "*<code>si_1_zext_imm"
8207 [(set (match_operand:DI 0 "register_operand" "=r")
8208 (any_or:DI
8209 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8210 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8211 (clobber (reg:CC FLAGS_REG))]
8212 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8213 "<logic>{l}\t{%2, %k0|%k0, %2}"
8214 [(set_attr "type" "alu")
8215 (set_attr "mode" "SI")])
8216
8217 (define_insn "*<code>qi_1_slp"
8218 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8219 (any_or:QI (match_dup 0)
8220 (match_operand:QI 1 "general_operand" "qmn,qn")))
8221 (clobber (reg:CC FLAGS_REG))]
8222 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8223 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8224 "<logic>{b}\t{%1, %0|%0, %1}"
8225 [(set_attr "type" "alu1")
8226 (set_attr "mode" "QI")])
8227
8228 (define_insn "*<code><mode>_2"
8229 [(set (reg FLAGS_REG)
8230 (compare (any_or:SWI
8231 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8232 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8233 (const_int 0)))
8234 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8235 (any_or:SWI (match_dup 1) (match_dup 2)))]
8236 "ix86_match_ccmode (insn, CCNOmode)
8237 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8238 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8239 [(set_attr "type" "alu")
8240 (set_attr "mode" "<MODE>")])
8241
8242 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8243 ;; ??? Special case for immediate operand is missing - it is tricky.
8244 (define_insn "*<code>si_2_zext"
8245 [(set (reg FLAGS_REG)
8246 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8247 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8248 (const_int 0)))
8249 (set (match_operand:DI 0 "register_operand" "=r")
8250 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8251 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8252 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8253 "<logic>{l}\t{%2, %k0|%k0, %2}"
8254 [(set_attr "type" "alu")
8255 (set_attr "mode" "SI")])
8256
8257 (define_insn "*<code>si_2_zext_imm"
8258 [(set (reg FLAGS_REG)
8259 (compare (any_or:SI
8260 (match_operand:SI 1 "nonimmediate_operand" "%0")
8261 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8262 (const_int 0)))
8263 (set (match_operand:DI 0 "register_operand" "=r")
8264 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8265 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8266 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8267 "<logic>{l}\t{%2, %k0|%k0, %2}"
8268 [(set_attr "type" "alu")
8269 (set_attr "mode" "SI")])
8270
8271 (define_insn "*<code>qi_2_slp"
8272 [(set (reg FLAGS_REG)
8273 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8274 (match_operand:QI 1 "general_operand" "qmn,qn"))
8275 (const_int 0)))
8276 (set (strict_low_part (match_dup 0))
8277 (any_or:QI (match_dup 0) (match_dup 1)))]
8278 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8279 && ix86_match_ccmode (insn, CCNOmode)
8280 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8281 "<logic>{b}\t{%1, %0|%0, %1}"
8282 [(set_attr "type" "alu1")
8283 (set_attr "mode" "QI")])
8284
8285 (define_insn "*<code><mode>_3"
8286 [(set (reg FLAGS_REG)
8287 (compare (any_or:SWI
8288 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8289 (match_operand:SWI 2 "<general_operand>" "<g>"))
8290 (const_int 0)))
8291 (clobber (match_scratch:SWI 0 "=<r>"))]
8292 "ix86_match_ccmode (insn, CCNOmode)
8293 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8294 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8295 [(set_attr "type" "alu")
8296 (set_attr "mode" "<MODE>")])
8297
8298 (define_insn "*<code>qi_ext_0"
8299 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8300 (const_int 8)
8301 (const_int 8))
8302 (any_or:SI
8303 (zero_extract:SI
8304 (match_operand 1 "ext_register_operand" "0")
8305 (const_int 8)
8306 (const_int 8))
8307 (match_operand 2 "const_int_operand" "n")))
8308 (clobber (reg:CC FLAGS_REG))]
8309 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8310 "<logic>{b}\t{%2, %h0|%h0, %2}"
8311 [(set_attr "type" "alu")
8312 (set_attr "length_immediate" "1")
8313 (set_attr "modrm" "1")
8314 (set_attr "mode" "QI")])
8315
8316 (define_insn "*<code>qi_ext_1_rex64"
8317 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8318 (const_int 8)
8319 (const_int 8))
8320 (any_or:SI
8321 (zero_extract:SI
8322 (match_operand 1 "ext_register_operand" "0")
8323 (const_int 8)
8324 (const_int 8))
8325 (zero_extend:SI
8326 (match_operand 2 "ext_register_operand" "Q"))))
8327 (clobber (reg:CC FLAGS_REG))]
8328 "TARGET_64BIT
8329 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8330 "<logic>{b}\t{%2, %h0|%h0, %2}"
8331 [(set_attr "type" "alu")
8332 (set_attr "length_immediate" "0")
8333 (set_attr "mode" "QI")])
8334
8335 (define_insn "*<code>qi_ext_1"
8336 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8337 (const_int 8)
8338 (const_int 8))
8339 (any_or:SI
8340 (zero_extract:SI
8341 (match_operand 1 "ext_register_operand" "0")
8342 (const_int 8)
8343 (const_int 8))
8344 (zero_extend:SI
8345 (match_operand:QI 2 "general_operand" "Qm"))))
8346 (clobber (reg:CC FLAGS_REG))]
8347 "!TARGET_64BIT
8348 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8349 "<logic>{b}\t{%2, %h0|%h0, %2}"
8350 [(set_attr "type" "alu")
8351 (set_attr "length_immediate" "0")
8352 (set_attr "mode" "QI")])
8353
8354 (define_insn "*<code>qi_ext_2"
8355 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8356 (const_int 8)
8357 (const_int 8))
8358 (any_or:SI
8359 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8360 (const_int 8)
8361 (const_int 8))
8362 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8363 (const_int 8)
8364 (const_int 8))))
8365 (clobber (reg:CC FLAGS_REG))]
8366 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8367 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8368 [(set_attr "type" "alu")
8369 (set_attr "length_immediate" "0")
8370 (set_attr "mode" "QI")])
8371
8372 (define_split
8373 [(set (match_operand 0 "register_operand" "")
8374 (any_or (match_operand 1 "register_operand" "")
8375 (match_operand 2 "const_int_operand" "")))
8376 (clobber (reg:CC FLAGS_REG))]
8377 "reload_completed
8378 && QI_REG_P (operands[0])
8379 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8380 && !(INTVAL (operands[2]) & ~(255 << 8))
8381 && GET_MODE (operands[0]) != QImode"
8382 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8383 (any_or:SI (zero_extract:SI (match_dup 1)
8384 (const_int 8) (const_int 8))
8385 (match_dup 2)))
8386 (clobber (reg:CC FLAGS_REG))])]
8387 "operands[0] = gen_lowpart (SImode, operands[0]);
8388 operands[1] = gen_lowpart (SImode, operands[1]);
8389 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8390
8391 ;; Since OR can be encoded with sign extended immediate, this is only
8392 ;; profitable when 7th bit is set.
8393 (define_split
8394 [(set (match_operand 0 "register_operand" "")
8395 (any_or (match_operand 1 "general_operand" "")
8396 (match_operand 2 "const_int_operand" "")))
8397 (clobber (reg:CC FLAGS_REG))]
8398 "reload_completed
8399 && ANY_QI_REG_P (operands[0])
8400 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8401 && !(INTVAL (operands[2]) & ~255)
8402 && (INTVAL (operands[2]) & 128)
8403 && GET_MODE (operands[0]) != QImode"
8404 [(parallel [(set (strict_low_part (match_dup 0))
8405 (any_or:QI (match_dup 1)
8406 (match_dup 2)))
8407 (clobber (reg:CC FLAGS_REG))])]
8408 "operands[0] = gen_lowpart (QImode, operands[0]);
8409 operands[1] = gen_lowpart (QImode, operands[1]);
8410 operands[2] = gen_lowpart (QImode, operands[2]);")
8411
8412 (define_expand "xorqi_cc_ext_1"
8413 [(parallel [
8414 (set (reg:CCNO FLAGS_REG)
8415 (compare:CCNO
8416 (xor:SI
8417 (zero_extract:SI
8418 (match_operand 1 "ext_register_operand" "")
8419 (const_int 8)
8420 (const_int 8))
8421 (match_operand:QI 2 "general_operand" ""))
8422 (const_int 0)))
8423 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8424 (const_int 8)
8425 (const_int 8))
8426 (xor:SI
8427 (zero_extract:SI
8428 (match_dup 1)
8429 (const_int 8)
8430 (const_int 8))
8431 (match_dup 2)))])])
8432
8433 (define_insn "*xorqi_cc_ext_1_rex64"
8434 [(set (reg FLAGS_REG)
8435 (compare
8436 (xor:SI
8437 (zero_extract:SI
8438 (match_operand 1 "ext_register_operand" "0")
8439 (const_int 8)
8440 (const_int 8))
8441 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8442 (const_int 0)))
8443 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8444 (const_int 8)
8445 (const_int 8))
8446 (xor:SI
8447 (zero_extract:SI
8448 (match_dup 1)
8449 (const_int 8)
8450 (const_int 8))
8451 (match_dup 2)))]
8452 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8453 "xor{b}\t{%2, %h0|%h0, %2}"
8454 [(set_attr "type" "alu")
8455 (set_attr "modrm" "1")
8456 (set_attr "mode" "QI")])
8457
8458 (define_insn "*xorqi_cc_ext_1"
8459 [(set (reg FLAGS_REG)
8460 (compare
8461 (xor:SI
8462 (zero_extract:SI
8463 (match_operand 1 "ext_register_operand" "0")
8464 (const_int 8)
8465 (const_int 8))
8466 (match_operand:QI 2 "general_operand" "qmn"))
8467 (const_int 0)))
8468 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8469 (const_int 8)
8470 (const_int 8))
8471 (xor:SI
8472 (zero_extract:SI
8473 (match_dup 1)
8474 (const_int 8)
8475 (const_int 8))
8476 (match_dup 2)))]
8477 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8478 "xor{b}\t{%2, %h0|%h0, %2}"
8479 [(set_attr "type" "alu")
8480 (set_attr "modrm" "1")
8481 (set_attr "mode" "QI")])
8482 \f
8483 ;; Negation instructions
8484
8485 (define_expand "neg<mode>2"
8486 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8487 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8488 ""
8489 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8490
8491 (define_insn_and_split "*neg<dwi>2_doubleword"
8492 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8493 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8494 (clobber (reg:CC FLAGS_REG))]
8495 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8496 "#"
8497 "reload_completed"
8498 [(parallel
8499 [(set (reg:CCZ FLAGS_REG)
8500 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8501 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8502 (parallel
8503 [(set (match_dup 2)
8504 (plus:DWIH (match_dup 3)
8505 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8506 (const_int 0))))
8507 (clobber (reg:CC FLAGS_REG))])
8508 (parallel
8509 [(set (match_dup 2)
8510 (neg:DWIH (match_dup 2)))
8511 (clobber (reg:CC FLAGS_REG))])]
8512 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8513
8514 (define_insn "*neg<mode>2_1"
8515 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8516 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8517 (clobber (reg:CC FLAGS_REG))]
8518 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8519 "neg{<imodesuffix>}\t%0"
8520 [(set_attr "type" "negnot")
8521 (set_attr "mode" "<MODE>")])
8522
8523 ;; Combine is quite creative about this pattern.
8524 (define_insn "*negsi2_1_zext"
8525 [(set (match_operand:DI 0 "register_operand" "=r")
8526 (lshiftrt:DI
8527 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8528 (const_int 32)))
8529 (const_int 32)))
8530 (clobber (reg:CC FLAGS_REG))]
8531 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8532 "neg{l}\t%k0"
8533 [(set_attr "type" "negnot")
8534 (set_attr "mode" "SI")])
8535
8536 ;; The problem with neg is that it does not perform (compare x 0),
8537 ;; it really performs (compare 0 x), which leaves us with the zero
8538 ;; flag being the only useful item.
8539
8540 (define_insn "*neg<mode>2_cmpz"
8541 [(set (reg:CCZ FLAGS_REG)
8542 (compare:CCZ
8543 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8544 (const_int 0)))
8545 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8546 (neg:SWI (match_dup 1)))]
8547 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8548 "neg{<imodesuffix>}\t%0"
8549 [(set_attr "type" "negnot")
8550 (set_attr "mode" "<MODE>")])
8551
8552 (define_insn "*negsi2_cmpz_zext"
8553 [(set (reg:CCZ FLAGS_REG)
8554 (compare:CCZ
8555 (lshiftrt:DI
8556 (neg:DI (ashift:DI
8557 (match_operand:DI 1 "register_operand" "0")
8558 (const_int 32)))
8559 (const_int 32))
8560 (const_int 0)))
8561 (set (match_operand:DI 0 "register_operand" "=r")
8562 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8563 (const_int 32)))
8564 (const_int 32)))]
8565 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8566 "neg{l}\t%k0"
8567 [(set_attr "type" "negnot")
8568 (set_attr "mode" "SI")])
8569
8570 ;; Changing of sign for FP values is doable using integer unit too.
8571
8572 (define_expand "<code><mode>2"
8573 [(set (match_operand:X87MODEF 0 "register_operand" "")
8574 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8575 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8576 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8577
8578 (define_insn "*absneg<mode>2_mixed"
8579 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8580 (match_operator:MODEF 3 "absneg_operator"
8581 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8582 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8583 (clobber (reg:CC FLAGS_REG))]
8584 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8585 "#")
8586
8587 (define_insn "*absneg<mode>2_sse"
8588 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8589 (match_operator:MODEF 3 "absneg_operator"
8590 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8591 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8592 (clobber (reg:CC FLAGS_REG))]
8593 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8594 "#")
8595
8596 (define_insn "*absneg<mode>2_i387"
8597 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8598 (match_operator:X87MODEF 3 "absneg_operator"
8599 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8600 (use (match_operand 2 "" ""))
8601 (clobber (reg:CC FLAGS_REG))]
8602 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8603 "#")
8604
8605 (define_expand "<code>tf2"
8606 [(set (match_operand:TF 0 "register_operand" "")
8607 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8608 "TARGET_SSE2"
8609 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8610
8611 (define_insn "*absnegtf2_sse"
8612 [(set (match_operand:TF 0 "register_operand" "=x,x")
8613 (match_operator:TF 3 "absneg_operator"
8614 [(match_operand:TF 1 "register_operand" "0,x")]))
8615 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8616 (clobber (reg:CC FLAGS_REG))]
8617 "TARGET_SSE2"
8618 "#")
8619
8620 ;; Splitters for fp abs and neg.
8621
8622 (define_split
8623 [(set (match_operand 0 "fp_register_operand" "")
8624 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8625 (use (match_operand 2 "" ""))
8626 (clobber (reg:CC FLAGS_REG))]
8627 "reload_completed"
8628 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8629
8630 (define_split
8631 [(set (match_operand 0 "register_operand" "")
8632 (match_operator 3 "absneg_operator"
8633 [(match_operand 1 "register_operand" "")]))
8634 (use (match_operand 2 "nonimmediate_operand" ""))
8635 (clobber (reg:CC FLAGS_REG))]
8636 "reload_completed && SSE_REG_P (operands[0])"
8637 [(set (match_dup 0) (match_dup 3))]
8638 {
8639 enum machine_mode mode = GET_MODE (operands[0]);
8640 enum machine_mode vmode = GET_MODE (operands[2]);
8641 rtx tmp;
8642
8643 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8644 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8645 if (operands_match_p (operands[0], operands[2]))
8646 {
8647 tmp = operands[1];
8648 operands[1] = operands[2];
8649 operands[2] = tmp;
8650 }
8651 if (GET_CODE (operands[3]) == ABS)
8652 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8653 else
8654 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8655 operands[3] = tmp;
8656 })
8657
8658 (define_split
8659 [(set (match_operand:SF 0 "register_operand" "")
8660 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8661 (use (match_operand:V4SF 2 "" ""))
8662 (clobber (reg:CC FLAGS_REG))]
8663 "reload_completed"
8664 [(parallel [(set (match_dup 0) (match_dup 1))
8665 (clobber (reg:CC FLAGS_REG))])]
8666 {
8667 rtx tmp;
8668 operands[0] = gen_lowpart (SImode, operands[0]);
8669 if (GET_CODE (operands[1]) == ABS)
8670 {
8671 tmp = gen_int_mode (0x7fffffff, SImode);
8672 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8673 }
8674 else
8675 {
8676 tmp = gen_int_mode (0x80000000, SImode);
8677 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8678 }
8679 operands[1] = tmp;
8680 })
8681
8682 (define_split
8683 [(set (match_operand:DF 0 "register_operand" "")
8684 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8685 (use (match_operand 2 "" ""))
8686 (clobber (reg:CC FLAGS_REG))]
8687 "reload_completed"
8688 [(parallel [(set (match_dup 0) (match_dup 1))
8689 (clobber (reg:CC FLAGS_REG))])]
8690 {
8691 rtx tmp;
8692 if (TARGET_64BIT)
8693 {
8694 tmp = gen_lowpart (DImode, operands[0]);
8695 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8696 operands[0] = tmp;
8697
8698 if (GET_CODE (operands[1]) == ABS)
8699 tmp = const0_rtx;
8700 else
8701 tmp = gen_rtx_NOT (DImode, tmp);
8702 }
8703 else
8704 {
8705 operands[0] = gen_highpart (SImode, operands[0]);
8706 if (GET_CODE (operands[1]) == ABS)
8707 {
8708 tmp = gen_int_mode (0x7fffffff, SImode);
8709 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8710 }
8711 else
8712 {
8713 tmp = gen_int_mode (0x80000000, SImode);
8714 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8715 }
8716 }
8717 operands[1] = tmp;
8718 })
8719
8720 (define_split
8721 [(set (match_operand:XF 0 "register_operand" "")
8722 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8723 (use (match_operand 2 "" ""))
8724 (clobber (reg:CC FLAGS_REG))]
8725 "reload_completed"
8726 [(parallel [(set (match_dup 0) (match_dup 1))
8727 (clobber (reg:CC FLAGS_REG))])]
8728 {
8729 rtx tmp;
8730 operands[0] = gen_rtx_REG (SImode,
8731 true_regnum (operands[0])
8732 + (TARGET_64BIT ? 1 : 2));
8733 if (GET_CODE (operands[1]) == ABS)
8734 {
8735 tmp = GEN_INT (0x7fff);
8736 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8737 }
8738 else
8739 {
8740 tmp = GEN_INT (0x8000);
8741 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8742 }
8743 operands[1] = tmp;
8744 })
8745
8746 ;; Conditionalize these after reload. If they match before reload, we
8747 ;; lose the clobber and ability to use integer instructions.
8748
8749 (define_insn "*<code><mode>2_1"
8750 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8751 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8752 "TARGET_80387
8753 && (reload_completed
8754 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8755 "f<absneg_mnemonic>"
8756 [(set_attr "type" "fsgn")
8757 (set_attr "mode" "<MODE>")])
8758
8759 (define_insn "*<code>extendsfdf2"
8760 [(set (match_operand:DF 0 "register_operand" "=f")
8761 (absneg:DF (float_extend:DF
8762 (match_operand:SF 1 "register_operand" "0"))))]
8763 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8764 "f<absneg_mnemonic>"
8765 [(set_attr "type" "fsgn")
8766 (set_attr "mode" "DF")])
8767
8768 (define_insn "*<code>extendsfxf2"
8769 [(set (match_operand:XF 0 "register_operand" "=f")
8770 (absneg:XF (float_extend:XF
8771 (match_operand:SF 1 "register_operand" "0"))))]
8772 "TARGET_80387"
8773 "f<absneg_mnemonic>"
8774 [(set_attr "type" "fsgn")
8775 (set_attr "mode" "XF")])
8776
8777 (define_insn "*<code>extenddfxf2"
8778 [(set (match_operand:XF 0 "register_operand" "=f")
8779 (absneg:XF (float_extend:XF
8780 (match_operand:DF 1 "register_operand" "0"))))]
8781 "TARGET_80387"
8782 "f<absneg_mnemonic>"
8783 [(set_attr "type" "fsgn")
8784 (set_attr "mode" "XF")])
8785
8786 ;; Copysign instructions
8787
8788 (define_mode_iterator CSGNMODE [SF DF TF])
8789 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8790
8791 (define_expand "copysign<mode>3"
8792 [(match_operand:CSGNMODE 0 "register_operand" "")
8793 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8794 (match_operand:CSGNMODE 2 "register_operand" "")]
8795 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8796 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8797 "ix86_expand_copysign (operands); DONE;")
8798
8799 (define_insn_and_split "copysign<mode>3_const"
8800 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8801 (unspec:CSGNMODE
8802 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8803 (match_operand:CSGNMODE 2 "register_operand" "0")
8804 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8805 UNSPEC_COPYSIGN))]
8806 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8807 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8808 "#"
8809 "&& reload_completed"
8810 [(const_int 0)]
8811 "ix86_split_copysign_const (operands); DONE;")
8812
8813 (define_insn "copysign<mode>3_var"
8814 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8815 (unspec:CSGNMODE
8816 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8817 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8818 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8819 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8820 UNSPEC_COPYSIGN))
8821 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8822 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8823 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8824 "#")
8825
8826 (define_split
8827 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8828 (unspec:CSGNMODE
8829 [(match_operand:CSGNMODE 2 "register_operand" "")
8830 (match_operand:CSGNMODE 3 "register_operand" "")
8831 (match_operand:<CSGNVMODE> 4 "" "")
8832 (match_operand:<CSGNVMODE> 5 "" "")]
8833 UNSPEC_COPYSIGN))
8834 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8835 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8836 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8837 && reload_completed"
8838 [(const_int 0)]
8839 "ix86_split_copysign_var (operands); DONE;")
8840 \f
8841 ;; One complement instructions
8842
8843 (define_expand "one_cmpl<mode>2"
8844 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8845 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8846 ""
8847 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8848
8849 (define_insn "*one_cmpl<mode>2_1"
8850 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8851 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8852 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8853 "not{<imodesuffix>}\t%0"
8854 [(set_attr "type" "negnot")
8855 (set_attr "mode" "<MODE>")])
8856
8857 ;; %%% Potential partial reg stall on alternative 1. What to do?
8858 (define_insn "*one_cmplqi2_1"
8859 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8860 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8861 "ix86_unary_operator_ok (NOT, QImode, operands)"
8862 "@
8863 not{b}\t%0
8864 not{l}\t%k0"
8865 [(set_attr "type" "negnot")
8866 (set_attr "mode" "QI,SI")])
8867
8868 ;; ??? Currently never generated - xor is used instead.
8869 (define_insn "*one_cmplsi2_1_zext"
8870 [(set (match_operand:DI 0 "register_operand" "=r")
8871 (zero_extend:DI
8872 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8873 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8874 "not{l}\t%k0"
8875 [(set_attr "type" "negnot")
8876 (set_attr "mode" "SI")])
8877
8878 (define_insn "*one_cmpl<mode>2_2"
8879 [(set (reg FLAGS_REG)
8880 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8881 (const_int 0)))
8882 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8883 (not:SWI (match_dup 1)))]
8884 "ix86_match_ccmode (insn, CCNOmode)
8885 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8886 "#"
8887 [(set_attr "type" "alu1")
8888 (set_attr "mode" "<MODE>")])
8889
8890 (define_split
8891 [(set (match_operand 0 "flags_reg_operand" "")
8892 (match_operator 2 "compare_operator"
8893 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8894 (const_int 0)]))
8895 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8896 (not:SWI (match_dup 3)))]
8897 "ix86_match_ccmode (insn, CCNOmode)"
8898 [(parallel [(set (match_dup 0)
8899 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8900 (const_int 0)]))
8901 (set (match_dup 1)
8902 (xor:SWI (match_dup 3) (const_int -1)))])])
8903
8904 ;; ??? Currently never generated - xor is used instead.
8905 (define_insn "*one_cmplsi2_2_zext"
8906 [(set (reg FLAGS_REG)
8907 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8908 (const_int 0)))
8909 (set (match_operand:DI 0 "register_operand" "=r")
8910 (zero_extend:DI (not:SI (match_dup 1))))]
8911 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8912 && ix86_unary_operator_ok (NOT, SImode, operands)"
8913 "#"
8914 [(set_attr "type" "alu1")
8915 (set_attr "mode" "SI")])
8916
8917 (define_split
8918 [(set (match_operand 0 "flags_reg_operand" "")
8919 (match_operator 2 "compare_operator"
8920 [(not:SI (match_operand:SI 3 "register_operand" ""))
8921 (const_int 0)]))
8922 (set (match_operand:DI 1 "register_operand" "")
8923 (zero_extend:DI (not:SI (match_dup 3))))]
8924 "ix86_match_ccmode (insn, CCNOmode)"
8925 [(parallel [(set (match_dup 0)
8926 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8927 (const_int 0)]))
8928 (set (match_dup 1)
8929 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8930 \f
8931 ;; Shift instructions
8932
8933 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8934 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8935 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8936 ;; from the assembler input.
8937 ;;
8938 ;; This instruction shifts the target reg/mem as usual, but instead of
8939 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8940 ;; is a left shift double, bits are taken from the high order bits of
8941 ;; reg, else if the insn is a shift right double, bits are taken from the
8942 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8943 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8944 ;;
8945 ;; Since sh[lr]d does not change the `reg' operand, that is done
8946 ;; separately, making all shifts emit pairs of shift double and normal
8947 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8948 ;; support a 63 bit shift, each shift where the count is in a reg expands
8949 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8950 ;;
8951 ;; If the shift count is a constant, we need never emit more than one
8952 ;; shift pair, instead using moves and sign extension for counts greater
8953 ;; than 31.
8954
8955 (define_expand "ashl<mode>3"
8956 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8957 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8958 (match_operand:QI 2 "nonmemory_operand" "")))]
8959 ""
8960 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8961
8962 (define_insn "*ashl<mode>3_doubleword"
8963 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8964 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8965 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8966 (clobber (reg:CC FLAGS_REG))]
8967 ""
8968 "#"
8969 [(set_attr "type" "multi")])
8970
8971 (define_split
8972 [(set (match_operand:DWI 0 "register_operand" "")
8973 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8974 (match_operand:QI 2 "nonmemory_operand" "")))
8975 (clobber (reg:CC FLAGS_REG))]
8976 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8977 [(const_int 0)]
8978 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8979
8980 ;; By default we don't ask for a scratch register, because when DWImode
8981 ;; values are manipulated, registers are already at a premium. But if
8982 ;; we have one handy, we won't turn it away.
8983
8984 (define_peephole2
8985 [(match_scratch:DWIH 3 "r")
8986 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8987 (ashift:<DWI>
8988 (match_operand:<DWI> 1 "nonmemory_operand" "")
8989 (match_operand:QI 2 "nonmemory_operand" "")))
8990 (clobber (reg:CC FLAGS_REG))])
8991 (match_dup 3)]
8992 "TARGET_CMOVE"
8993 [(const_int 0)]
8994 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8995
8996 (define_insn "x86_64_shld"
8997 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8998 (ior:DI (ashift:DI (match_dup 0)
8999 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9000 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9001 (minus:QI (const_int 64) (match_dup 2)))))
9002 (clobber (reg:CC FLAGS_REG))]
9003 "TARGET_64BIT"
9004 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9005 [(set_attr "type" "ishift")
9006 (set_attr "prefix_0f" "1")
9007 (set_attr "mode" "DI")
9008 (set_attr "athlon_decode" "vector")
9009 (set_attr "amdfam10_decode" "vector")
9010 (set_attr "bdver1_decode" "vector")])
9011
9012 (define_insn "x86_shld"
9013 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9014 (ior:SI (ashift:SI (match_dup 0)
9015 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9016 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9017 (minus:QI (const_int 32) (match_dup 2)))))
9018 (clobber (reg:CC FLAGS_REG))]
9019 ""
9020 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9021 [(set_attr "type" "ishift")
9022 (set_attr "prefix_0f" "1")
9023 (set_attr "mode" "SI")
9024 (set_attr "pent_pair" "np")
9025 (set_attr "athlon_decode" "vector")
9026 (set_attr "amdfam10_decode" "vector")
9027 (set_attr "bdver1_decode" "vector")])
9028
9029 (define_expand "x86_shift<mode>_adj_1"
9030 [(set (reg:CCZ FLAGS_REG)
9031 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9032 (match_dup 4))
9033 (const_int 0)))
9034 (set (match_operand:SWI48 0 "register_operand" "")
9035 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9036 (match_operand:SWI48 1 "register_operand" "")
9037 (match_dup 0)))
9038 (set (match_dup 1)
9039 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9040 (match_operand:SWI48 3 "register_operand" "r")
9041 (match_dup 1)))]
9042 "TARGET_CMOVE"
9043 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9044
9045 (define_expand "x86_shift<mode>_adj_2"
9046 [(use (match_operand:SWI48 0 "register_operand" ""))
9047 (use (match_operand:SWI48 1 "register_operand" ""))
9048 (use (match_operand:QI 2 "register_operand" ""))]
9049 ""
9050 {
9051 rtx label = gen_label_rtx ();
9052 rtx tmp;
9053
9054 emit_insn (gen_testqi_ccz_1 (operands[2],
9055 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9056
9057 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9058 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9059 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9060 gen_rtx_LABEL_REF (VOIDmode, label),
9061 pc_rtx);
9062 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9063 JUMP_LABEL (tmp) = label;
9064
9065 emit_move_insn (operands[0], operands[1]);
9066 ix86_expand_clear (operands[1]);
9067
9068 emit_label (label);
9069 LABEL_NUSES (label) = 1;
9070
9071 DONE;
9072 })
9073
9074 ;; Avoid useless masking of count operand.
9075 (define_insn_and_split "*ashl<mode>3_mask"
9076 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9077 (ashift:SWI48
9078 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9079 (subreg:QI
9080 (and:SI
9081 (match_operand:SI 2 "nonimmediate_operand" "c")
9082 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9083 (clobber (reg:CC FLAGS_REG))]
9084 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9085 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9086 == GET_MODE_BITSIZE (<MODE>mode)-1"
9087 "#"
9088 "&& 1"
9089 [(parallel [(set (match_dup 0)
9090 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9091 (clobber (reg:CC FLAGS_REG))])]
9092 {
9093 if (can_create_pseudo_p ())
9094 operands [2] = force_reg (SImode, operands[2]);
9095
9096 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9097 }
9098 [(set_attr "type" "ishift")
9099 (set_attr "mode" "<MODE>")])
9100
9101 (define_insn "*bmi2_ashl<mode>3_1"
9102 [(set (match_operand:SWI48 0 "register_operand" "=r")
9103 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9104 (match_operand:SWI48 2 "register_operand" "r")))]
9105 "TARGET_BMI2"
9106 "shlx\t{%2, %1, %0|%0, %1, %2}"
9107 [(set_attr "type" "ishiftx")
9108 (set_attr "mode" "<MODE>")])
9109
9110 (define_insn "*ashl<mode>3_1"
9111 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9112 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9113 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9114 (clobber (reg:CC FLAGS_REG))]
9115 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9116 {
9117 switch (get_attr_type (insn))
9118 {
9119 case TYPE_LEA:
9120 case TYPE_ISHIFTX:
9121 return "#";
9122
9123 case TYPE_ALU:
9124 gcc_assert (operands[2] == const1_rtx);
9125 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9126 return "add{<imodesuffix>}\t%0, %0";
9127
9128 default:
9129 if (operands[2] == const1_rtx
9130 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9131 return "sal{<imodesuffix>}\t%0";
9132 else
9133 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9134 }
9135 }
9136 [(set_attr "isa" "*,*,bmi2")
9137 (set (attr "type")
9138 (cond [(eq_attr "alternative" "1")
9139 (const_string "lea")
9140 (eq_attr "alternative" "2")
9141 (const_string "ishiftx")
9142 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9143 (match_operand 0 "register_operand" ""))
9144 (match_operand 2 "const1_operand" ""))
9145 (const_string "alu")
9146 ]
9147 (const_string "ishift")))
9148 (set (attr "length_immediate")
9149 (if_then_else
9150 (ior (eq_attr "type" "alu")
9151 (and (eq_attr "type" "ishift")
9152 (and (match_operand 2 "const1_operand" "")
9153 (ior (match_test "TARGET_SHIFT1")
9154 (match_test "optimize_function_for_size_p (cfun)")))))
9155 (const_string "0")
9156 (const_string "*")))
9157 (set_attr "mode" "<MODE>")])
9158
9159 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9160 (define_split
9161 [(set (match_operand:SWI48 0 "register_operand" "")
9162 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9163 (match_operand:QI 2 "register_operand" "")))
9164 (clobber (reg:CC FLAGS_REG))]
9165 "TARGET_BMI2 && reload_completed"
9166 [(set (match_dup 0)
9167 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9168 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9169
9170 (define_insn "*bmi2_ashlsi3_1_zext"
9171 [(set (match_operand:DI 0 "register_operand" "=r")
9172 (zero_extend:DI
9173 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9174 (match_operand:SI 2 "register_operand" "r"))))]
9175 "TARGET_64BIT && TARGET_BMI2"
9176 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9177 [(set_attr "type" "ishiftx")
9178 (set_attr "mode" "SI")])
9179
9180 (define_insn "*ashlsi3_1_zext"
9181 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9182 (zero_extend:DI
9183 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9184 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9185 (clobber (reg:CC FLAGS_REG))]
9186 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9187 {
9188 switch (get_attr_type (insn))
9189 {
9190 case TYPE_LEA:
9191 case TYPE_ISHIFTX:
9192 return "#";
9193
9194 case TYPE_ALU:
9195 gcc_assert (operands[2] == const1_rtx);
9196 return "add{l}\t%k0, %k0";
9197
9198 default:
9199 if (operands[2] == const1_rtx
9200 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9201 return "sal{l}\t%k0";
9202 else
9203 return "sal{l}\t{%2, %k0|%k0, %2}";
9204 }
9205 }
9206 [(set_attr "isa" "*,*,bmi2")
9207 (set (attr "type")
9208 (cond [(eq_attr "alternative" "1")
9209 (const_string "lea")
9210 (eq_attr "alternative" "2")
9211 (const_string "ishiftx")
9212 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9213 (match_operand 2 "const1_operand" ""))
9214 (const_string "alu")
9215 ]
9216 (const_string "ishift")))
9217 (set (attr "length_immediate")
9218 (if_then_else
9219 (ior (eq_attr "type" "alu")
9220 (and (eq_attr "type" "ishift")
9221 (and (match_operand 2 "const1_operand" "")
9222 (ior (match_test "TARGET_SHIFT1")
9223 (match_test "optimize_function_for_size_p (cfun)")))))
9224 (const_string "0")
9225 (const_string "*")))
9226 (set_attr "mode" "SI")])
9227
9228 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9229 (define_split
9230 [(set (match_operand:DI 0 "register_operand" "")
9231 (zero_extend:DI
9232 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9233 (match_operand:QI 2 "register_operand" ""))))
9234 (clobber (reg:CC FLAGS_REG))]
9235 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9236 [(set (match_dup 0)
9237 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9238 "operands[2] = gen_lowpart (SImode, operands[2]);")
9239
9240 (define_insn "*ashlhi3_1"
9241 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9242 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9243 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9244 (clobber (reg:CC FLAGS_REG))]
9245 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9246 {
9247 switch (get_attr_type (insn))
9248 {
9249 case TYPE_LEA:
9250 return "#";
9251
9252 case TYPE_ALU:
9253 gcc_assert (operands[2] == const1_rtx);
9254 return "add{w}\t%0, %0";
9255
9256 default:
9257 if (operands[2] == const1_rtx
9258 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9259 return "sal{w}\t%0";
9260 else
9261 return "sal{w}\t{%2, %0|%0, %2}";
9262 }
9263 }
9264 [(set (attr "type")
9265 (cond [(eq_attr "alternative" "1")
9266 (const_string "lea")
9267 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9268 (match_operand 0 "register_operand" ""))
9269 (match_operand 2 "const1_operand" ""))
9270 (const_string "alu")
9271 ]
9272 (const_string "ishift")))
9273 (set (attr "length_immediate")
9274 (if_then_else
9275 (ior (eq_attr "type" "alu")
9276 (and (eq_attr "type" "ishift")
9277 (and (match_operand 2 "const1_operand" "")
9278 (ior (match_test "TARGET_SHIFT1")
9279 (match_test "optimize_function_for_size_p (cfun)")))))
9280 (const_string "0")
9281 (const_string "*")))
9282 (set_attr "mode" "HI,SI")])
9283
9284 ;; %%% Potential partial reg stall on alternative 1. What to do?
9285 (define_insn "*ashlqi3_1"
9286 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9287 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9288 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9289 (clobber (reg:CC FLAGS_REG))]
9290 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9291 {
9292 switch (get_attr_type (insn))
9293 {
9294 case TYPE_LEA:
9295 return "#";
9296
9297 case TYPE_ALU:
9298 gcc_assert (operands[2] == const1_rtx);
9299 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9300 return "add{l}\t%k0, %k0";
9301 else
9302 return "add{b}\t%0, %0";
9303
9304 default:
9305 if (operands[2] == const1_rtx
9306 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9307 {
9308 if (get_attr_mode (insn) == MODE_SI)
9309 return "sal{l}\t%k0";
9310 else
9311 return "sal{b}\t%0";
9312 }
9313 else
9314 {
9315 if (get_attr_mode (insn) == MODE_SI)
9316 return "sal{l}\t{%2, %k0|%k0, %2}";
9317 else
9318 return "sal{b}\t{%2, %0|%0, %2}";
9319 }
9320 }
9321 }
9322 [(set (attr "type")
9323 (cond [(eq_attr "alternative" "2")
9324 (const_string "lea")
9325 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9326 (match_operand 0 "register_operand" ""))
9327 (match_operand 2 "const1_operand" ""))
9328 (const_string "alu")
9329 ]
9330 (const_string "ishift")))
9331 (set (attr "length_immediate")
9332 (if_then_else
9333 (ior (eq_attr "type" "alu")
9334 (and (eq_attr "type" "ishift")
9335 (and (match_operand 2 "const1_operand" "")
9336 (ior (match_test "TARGET_SHIFT1")
9337 (match_test "optimize_function_for_size_p (cfun)")))))
9338 (const_string "0")
9339 (const_string "*")))
9340 (set_attr "mode" "QI,SI,SI")])
9341
9342 (define_insn "*ashlqi3_1_slp"
9343 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9344 (ashift:QI (match_dup 0)
9345 (match_operand:QI 1 "nonmemory_operand" "cI")))
9346 (clobber (reg:CC FLAGS_REG))]
9347 "(optimize_function_for_size_p (cfun)
9348 || !TARGET_PARTIAL_FLAG_REG_STALL
9349 || (operands[1] == const1_rtx
9350 && (TARGET_SHIFT1
9351 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9352 {
9353 switch (get_attr_type (insn))
9354 {
9355 case TYPE_ALU:
9356 gcc_assert (operands[1] == const1_rtx);
9357 return "add{b}\t%0, %0";
9358
9359 default:
9360 if (operands[1] == const1_rtx
9361 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9362 return "sal{b}\t%0";
9363 else
9364 return "sal{b}\t{%1, %0|%0, %1}";
9365 }
9366 }
9367 [(set (attr "type")
9368 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9369 (match_operand 0 "register_operand" ""))
9370 (match_operand 1 "const1_operand" ""))
9371 (const_string "alu")
9372 ]
9373 (const_string "ishift1")))
9374 (set (attr "length_immediate")
9375 (if_then_else
9376 (ior (eq_attr "type" "alu")
9377 (and (eq_attr "type" "ishift1")
9378 (and (match_operand 1 "const1_operand" "")
9379 (ior (match_test "TARGET_SHIFT1")
9380 (match_test "optimize_function_for_size_p (cfun)")))))
9381 (const_string "0")
9382 (const_string "*")))
9383 (set_attr "mode" "QI")])
9384
9385 ;; Convert ashift to the lea pattern to avoid flags dependency.
9386 (define_split
9387 [(set (match_operand 0 "register_operand" "")
9388 (ashift (match_operand 1 "index_register_operand" "")
9389 (match_operand:QI 2 "const_int_operand" "")))
9390 (clobber (reg:CC FLAGS_REG))]
9391 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9392 && reload_completed
9393 && true_regnum (operands[0]) != true_regnum (operands[1])"
9394 [(const_int 0)]
9395 {
9396 enum machine_mode mode = GET_MODE (operands[0]);
9397 rtx pat;
9398
9399 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9400 {
9401 mode = SImode;
9402 operands[0] = gen_lowpart (mode, operands[0]);
9403 operands[1] = gen_lowpart (mode, operands[1]);
9404 }
9405
9406 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9407
9408 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9409
9410 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9411 DONE;
9412 })
9413
9414 ;; Convert ashift to the lea pattern to avoid flags dependency.
9415 (define_split
9416 [(set (match_operand:DI 0 "register_operand" "")
9417 (zero_extend:DI
9418 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9419 (match_operand:QI 2 "const_int_operand" ""))))
9420 (clobber (reg:CC FLAGS_REG))]
9421 "TARGET_64BIT && reload_completed
9422 && true_regnum (operands[0]) != true_regnum (operands[1])"
9423 [(set (match_dup 0)
9424 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9425 {
9426 operands[1] = gen_lowpart (DImode, operands[1]);
9427 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9428 })
9429
9430 ;; This pattern can't accept a variable shift count, since shifts by
9431 ;; zero don't affect the flags. We assume that shifts by constant
9432 ;; zero are optimized away.
9433 (define_insn "*ashl<mode>3_cmp"
9434 [(set (reg FLAGS_REG)
9435 (compare
9436 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9437 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9438 (const_int 0)))
9439 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9440 (ashift:SWI (match_dup 1) (match_dup 2)))]
9441 "(optimize_function_for_size_p (cfun)
9442 || !TARGET_PARTIAL_FLAG_REG_STALL
9443 || (operands[2] == const1_rtx
9444 && (TARGET_SHIFT1
9445 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9446 && ix86_match_ccmode (insn, CCGOCmode)
9447 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9448 {
9449 switch (get_attr_type (insn))
9450 {
9451 case TYPE_ALU:
9452 gcc_assert (operands[2] == const1_rtx);
9453 return "add{<imodesuffix>}\t%0, %0";
9454
9455 default:
9456 if (operands[2] == const1_rtx
9457 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9458 return "sal{<imodesuffix>}\t%0";
9459 else
9460 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9461 }
9462 }
9463 [(set (attr "type")
9464 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9465 (match_operand 0 "register_operand" ""))
9466 (match_operand 2 "const1_operand" ""))
9467 (const_string "alu")
9468 ]
9469 (const_string "ishift")))
9470 (set (attr "length_immediate")
9471 (if_then_else
9472 (ior (eq_attr "type" "alu")
9473 (and (eq_attr "type" "ishift")
9474 (and (match_operand 2 "const1_operand" "")
9475 (ior (match_test "TARGET_SHIFT1")
9476 (match_test "optimize_function_for_size_p (cfun)")))))
9477 (const_string "0")
9478 (const_string "*")))
9479 (set_attr "mode" "<MODE>")])
9480
9481 (define_insn "*ashlsi3_cmp_zext"
9482 [(set (reg FLAGS_REG)
9483 (compare
9484 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9485 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9486 (const_int 0)))
9487 (set (match_operand:DI 0 "register_operand" "=r")
9488 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9489 "TARGET_64BIT
9490 && (optimize_function_for_size_p (cfun)
9491 || !TARGET_PARTIAL_FLAG_REG_STALL
9492 || (operands[2] == const1_rtx
9493 && (TARGET_SHIFT1
9494 || TARGET_DOUBLE_WITH_ADD)))
9495 && ix86_match_ccmode (insn, CCGOCmode)
9496 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9497 {
9498 switch (get_attr_type (insn))
9499 {
9500 case TYPE_ALU:
9501 gcc_assert (operands[2] == const1_rtx);
9502 return "add{l}\t%k0, %k0";
9503
9504 default:
9505 if (operands[2] == const1_rtx
9506 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9507 return "sal{l}\t%k0";
9508 else
9509 return "sal{l}\t{%2, %k0|%k0, %2}";
9510 }
9511 }
9512 [(set (attr "type")
9513 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9514 (match_operand 2 "const1_operand" ""))
9515 (const_string "alu")
9516 ]
9517 (const_string "ishift")))
9518 (set (attr "length_immediate")
9519 (if_then_else
9520 (ior (eq_attr "type" "alu")
9521 (and (eq_attr "type" "ishift")
9522 (and (match_operand 2 "const1_operand" "")
9523 (ior (match_test "TARGET_SHIFT1")
9524 (match_test "optimize_function_for_size_p (cfun)")))))
9525 (const_string "0")
9526 (const_string "*")))
9527 (set_attr "mode" "SI")])
9528
9529 (define_insn "*ashl<mode>3_cconly"
9530 [(set (reg FLAGS_REG)
9531 (compare
9532 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9533 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9534 (const_int 0)))
9535 (clobber (match_scratch:SWI 0 "=<r>"))]
9536 "(optimize_function_for_size_p (cfun)
9537 || !TARGET_PARTIAL_FLAG_REG_STALL
9538 || (operands[2] == const1_rtx
9539 && (TARGET_SHIFT1
9540 || TARGET_DOUBLE_WITH_ADD)))
9541 && ix86_match_ccmode (insn, CCGOCmode)"
9542 {
9543 switch (get_attr_type (insn))
9544 {
9545 case TYPE_ALU:
9546 gcc_assert (operands[2] == const1_rtx);
9547 return "add{<imodesuffix>}\t%0, %0";
9548
9549 default:
9550 if (operands[2] == const1_rtx
9551 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9552 return "sal{<imodesuffix>}\t%0";
9553 else
9554 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9555 }
9556 }
9557 [(set (attr "type")
9558 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9559 (match_operand 0 "register_operand" ""))
9560 (match_operand 2 "const1_operand" ""))
9561 (const_string "alu")
9562 ]
9563 (const_string "ishift")))
9564 (set (attr "length_immediate")
9565 (if_then_else
9566 (ior (eq_attr "type" "alu")
9567 (and (eq_attr "type" "ishift")
9568 (and (match_operand 2 "const1_operand" "")
9569 (ior (match_test "TARGET_SHIFT1")
9570 (match_test "optimize_function_for_size_p (cfun)")))))
9571 (const_string "0")
9572 (const_string "*")))
9573 (set_attr "mode" "<MODE>")])
9574
9575 ;; See comment above `ashl<mode>3' about how this works.
9576
9577 (define_expand "<shift_insn><mode>3"
9578 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9579 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9580 (match_operand:QI 2 "nonmemory_operand" "")))]
9581 ""
9582 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9583
9584 ;; Avoid useless masking of count operand.
9585 (define_insn_and_split "*<shift_insn><mode>3_mask"
9586 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9587 (any_shiftrt:SWI48
9588 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9589 (subreg:QI
9590 (and:SI
9591 (match_operand:SI 2 "nonimmediate_operand" "c")
9592 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9593 (clobber (reg:CC FLAGS_REG))]
9594 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9595 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9596 == GET_MODE_BITSIZE (<MODE>mode)-1"
9597 "#"
9598 "&& 1"
9599 [(parallel [(set (match_dup 0)
9600 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9601 (clobber (reg:CC FLAGS_REG))])]
9602 {
9603 if (can_create_pseudo_p ())
9604 operands [2] = force_reg (SImode, operands[2]);
9605
9606 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9607 }
9608 [(set_attr "type" "ishift")
9609 (set_attr "mode" "<MODE>")])
9610
9611 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9612 [(set (match_operand:DWI 0 "register_operand" "=r")
9613 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9614 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9615 (clobber (reg:CC FLAGS_REG))]
9616 ""
9617 "#"
9618 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9619 [(const_int 0)]
9620 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9621 [(set_attr "type" "multi")])
9622
9623 ;; By default we don't ask for a scratch register, because when DWImode
9624 ;; values are manipulated, registers are already at a premium. But if
9625 ;; we have one handy, we won't turn it away.
9626
9627 (define_peephole2
9628 [(match_scratch:DWIH 3 "r")
9629 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9630 (any_shiftrt:<DWI>
9631 (match_operand:<DWI> 1 "register_operand" "")
9632 (match_operand:QI 2 "nonmemory_operand" "")))
9633 (clobber (reg:CC FLAGS_REG))])
9634 (match_dup 3)]
9635 "TARGET_CMOVE"
9636 [(const_int 0)]
9637 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9638
9639 (define_insn "x86_64_shrd"
9640 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9641 (ior:DI (ashiftrt:DI (match_dup 0)
9642 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9643 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9644 (minus:QI (const_int 64) (match_dup 2)))))
9645 (clobber (reg:CC FLAGS_REG))]
9646 "TARGET_64BIT"
9647 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9648 [(set_attr "type" "ishift")
9649 (set_attr "prefix_0f" "1")
9650 (set_attr "mode" "DI")
9651 (set_attr "athlon_decode" "vector")
9652 (set_attr "amdfam10_decode" "vector")
9653 (set_attr "bdver1_decode" "vector")])
9654
9655 (define_insn "x86_shrd"
9656 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9657 (ior:SI (ashiftrt:SI (match_dup 0)
9658 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9659 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9660 (minus:QI (const_int 32) (match_dup 2)))))
9661 (clobber (reg:CC FLAGS_REG))]
9662 ""
9663 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9664 [(set_attr "type" "ishift")
9665 (set_attr "prefix_0f" "1")
9666 (set_attr "mode" "SI")
9667 (set_attr "pent_pair" "np")
9668 (set_attr "athlon_decode" "vector")
9669 (set_attr "amdfam10_decode" "vector")
9670 (set_attr "bdver1_decode" "vector")])
9671
9672 (define_insn "ashrdi3_cvt"
9673 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9674 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9675 (match_operand:QI 2 "const_int_operand" "")))
9676 (clobber (reg:CC FLAGS_REG))]
9677 "TARGET_64BIT && INTVAL (operands[2]) == 63
9678 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9679 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9680 "@
9681 {cqto|cqo}
9682 sar{q}\t{%2, %0|%0, %2}"
9683 [(set_attr "type" "imovx,ishift")
9684 (set_attr "prefix_0f" "0,*")
9685 (set_attr "length_immediate" "0,*")
9686 (set_attr "modrm" "0,1")
9687 (set_attr "mode" "DI")])
9688
9689 (define_insn "ashrsi3_cvt"
9690 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9691 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9692 (match_operand:QI 2 "const_int_operand" "")))
9693 (clobber (reg:CC FLAGS_REG))]
9694 "INTVAL (operands[2]) == 31
9695 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9696 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9697 "@
9698 {cltd|cdq}
9699 sar{l}\t{%2, %0|%0, %2}"
9700 [(set_attr "type" "imovx,ishift")
9701 (set_attr "prefix_0f" "0,*")
9702 (set_attr "length_immediate" "0,*")
9703 (set_attr "modrm" "0,1")
9704 (set_attr "mode" "SI")])
9705
9706 (define_insn "*ashrsi3_cvt_zext"
9707 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9708 (zero_extend:DI
9709 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9710 (match_operand:QI 2 "const_int_operand" ""))))
9711 (clobber (reg:CC FLAGS_REG))]
9712 "TARGET_64BIT && INTVAL (operands[2]) == 31
9713 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9714 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9715 "@
9716 {cltd|cdq}
9717 sar{l}\t{%2, %k0|%k0, %2}"
9718 [(set_attr "type" "imovx,ishift")
9719 (set_attr "prefix_0f" "0,*")
9720 (set_attr "length_immediate" "0,*")
9721 (set_attr "modrm" "0,1")
9722 (set_attr "mode" "SI")])
9723
9724 (define_expand "x86_shift<mode>_adj_3"
9725 [(use (match_operand:SWI48 0 "register_operand" ""))
9726 (use (match_operand:SWI48 1 "register_operand" ""))
9727 (use (match_operand:QI 2 "register_operand" ""))]
9728 ""
9729 {
9730 rtx label = gen_label_rtx ();
9731 rtx tmp;
9732
9733 emit_insn (gen_testqi_ccz_1 (operands[2],
9734 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9735
9736 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9737 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9738 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9739 gen_rtx_LABEL_REF (VOIDmode, label),
9740 pc_rtx);
9741 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9742 JUMP_LABEL (tmp) = label;
9743
9744 emit_move_insn (operands[0], operands[1]);
9745 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9746 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9747 emit_label (label);
9748 LABEL_NUSES (label) = 1;
9749
9750 DONE;
9751 })
9752
9753 (define_insn "*bmi2_<shift_insn><mode>3_1"
9754 [(set (match_operand:SWI48 0 "register_operand" "=r")
9755 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9756 (match_operand:SWI48 2 "register_operand" "r")))]
9757 "TARGET_BMI2"
9758 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9759 [(set_attr "type" "ishiftx")
9760 (set_attr "mode" "<MODE>")])
9761
9762 (define_insn "*<shift_insn><mode>3_1"
9763 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9764 (any_shiftrt:SWI48
9765 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9766 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9767 (clobber (reg:CC FLAGS_REG))]
9768 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9769 {
9770 switch (get_attr_type (insn))
9771 {
9772 case TYPE_ISHIFTX:
9773 return "#";
9774
9775 default:
9776 if (operands[2] == const1_rtx
9777 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9778 return "<shift>{<imodesuffix>}\t%0";
9779 else
9780 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9781 }
9782 }
9783 [(set_attr "isa" "*,bmi2")
9784 (set_attr "type" "ishift,ishiftx")
9785 (set (attr "length_immediate")
9786 (if_then_else
9787 (and (match_operand 2 "const1_operand" "")
9788 (ior (match_test "TARGET_SHIFT1")
9789 (match_test "optimize_function_for_size_p (cfun)")))
9790 (const_string "0")
9791 (const_string "*")))
9792 (set_attr "mode" "<MODE>")])
9793
9794 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9795 (define_split
9796 [(set (match_operand:SWI48 0 "register_operand" "")
9797 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9798 (match_operand:QI 2 "register_operand" "")))
9799 (clobber (reg:CC FLAGS_REG))]
9800 "TARGET_BMI2 && reload_completed"
9801 [(set (match_dup 0)
9802 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9803 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9804
9805 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9806 [(set (match_operand:DI 0 "register_operand" "=r")
9807 (zero_extend:DI
9808 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9809 (match_operand:SI 2 "register_operand" "r"))))]
9810 "TARGET_64BIT && TARGET_BMI2"
9811 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9812 [(set_attr "type" "ishiftx")
9813 (set_attr "mode" "SI")])
9814
9815 (define_insn "*<shift_insn>si3_1_zext"
9816 [(set (match_operand:DI 0 "register_operand" "=r,r")
9817 (zero_extend:DI
9818 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9819 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9820 (clobber (reg:CC FLAGS_REG))]
9821 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9822 {
9823 switch (get_attr_type (insn))
9824 {
9825 case TYPE_ISHIFTX:
9826 return "#";
9827
9828 default:
9829 if (operands[2] == const1_rtx
9830 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9831 return "<shift>{l}\t%k0";
9832 else
9833 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9834 }
9835 }
9836 [(set_attr "isa" "*,bmi2")
9837 (set_attr "type" "ishift,ishiftx")
9838 (set (attr "length_immediate")
9839 (if_then_else
9840 (and (match_operand 2 "const1_operand" "")
9841 (ior (match_test "TARGET_SHIFT1")
9842 (match_test "optimize_function_for_size_p (cfun)")))
9843 (const_string "0")
9844 (const_string "*")))
9845 (set_attr "mode" "SI")])
9846
9847 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9848 (define_split
9849 [(set (match_operand:DI 0 "register_operand" "")
9850 (zero_extend:DI
9851 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9852 (match_operand:QI 2 "register_operand" ""))))
9853 (clobber (reg:CC FLAGS_REG))]
9854 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9855 [(set (match_dup 0)
9856 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9857 "operands[2] = gen_lowpart (SImode, operands[2]);")
9858
9859 (define_insn "*<shift_insn><mode>3_1"
9860 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9861 (any_shiftrt:SWI12
9862 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9863 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9864 (clobber (reg:CC FLAGS_REG))]
9865 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9866 {
9867 if (operands[2] == const1_rtx
9868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9869 return "<shift>{<imodesuffix>}\t%0";
9870 else
9871 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9872 }
9873 [(set_attr "type" "ishift")
9874 (set (attr "length_immediate")
9875 (if_then_else
9876 (and (match_operand 2 "const1_operand" "")
9877 (ior (match_test "TARGET_SHIFT1")
9878 (match_test "optimize_function_for_size_p (cfun)")))
9879 (const_string "0")
9880 (const_string "*")))
9881 (set_attr "mode" "<MODE>")])
9882
9883 (define_insn "*<shift_insn>qi3_1_slp"
9884 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9885 (any_shiftrt:QI (match_dup 0)
9886 (match_operand:QI 1 "nonmemory_operand" "cI")))
9887 (clobber (reg:CC FLAGS_REG))]
9888 "(optimize_function_for_size_p (cfun)
9889 || !TARGET_PARTIAL_REG_STALL
9890 || (operands[1] == const1_rtx
9891 && TARGET_SHIFT1))"
9892 {
9893 if (operands[1] == const1_rtx
9894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9895 return "<shift>{b}\t%0";
9896 else
9897 return "<shift>{b}\t{%1, %0|%0, %1}";
9898 }
9899 [(set_attr "type" "ishift1")
9900 (set (attr "length_immediate")
9901 (if_then_else
9902 (and (match_operand 1 "const1_operand" "")
9903 (ior (match_test "TARGET_SHIFT1")
9904 (match_test "optimize_function_for_size_p (cfun)")))
9905 (const_string "0")
9906 (const_string "*")))
9907 (set_attr "mode" "QI")])
9908
9909 ;; This pattern can't accept a variable shift count, since shifts by
9910 ;; zero don't affect the flags. We assume that shifts by constant
9911 ;; zero are optimized away.
9912 (define_insn "*<shift_insn><mode>3_cmp"
9913 [(set (reg FLAGS_REG)
9914 (compare
9915 (any_shiftrt:SWI
9916 (match_operand:SWI 1 "nonimmediate_operand" "0")
9917 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9918 (const_int 0)))
9919 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9920 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9921 "(optimize_function_for_size_p (cfun)
9922 || !TARGET_PARTIAL_FLAG_REG_STALL
9923 || (operands[2] == const1_rtx
9924 && TARGET_SHIFT1))
9925 && ix86_match_ccmode (insn, CCGOCmode)
9926 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9927 {
9928 if (operands[2] == const1_rtx
9929 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9930 return "<shift>{<imodesuffix>}\t%0";
9931 else
9932 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9933 }
9934 [(set_attr "type" "ishift")
9935 (set (attr "length_immediate")
9936 (if_then_else
9937 (and (match_operand 2 "const1_operand" "")
9938 (ior (match_test "TARGET_SHIFT1")
9939 (match_test "optimize_function_for_size_p (cfun)")))
9940 (const_string "0")
9941 (const_string "*")))
9942 (set_attr "mode" "<MODE>")])
9943
9944 (define_insn "*<shift_insn>si3_cmp_zext"
9945 [(set (reg FLAGS_REG)
9946 (compare
9947 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9948 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9949 (const_int 0)))
9950 (set (match_operand:DI 0 "register_operand" "=r")
9951 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9952 "TARGET_64BIT
9953 && (optimize_function_for_size_p (cfun)
9954 || !TARGET_PARTIAL_FLAG_REG_STALL
9955 || (operands[2] == const1_rtx
9956 && TARGET_SHIFT1))
9957 && ix86_match_ccmode (insn, CCGOCmode)
9958 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9959 {
9960 if (operands[2] == const1_rtx
9961 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9962 return "<shift>{l}\t%k0";
9963 else
9964 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9965 }
9966 [(set_attr "type" "ishift")
9967 (set (attr "length_immediate")
9968 (if_then_else
9969 (and (match_operand 2 "const1_operand" "")
9970 (ior (match_test "TARGET_SHIFT1")
9971 (match_test "optimize_function_for_size_p (cfun)")))
9972 (const_string "0")
9973 (const_string "*")))
9974 (set_attr "mode" "SI")])
9975
9976 (define_insn "*<shift_insn><mode>3_cconly"
9977 [(set (reg FLAGS_REG)
9978 (compare
9979 (any_shiftrt:SWI
9980 (match_operand:SWI 1 "register_operand" "0")
9981 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9982 (const_int 0)))
9983 (clobber (match_scratch:SWI 0 "=<r>"))]
9984 "(optimize_function_for_size_p (cfun)
9985 || !TARGET_PARTIAL_FLAG_REG_STALL
9986 || (operands[2] == const1_rtx
9987 && TARGET_SHIFT1))
9988 && ix86_match_ccmode (insn, CCGOCmode)"
9989 {
9990 if (operands[2] == const1_rtx
9991 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9992 return "<shift>{<imodesuffix>}\t%0";
9993 else
9994 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9995 }
9996 [(set_attr "type" "ishift")
9997 (set (attr "length_immediate")
9998 (if_then_else
9999 (and (match_operand 2 "const1_operand" "")
10000 (ior (match_test "TARGET_SHIFT1")
10001 (match_test "optimize_function_for_size_p (cfun)")))
10002 (const_string "0")
10003 (const_string "*")))
10004 (set_attr "mode" "<MODE>")])
10005 \f
10006 ;; Rotate instructions
10007
10008 (define_expand "<rotate_insn>ti3"
10009 [(set (match_operand:TI 0 "register_operand" "")
10010 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10011 (match_operand:QI 2 "nonmemory_operand" "")))]
10012 "TARGET_64BIT"
10013 {
10014 if (const_1_to_63_operand (operands[2], VOIDmode))
10015 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10016 (operands[0], operands[1], operands[2]));
10017 else
10018 FAIL;
10019
10020 DONE;
10021 })
10022
10023 (define_expand "<rotate_insn>di3"
10024 [(set (match_operand:DI 0 "shiftdi_operand" "")
10025 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10026 (match_operand:QI 2 "nonmemory_operand" "")))]
10027 ""
10028 {
10029 if (TARGET_64BIT)
10030 ix86_expand_binary_operator (<CODE>, DImode, operands);
10031 else if (const_1_to_31_operand (operands[2], VOIDmode))
10032 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10033 (operands[0], operands[1], operands[2]));
10034 else
10035 FAIL;
10036
10037 DONE;
10038 })
10039
10040 (define_expand "<rotate_insn><mode>3"
10041 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10042 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10043 (match_operand:QI 2 "nonmemory_operand" "")))]
10044 ""
10045 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10046
10047 ;; Avoid useless masking of count operand.
10048 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10049 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10050 (any_rotate:SWI48
10051 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10052 (subreg:QI
10053 (and:SI
10054 (match_operand:SI 2 "nonimmediate_operand" "c")
10055 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10056 (clobber (reg:CC FLAGS_REG))]
10057 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10058 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10059 == GET_MODE_BITSIZE (<MODE>mode)-1"
10060 "#"
10061 "&& 1"
10062 [(parallel [(set (match_dup 0)
10063 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10064 (clobber (reg:CC FLAGS_REG))])]
10065 {
10066 if (can_create_pseudo_p ())
10067 operands [2] = force_reg (SImode, operands[2]);
10068
10069 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10070 }
10071 [(set_attr "type" "rotate")
10072 (set_attr "mode" "<MODE>")])
10073
10074 ;; Implement rotation using two double-precision
10075 ;; shift instructions and a scratch register.
10076
10077 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10078 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10079 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10080 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10081 (clobber (reg:CC FLAGS_REG))
10082 (clobber (match_scratch:DWIH 3 "=&r"))]
10083 ""
10084 "#"
10085 "reload_completed"
10086 [(set (match_dup 3) (match_dup 4))
10087 (parallel
10088 [(set (match_dup 4)
10089 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10090 (lshiftrt:DWIH (match_dup 5)
10091 (minus:QI (match_dup 6) (match_dup 2)))))
10092 (clobber (reg:CC FLAGS_REG))])
10093 (parallel
10094 [(set (match_dup 5)
10095 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10096 (lshiftrt:DWIH (match_dup 3)
10097 (minus:QI (match_dup 6) (match_dup 2)))))
10098 (clobber (reg:CC FLAGS_REG))])]
10099 {
10100 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10101
10102 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10103 })
10104
10105 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10106 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10107 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10108 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10109 (clobber (reg:CC FLAGS_REG))
10110 (clobber (match_scratch:DWIH 3 "=&r"))]
10111 ""
10112 "#"
10113 "reload_completed"
10114 [(set (match_dup 3) (match_dup 4))
10115 (parallel
10116 [(set (match_dup 4)
10117 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10118 (ashift:DWIH (match_dup 5)
10119 (minus:QI (match_dup 6) (match_dup 2)))))
10120 (clobber (reg:CC FLAGS_REG))])
10121 (parallel
10122 [(set (match_dup 5)
10123 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10124 (ashift:DWIH (match_dup 3)
10125 (minus:QI (match_dup 6) (match_dup 2)))))
10126 (clobber (reg:CC FLAGS_REG))])]
10127 {
10128 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10129
10130 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10131 })
10132
10133 (define_insn "*bmi2_rorx<mode>3_1"
10134 [(set (match_operand:SWI48 0 "register_operand" "=r")
10135 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10136 (match_operand:QI 2 "immediate_operand" "<S>")))]
10137 "TARGET_BMI2"
10138 "rorx\t{%2, %1, %0|%0, %1, %2}"
10139 [(set_attr "type" "rotatex")
10140 (set_attr "mode" "<MODE>")])
10141
10142 (define_insn "*<rotate_insn><mode>3_1"
10143 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10144 (any_rotate:SWI48
10145 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10146 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10147 (clobber (reg:CC FLAGS_REG))]
10148 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10149 {
10150 switch (get_attr_type (insn))
10151 {
10152 case TYPE_ROTATEX:
10153 return "#";
10154
10155 default:
10156 if (operands[2] == const1_rtx
10157 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10158 return "<rotate>{<imodesuffix>}\t%0";
10159 else
10160 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10161 }
10162 }
10163 [(set_attr "isa" "*,bmi2")
10164 (set_attr "type" "rotate,rotatex")
10165 (set (attr "length_immediate")
10166 (if_then_else
10167 (and (eq_attr "type" "rotate")
10168 (and (match_operand 2 "const1_operand" "")
10169 (ior (match_test "TARGET_SHIFT1")
10170 (match_test "optimize_function_for_size_p (cfun)"))))
10171 (const_string "0")
10172 (const_string "*")))
10173 (set_attr "mode" "<MODE>")])
10174
10175 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10176 (define_split
10177 [(set (match_operand:SWI48 0 "register_operand" "")
10178 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10179 (match_operand:QI 2 "immediate_operand" "")))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "TARGET_BMI2 && reload_completed"
10182 [(set (match_dup 0)
10183 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10184 {
10185 operands[2]
10186 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10187 })
10188
10189 (define_split
10190 [(set (match_operand:SWI48 0 "register_operand" "")
10191 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10192 (match_operand:QI 2 "immediate_operand" "")))
10193 (clobber (reg:CC FLAGS_REG))]
10194 "TARGET_BMI2 && reload_completed"
10195 [(set (match_dup 0)
10196 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10197
10198 (define_insn "*bmi2_rorxsi3_1_zext"
10199 [(set (match_operand:DI 0 "register_operand" "=r")
10200 (zero_extend:DI
10201 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10202 (match_operand:QI 2 "immediate_operand" "I"))))]
10203 "TARGET_64BIT && TARGET_BMI2"
10204 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10205 [(set_attr "type" "rotatex")
10206 (set_attr "mode" "SI")])
10207
10208 (define_insn "*<rotate_insn>si3_1_zext"
10209 [(set (match_operand:DI 0 "register_operand" "=r,r")
10210 (zero_extend:DI
10211 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10212 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10213 (clobber (reg:CC FLAGS_REG))]
10214 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10215 {
10216 switch (get_attr_type (insn))
10217 {
10218 case TYPE_ROTATEX:
10219 return "#";
10220
10221 default:
10222 if (operands[2] == const1_rtx
10223 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10224 return "<rotate>{l}\t%k0";
10225 else
10226 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10227 }
10228 }
10229 [(set_attr "isa" "*,bmi2")
10230 (set_attr "type" "rotate,rotatex")
10231 (set (attr "length_immediate")
10232 (if_then_else
10233 (and (eq_attr "type" "rotate")
10234 (and (match_operand 2 "const1_operand" "")
10235 (ior (match_test "TARGET_SHIFT1")
10236 (match_test "optimize_function_for_size_p (cfun)"))))
10237 (const_string "0")
10238 (const_string "*")))
10239 (set_attr "mode" "SI")])
10240
10241 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10242 (define_split
10243 [(set (match_operand:DI 0 "register_operand" "")
10244 (zero_extend:DI
10245 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10246 (match_operand:QI 2 "immediate_operand" ""))))
10247 (clobber (reg:CC FLAGS_REG))]
10248 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10249 [(set (match_dup 0)
10250 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10251 {
10252 operands[2]
10253 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10254 })
10255
10256 (define_split
10257 [(set (match_operand:DI 0 "register_operand" "")
10258 (zero_extend:DI
10259 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10260 (match_operand:QI 2 "immediate_operand" ""))))
10261 (clobber (reg:CC FLAGS_REG))]
10262 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10263 [(set (match_dup 0)
10264 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10265
10266 (define_insn "*<rotate_insn><mode>3_1"
10267 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10268 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10269 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10270 (clobber (reg:CC FLAGS_REG))]
10271 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10272 {
10273 if (operands[2] == const1_rtx
10274 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10275 return "<rotate>{<imodesuffix>}\t%0";
10276 else
10277 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10278 }
10279 [(set_attr "type" "rotate")
10280 (set (attr "length_immediate")
10281 (if_then_else
10282 (and (match_operand 2 "const1_operand" "")
10283 (ior (match_test "TARGET_SHIFT1")
10284 (match_test "optimize_function_for_size_p (cfun)")))
10285 (const_string "0")
10286 (const_string "*")))
10287 (set_attr "mode" "<MODE>")])
10288
10289 (define_insn "*<rotate_insn>qi3_1_slp"
10290 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10291 (any_rotate:QI (match_dup 0)
10292 (match_operand:QI 1 "nonmemory_operand" "cI")))
10293 (clobber (reg:CC FLAGS_REG))]
10294 "(optimize_function_for_size_p (cfun)
10295 || !TARGET_PARTIAL_REG_STALL
10296 || (operands[1] == const1_rtx
10297 && TARGET_SHIFT1))"
10298 {
10299 if (operands[1] == const1_rtx
10300 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10301 return "<rotate>{b}\t%0";
10302 else
10303 return "<rotate>{b}\t{%1, %0|%0, %1}";
10304 }
10305 [(set_attr "type" "rotate1")
10306 (set (attr "length_immediate")
10307 (if_then_else
10308 (and (match_operand 1 "const1_operand" "")
10309 (ior (match_test "TARGET_SHIFT1")
10310 (match_test "optimize_function_for_size_p (cfun)")))
10311 (const_string "0")
10312 (const_string "*")))
10313 (set_attr "mode" "QI")])
10314
10315 (define_split
10316 [(set (match_operand:HI 0 "register_operand" "")
10317 (any_rotate:HI (match_dup 0) (const_int 8)))
10318 (clobber (reg:CC FLAGS_REG))]
10319 "reload_completed
10320 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10321 [(parallel [(set (strict_low_part (match_dup 0))
10322 (bswap:HI (match_dup 0)))
10323 (clobber (reg:CC FLAGS_REG))])])
10324 \f
10325 ;; Bit set / bit test instructions
10326
10327 (define_expand "extv"
10328 [(set (match_operand:SI 0 "register_operand" "")
10329 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10330 (match_operand:SI 2 "const8_operand" "")
10331 (match_operand:SI 3 "const8_operand" "")))]
10332 ""
10333 {
10334 /* Handle extractions from %ah et al. */
10335 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10336 FAIL;
10337
10338 /* From mips.md: extract_bit_field doesn't verify that our source
10339 matches the predicate, so check it again here. */
10340 if (! ext_register_operand (operands[1], VOIDmode))
10341 FAIL;
10342 })
10343
10344 (define_expand "extzv"
10345 [(set (match_operand:SI 0 "register_operand" "")
10346 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10347 (match_operand:SI 2 "const8_operand" "")
10348 (match_operand:SI 3 "const8_operand" "")))]
10349 ""
10350 {
10351 /* Handle extractions from %ah et al. */
10352 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10353 FAIL;
10354
10355 /* From mips.md: extract_bit_field doesn't verify that our source
10356 matches the predicate, so check it again here. */
10357 if (! ext_register_operand (operands[1], VOIDmode))
10358 FAIL;
10359 })
10360
10361 (define_expand "insv"
10362 [(set (zero_extract (match_operand 0 "register_operand" "")
10363 (match_operand 1 "const_int_operand" "")
10364 (match_operand 2 "const_int_operand" ""))
10365 (match_operand 3 "register_operand" ""))]
10366 ""
10367 {
10368 rtx (*gen_mov_insv_1) (rtx, rtx);
10369
10370 if (ix86_expand_pinsr (operands))
10371 DONE;
10372
10373 /* Handle insertions to %ah et al. */
10374 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10375 FAIL;
10376
10377 /* From mips.md: insert_bit_field doesn't verify that our source
10378 matches the predicate, so check it again here. */
10379 if (! ext_register_operand (operands[0], VOIDmode))
10380 FAIL;
10381
10382 gen_mov_insv_1 = (TARGET_64BIT
10383 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10384
10385 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10386 DONE;
10387 })
10388
10389 ;; %%% bts, btr, btc, bt.
10390 ;; In general these instructions are *slow* when applied to memory,
10391 ;; since they enforce atomic operation. When applied to registers,
10392 ;; it depends on the cpu implementation. They're never faster than
10393 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10394 ;; no point. But in 64-bit, we can't hold the relevant immediates
10395 ;; within the instruction itself, so operating on bits in the high
10396 ;; 32-bits of a register becomes easier.
10397 ;;
10398 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10399 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10400 ;; negdf respectively, so they can never be disabled entirely.
10401
10402 (define_insn "*btsq"
10403 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10404 (const_int 1)
10405 (match_operand:DI 1 "const_0_to_63_operand" ""))
10406 (const_int 1))
10407 (clobber (reg:CC FLAGS_REG))]
10408 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10409 "bts{q}\t{%1, %0|%0, %1}"
10410 [(set_attr "type" "alu1")
10411 (set_attr "prefix_0f" "1")
10412 (set_attr "mode" "DI")])
10413
10414 (define_insn "*btrq"
10415 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10416 (const_int 1)
10417 (match_operand:DI 1 "const_0_to_63_operand" ""))
10418 (const_int 0))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10421 "btr{q}\t{%1, %0|%0, %1}"
10422 [(set_attr "type" "alu1")
10423 (set_attr "prefix_0f" "1")
10424 (set_attr "mode" "DI")])
10425
10426 (define_insn "*btcq"
10427 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10428 (const_int 1)
10429 (match_operand:DI 1 "const_0_to_63_operand" ""))
10430 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10431 (clobber (reg:CC FLAGS_REG))]
10432 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10433 "btc{q}\t{%1, %0|%0, %1}"
10434 [(set_attr "type" "alu1")
10435 (set_attr "prefix_0f" "1")
10436 (set_attr "mode" "DI")])
10437
10438 ;; Allow Nocona to avoid these instructions if a register is available.
10439
10440 (define_peephole2
10441 [(match_scratch:DI 2 "r")
10442 (parallel [(set (zero_extract:DI
10443 (match_operand:DI 0 "register_operand" "")
10444 (const_int 1)
10445 (match_operand:DI 1 "const_0_to_63_operand" ""))
10446 (const_int 1))
10447 (clobber (reg:CC FLAGS_REG))])]
10448 "TARGET_64BIT && !TARGET_USE_BT"
10449 [(const_int 0)]
10450 {
10451 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10452 rtx op1;
10453
10454 if (HOST_BITS_PER_WIDE_INT >= 64)
10455 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10456 else if (i < HOST_BITS_PER_WIDE_INT)
10457 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10458 else
10459 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10460
10461 op1 = immed_double_const (lo, hi, DImode);
10462 if (i >= 31)
10463 {
10464 emit_move_insn (operands[2], op1);
10465 op1 = operands[2];
10466 }
10467
10468 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10469 DONE;
10470 })
10471
10472 (define_peephole2
10473 [(match_scratch:DI 2 "r")
10474 (parallel [(set (zero_extract:DI
10475 (match_operand:DI 0 "register_operand" "")
10476 (const_int 1)
10477 (match_operand:DI 1 "const_0_to_63_operand" ""))
10478 (const_int 0))
10479 (clobber (reg:CC FLAGS_REG))])]
10480 "TARGET_64BIT && !TARGET_USE_BT"
10481 [(const_int 0)]
10482 {
10483 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10484 rtx op1;
10485
10486 if (HOST_BITS_PER_WIDE_INT >= 64)
10487 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10488 else if (i < HOST_BITS_PER_WIDE_INT)
10489 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10490 else
10491 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10492
10493 op1 = immed_double_const (~lo, ~hi, DImode);
10494 if (i >= 32)
10495 {
10496 emit_move_insn (operands[2], op1);
10497 op1 = operands[2];
10498 }
10499
10500 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10501 DONE;
10502 })
10503
10504 (define_peephole2
10505 [(match_scratch:DI 2 "r")
10506 (parallel [(set (zero_extract:DI
10507 (match_operand:DI 0 "register_operand" "")
10508 (const_int 1)
10509 (match_operand:DI 1 "const_0_to_63_operand" ""))
10510 (not:DI (zero_extract:DI
10511 (match_dup 0) (const_int 1) (match_dup 1))))
10512 (clobber (reg:CC FLAGS_REG))])]
10513 "TARGET_64BIT && !TARGET_USE_BT"
10514 [(const_int 0)]
10515 {
10516 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10517 rtx op1;
10518
10519 if (HOST_BITS_PER_WIDE_INT >= 64)
10520 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10521 else if (i < HOST_BITS_PER_WIDE_INT)
10522 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10523 else
10524 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10525
10526 op1 = immed_double_const (lo, hi, DImode);
10527 if (i >= 31)
10528 {
10529 emit_move_insn (operands[2], op1);
10530 op1 = operands[2];
10531 }
10532
10533 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10534 DONE;
10535 })
10536
10537 (define_insn "*bt<mode>"
10538 [(set (reg:CCC FLAGS_REG)
10539 (compare:CCC
10540 (zero_extract:SWI48
10541 (match_operand:SWI48 0 "register_operand" "r")
10542 (const_int 1)
10543 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10544 (const_int 0)))]
10545 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10546 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10547 [(set_attr "type" "alu1")
10548 (set_attr "prefix_0f" "1")
10549 (set_attr "mode" "<MODE>")])
10550 \f
10551 ;; Store-flag instructions.
10552
10553 ;; For all sCOND expanders, also expand the compare or test insn that
10554 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10555
10556 (define_insn_and_split "*setcc_di_1"
10557 [(set (match_operand:DI 0 "register_operand" "=q")
10558 (match_operator:DI 1 "ix86_comparison_operator"
10559 [(reg FLAGS_REG) (const_int 0)]))]
10560 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10561 "#"
10562 "&& reload_completed"
10563 [(set (match_dup 2) (match_dup 1))
10564 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10565 {
10566 PUT_MODE (operands[1], QImode);
10567 operands[2] = gen_lowpart (QImode, operands[0]);
10568 })
10569
10570 (define_insn_and_split "*setcc_si_1_and"
10571 [(set (match_operand:SI 0 "register_operand" "=q")
10572 (match_operator:SI 1 "ix86_comparison_operator"
10573 [(reg FLAGS_REG) (const_int 0)]))
10574 (clobber (reg:CC FLAGS_REG))]
10575 "!TARGET_PARTIAL_REG_STALL
10576 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10577 "#"
10578 "&& reload_completed"
10579 [(set (match_dup 2) (match_dup 1))
10580 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10581 (clobber (reg:CC FLAGS_REG))])]
10582 {
10583 PUT_MODE (operands[1], QImode);
10584 operands[2] = gen_lowpart (QImode, operands[0]);
10585 })
10586
10587 (define_insn_and_split "*setcc_si_1_movzbl"
10588 [(set (match_operand:SI 0 "register_operand" "=q")
10589 (match_operator:SI 1 "ix86_comparison_operator"
10590 [(reg FLAGS_REG) (const_int 0)]))]
10591 "!TARGET_PARTIAL_REG_STALL
10592 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10593 "#"
10594 "&& reload_completed"
10595 [(set (match_dup 2) (match_dup 1))
10596 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10597 {
10598 PUT_MODE (operands[1], QImode);
10599 operands[2] = gen_lowpart (QImode, operands[0]);
10600 })
10601
10602 (define_insn "*setcc_qi"
10603 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10604 (match_operator:QI 1 "ix86_comparison_operator"
10605 [(reg FLAGS_REG) (const_int 0)]))]
10606 ""
10607 "set%C1\t%0"
10608 [(set_attr "type" "setcc")
10609 (set_attr "mode" "QI")])
10610
10611 (define_insn "*setcc_qi_slp"
10612 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10613 (match_operator:QI 1 "ix86_comparison_operator"
10614 [(reg FLAGS_REG) (const_int 0)]))]
10615 ""
10616 "set%C1\t%0"
10617 [(set_attr "type" "setcc")
10618 (set_attr "mode" "QI")])
10619
10620 ;; In general it is not safe to assume too much about CCmode registers,
10621 ;; so simplify-rtx stops when it sees a second one. Under certain
10622 ;; conditions this is safe on x86, so help combine not create
10623 ;;
10624 ;; seta %al
10625 ;; testb %al, %al
10626 ;; sete %al
10627
10628 (define_split
10629 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10630 (ne:QI (match_operator 1 "ix86_comparison_operator"
10631 [(reg FLAGS_REG) (const_int 0)])
10632 (const_int 0)))]
10633 ""
10634 [(set (match_dup 0) (match_dup 1))]
10635 "PUT_MODE (operands[1], QImode);")
10636
10637 (define_split
10638 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10639 (ne:QI (match_operator 1 "ix86_comparison_operator"
10640 [(reg FLAGS_REG) (const_int 0)])
10641 (const_int 0)))]
10642 ""
10643 [(set (match_dup 0) (match_dup 1))]
10644 "PUT_MODE (operands[1], QImode);")
10645
10646 (define_split
10647 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10648 (eq:QI (match_operator 1 "ix86_comparison_operator"
10649 [(reg FLAGS_REG) (const_int 0)])
10650 (const_int 0)))]
10651 ""
10652 [(set (match_dup 0) (match_dup 1))]
10653 {
10654 rtx new_op1 = copy_rtx (operands[1]);
10655 operands[1] = new_op1;
10656 PUT_MODE (new_op1, QImode);
10657 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10658 GET_MODE (XEXP (new_op1, 0))));
10659
10660 /* Make sure that (a) the CCmode we have for the flags is strong
10661 enough for the reversed compare or (b) we have a valid FP compare. */
10662 if (! ix86_comparison_operator (new_op1, VOIDmode))
10663 FAIL;
10664 })
10665
10666 (define_split
10667 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10668 (eq:QI (match_operator 1 "ix86_comparison_operator"
10669 [(reg FLAGS_REG) (const_int 0)])
10670 (const_int 0)))]
10671 ""
10672 [(set (match_dup 0) (match_dup 1))]
10673 {
10674 rtx new_op1 = copy_rtx (operands[1]);
10675 operands[1] = new_op1;
10676 PUT_MODE (new_op1, QImode);
10677 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10678 GET_MODE (XEXP (new_op1, 0))));
10679
10680 /* Make sure that (a) the CCmode we have for the flags is strong
10681 enough for the reversed compare or (b) we have a valid FP compare. */
10682 if (! ix86_comparison_operator (new_op1, VOIDmode))
10683 FAIL;
10684 })
10685
10686 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10687 ;; subsequent logical operations are used to imitate conditional moves.
10688 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10689 ;; it directly.
10690
10691 (define_insn "setcc_<mode>_sse"
10692 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10693 (match_operator:MODEF 3 "sse_comparison_operator"
10694 [(match_operand:MODEF 1 "register_operand" "0,x")
10695 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10696 "SSE_FLOAT_MODE_P (<MODE>mode)"
10697 "@
10698 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10699 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10700 [(set_attr "isa" "noavx,avx")
10701 (set_attr "type" "ssecmp")
10702 (set_attr "length_immediate" "1")
10703 (set_attr "prefix" "orig,vex")
10704 (set_attr "mode" "<MODE>")])
10705 \f
10706 ;; Basic conditional jump instructions.
10707 ;; We ignore the overflow flag for signed branch instructions.
10708
10709 (define_insn "*jcc_1"
10710 [(set (pc)
10711 (if_then_else (match_operator 1 "ix86_comparison_operator"
10712 [(reg FLAGS_REG) (const_int 0)])
10713 (label_ref (match_operand 0 "" ""))
10714 (pc)))]
10715 ""
10716 "%+j%C1\t%l0"
10717 [(set_attr "type" "ibr")
10718 (set_attr "modrm" "0")
10719 (set (attr "length")
10720 (if_then_else (and (ge (minus (match_dup 0) (pc))
10721 (const_int -126))
10722 (lt (minus (match_dup 0) (pc))
10723 (const_int 128)))
10724 (const_int 2)
10725 (const_int 6)))])
10726
10727 (define_insn "*jcc_2"
10728 [(set (pc)
10729 (if_then_else (match_operator 1 "ix86_comparison_operator"
10730 [(reg FLAGS_REG) (const_int 0)])
10731 (pc)
10732 (label_ref (match_operand 0 "" ""))))]
10733 ""
10734 "%+j%c1\t%l0"
10735 [(set_attr "type" "ibr")
10736 (set_attr "modrm" "0")
10737 (set (attr "length")
10738 (if_then_else (and (ge (minus (match_dup 0) (pc))
10739 (const_int -126))
10740 (lt (minus (match_dup 0) (pc))
10741 (const_int 128)))
10742 (const_int 2)
10743 (const_int 6)))])
10744
10745 ;; In general it is not safe to assume too much about CCmode registers,
10746 ;; so simplify-rtx stops when it sees a second one. Under certain
10747 ;; conditions this is safe on x86, so help combine not create
10748 ;;
10749 ;; seta %al
10750 ;; testb %al, %al
10751 ;; je Lfoo
10752
10753 (define_split
10754 [(set (pc)
10755 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10756 [(reg FLAGS_REG) (const_int 0)])
10757 (const_int 0))
10758 (label_ref (match_operand 1 "" ""))
10759 (pc)))]
10760 ""
10761 [(set (pc)
10762 (if_then_else (match_dup 0)
10763 (label_ref (match_dup 1))
10764 (pc)))]
10765 "PUT_MODE (operands[0], VOIDmode);")
10766
10767 (define_split
10768 [(set (pc)
10769 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10770 [(reg FLAGS_REG) (const_int 0)])
10771 (const_int 0))
10772 (label_ref (match_operand 1 "" ""))
10773 (pc)))]
10774 ""
10775 [(set (pc)
10776 (if_then_else (match_dup 0)
10777 (label_ref (match_dup 1))
10778 (pc)))]
10779 {
10780 rtx new_op0 = copy_rtx (operands[0]);
10781 operands[0] = new_op0;
10782 PUT_MODE (new_op0, VOIDmode);
10783 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10784 GET_MODE (XEXP (new_op0, 0))));
10785
10786 /* Make sure that (a) the CCmode we have for the flags is strong
10787 enough for the reversed compare or (b) we have a valid FP compare. */
10788 if (! ix86_comparison_operator (new_op0, VOIDmode))
10789 FAIL;
10790 })
10791
10792 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10793 ;; pass generates from shift insn with QImode operand. Actually, the mode
10794 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10795 ;; appropriate modulo of the bit offset value.
10796
10797 (define_insn_and_split "*jcc_bt<mode>"
10798 [(set (pc)
10799 (if_then_else (match_operator 0 "bt_comparison_operator"
10800 [(zero_extract:SWI48
10801 (match_operand:SWI48 1 "register_operand" "r")
10802 (const_int 1)
10803 (zero_extend:SI
10804 (match_operand:QI 2 "register_operand" "r")))
10805 (const_int 0)])
10806 (label_ref (match_operand 3 "" ""))
10807 (pc)))
10808 (clobber (reg:CC FLAGS_REG))]
10809 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10810 "#"
10811 "&& 1"
10812 [(set (reg:CCC FLAGS_REG)
10813 (compare:CCC
10814 (zero_extract:SWI48
10815 (match_dup 1)
10816 (const_int 1)
10817 (match_dup 2))
10818 (const_int 0)))
10819 (set (pc)
10820 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10821 (label_ref (match_dup 3))
10822 (pc)))]
10823 {
10824 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10825
10826 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10827 })
10828
10829 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10830 ;; also for DImode, this is what combine produces.
10831 (define_insn_and_split "*jcc_bt<mode>_mask"
10832 [(set (pc)
10833 (if_then_else (match_operator 0 "bt_comparison_operator"
10834 [(zero_extract:SWI48
10835 (match_operand:SWI48 1 "register_operand" "r")
10836 (const_int 1)
10837 (and:SI
10838 (match_operand:SI 2 "register_operand" "r")
10839 (match_operand:SI 3 "const_int_operand" "n")))])
10840 (label_ref (match_operand 4 "" ""))
10841 (pc)))
10842 (clobber (reg:CC FLAGS_REG))]
10843 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10844 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10845 == GET_MODE_BITSIZE (<MODE>mode)-1"
10846 "#"
10847 "&& 1"
10848 [(set (reg:CCC FLAGS_REG)
10849 (compare:CCC
10850 (zero_extract:SWI48
10851 (match_dup 1)
10852 (const_int 1)
10853 (match_dup 2))
10854 (const_int 0)))
10855 (set (pc)
10856 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10857 (label_ref (match_dup 4))
10858 (pc)))]
10859 {
10860 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10861
10862 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10863 })
10864
10865 (define_insn_and_split "*jcc_btsi_1"
10866 [(set (pc)
10867 (if_then_else (match_operator 0 "bt_comparison_operator"
10868 [(and:SI
10869 (lshiftrt:SI
10870 (match_operand:SI 1 "register_operand" "r")
10871 (match_operand:QI 2 "register_operand" "r"))
10872 (const_int 1))
10873 (const_int 0)])
10874 (label_ref (match_operand 3 "" ""))
10875 (pc)))
10876 (clobber (reg:CC FLAGS_REG))]
10877 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10878 "#"
10879 "&& 1"
10880 [(set (reg:CCC FLAGS_REG)
10881 (compare:CCC
10882 (zero_extract:SI
10883 (match_dup 1)
10884 (const_int 1)
10885 (match_dup 2))
10886 (const_int 0)))
10887 (set (pc)
10888 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10889 (label_ref (match_dup 3))
10890 (pc)))]
10891 {
10892 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10893
10894 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10895 })
10896
10897 ;; avoid useless masking of bit offset operand
10898 (define_insn_and_split "*jcc_btsi_mask_1"
10899 [(set (pc)
10900 (if_then_else
10901 (match_operator 0 "bt_comparison_operator"
10902 [(and:SI
10903 (lshiftrt:SI
10904 (match_operand:SI 1 "register_operand" "r")
10905 (subreg:QI
10906 (and:SI
10907 (match_operand:SI 2 "register_operand" "r")
10908 (match_operand:SI 3 "const_int_operand" "n")) 0))
10909 (const_int 1))
10910 (const_int 0)])
10911 (label_ref (match_operand 4 "" ""))
10912 (pc)))
10913 (clobber (reg:CC FLAGS_REG))]
10914 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10915 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10916 "#"
10917 "&& 1"
10918 [(set (reg:CCC FLAGS_REG)
10919 (compare:CCC
10920 (zero_extract:SI
10921 (match_dup 1)
10922 (const_int 1)
10923 (match_dup 2))
10924 (const_int 0)))
10925 (set (pc)
10926 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10927 (label_ref (match_dup 4))
10928 (pc)))]
10929 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10930
10931 ;; Define combination compare-and-branch fp compare instructions to help
10932 ;; combine.
10933
10934 (define_insn "*fp_jcc_1_387"
10935 [(set (pc)
10936 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10937 [(match_operand 1 "register_operand" "f")
10938 (match_operand 2 "nonimmediate_operand" "fm")])
10939 (label_ref (match_operand 3 "" ""))
10940 (pc)))
10941 (clobber (reg:CCFP FPSR_REG))
10942 (clobber (reg:CCFP FLAGS_REG))
10943 (clobber (match_scratch:HI 4 "=a"))]
10944 "TARGET_80387
10945 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10946 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10947 && SELECT_CC_MODE (GET_CODE (operands[0]),
10948 operands[1], operands[2]) == CCFPmode
10949 && !TARGET_CMOVE"
10950 "#")
10951
10952 (define_insn "*fp_jcc_1r_387"
10953 [(set (pc)
10954 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10955 [(match_operand 1 "register_operand" "f")
10956 (match_operand 2 "nonimmediate_operand" "fm")])
10957 (pc)
10958 (label_ref (match_operand 3 "" ""))))
10959 (clobber (reg:CCFP FPSR_REG))
10960 (clobber (reg:CCFP FLAGS_REG))
10961 (clobber (match_scratch:HI 4 "=a"))]
10962 "TARGET_80387
10963 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10964 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10965 && SELECT_CC_MODE (GET_CODE (operands[0]),
10966 operands[1], operands[2]) == CCFPmode
10967 && !TARGET_CMOVE"
10968 "#")
10969
10970 (define_insn "*fp_jcc_2_387"
10971 [(set (pc)
10972 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10973 [(match_operand 1 "register_operand" "f")
10974 (match_operand 2 "register_operand" "f")])
10975 (label_ref (match_operand 3 "" ""))
10976 (pc)))
10977 (clobber (reg:CCFP FPSR_REG))
10978 (clobber (reg:CCFP FLAGS_REG))
10979 (clobber (match_scratch:HI 4 "=a"))]
10980 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10981 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10982 && !TARGET_CMOVE"
10983 "#")
10984
10985 (define_insn "*fp_jcc_2r_387"
10986 [(set (pc)
10987 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10988 [(match_operand 1 "register_operand" "f")
10989 (match_operand 2 "register_operand" "f")])
10990 (pc)
10991 (label_ref (match_operand 3 "" ""))))
10992 (clobber (reg:CCFP FPSR_REG))
10993 (clobber (reg:CCFP FLAGS_REG))
10994 (clobber (match_scratch:HI 4 "=a"))]
10995 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10996 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10997 && !TARGET_CMOVE"
10998 "#")
10999
11000 (define_insn "*fp_jcc_3_387"
11001 [(set (pc)
11002 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11003 [(match_operand 1 "register_operand" "f")
11004 (match_operand 2 "const0_operand" "")])
11005 (label_ref (match_operand 3 "" ""))
11006 (pc)))
11007 (clobber (reg:CCFP FPSR_REG))
11008 (clobber (reg:CCFP FLAGS_REG))
11009 (clobber (match_scratch:HI 4 "=a"))]
11010 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11011 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11012 && SELECT_CC_MODE (GET_CODE (operands[0]),
11013 operands[1], operands[2]) == CCFPmode
11014 && !TARGET_CMOVE"
11015 "#")
11016
11017 (define_split
11018 [(set (pc)
11019 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11020 [(match_operand 1 "register_operand" "")
11021 (match_operand 2 "nonimmediate_operand" "")])
11022 (match_operand 3 "" "")
11023 (match_operand 4 "" "")))
11024 (clobber (reg:CCFP FPSR_REG))
11025 (clobber (reg:CCFP FLAGS_REG))]
11026 "reload_completed"
11027 [(const_int 0)]
11028 {
11029 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11030 operands[3], operands[4], NULL_RTX, NULL_RTX);
11031 DONE;
11032 })
11033
11034 (define_split
11035 [(set (pc)
11036 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11037 [(match_operand 1 "register_operand" "")
11038 (match_operand 2 "general_operand" "")])
11039 (match_operand 3 "" "")
11040 (match_operand 4 "" "")))
11041 (clobber (reg:CCFP FPSR_REG))
11042 (clobber (reg:CCFP FLAGS_REG))
11043 (clobber (match_scratch:HI 5 "=a"))]
11044 "reload_completed"
11045 [(const_int 0)]
11046 {
11047 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11048 operands[3], operands[4], operands[5], NULL_RTX);
11049 DONE;
11050 })
11051
11052 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11053 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11054 ;; with a precedence over other operators and is always put in the first
11055 ;; place. Swap condition and operands to match ficom instruction.
11056
11057 (define_insn "*fp_jcc_4_<mode>_387"
11058 [(set (pc)
11059 (if_then_else
11060 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11061 [(match_operator 1 "float_operator"
11062 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11063 (match_operand 3 "register_operand" "f,f")])
11064 (label_ref (match_operand 4 "" ""))
11065 (pc)))
11066 (clobber (reg:CCFP FPSR_REG))
11067 (clobber (reg:CCFP FLAGS_REG))
11068 (clobber (match_scratch:HI 5 "=a,a"))]
11069 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11070 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11071 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11072 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11073 && !TARGET_CMOVE"
11074 "#")
11075
11076 (define_split
11077 [(set (pc)
11078 (if_then_else
11079 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11080 [(match_operator 1 "float_operator"
11081 [(match_operand:SWI24 2 "memory_operand" "")])
11082 (match_operand 3 "register_operand" "")])
11083 (match_operand 4 "" "")
11084 (match_operand 5 "" "")))
11085 (clobber (reg:CCFP FPSR_REG))
11086 (clobber (reg:CCFP FLAGS_REG))
11087 (clobber (match_scratch:HI 6 "=a"))]
11088 "reload_completed"
11089 [(const_int 0)]
11090 {
11091 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11092
11093 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11094 operands[3], operands[7],
11095 operands[4], operands[5], operands[6], NULL_RTX);
11096 DONE;
11097 })
11098
11099 ;; %%% Kill this when reload knows how to do it.
11100 (define_split
11101 [(set (pc)
11102 (if_then_else
11103 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11104 [(match_operator 1 "float_operator"
11105 [(match_operand:SWI24 2 "register_operand" "")])
11106 (match_operand 3 "register_operand" "")])
11107 (match_operand 4 "" "")
11108 (match_operand 5 "" "")))
11109 (clobber (reg:CCFP FPSR_REG))
11110 (clobber (reg:CCFP FLAGS_REG))
11111 (clobber (match_scratch:HI 6 "=a"))]
11112 "reload_completed"
11113 [(const_int 0)]
11114 {
11115 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11116 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11117
11118 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11119 operands[3], operands[7],
11120 operands[4], operands[5], operands[6], operands[2]);
11121 DONE;
11122 })
11123 \f
11124 ;; Unconditional and other jump instructions
11125
11126 (define_insn "jump"
11127 [(set (pc)
11128 (label_ref (match_operand 0 "" "")))]
11129 ""
11130 "jmp\t%l0"
11131 [(set_attr "type" "ibr")
11132 (set (attr "length")
11133 (if_then_else (and (ge (minus (match_dup 0) (pc))
11134 (const_int -126))
11135 (lt (minus (match_dup 0) (pc))
11136 (const_int 128)))
11137 (const_int 2)
11138 (const_int 5)))
11139 (set_attr "modrm" "0")])
11140
11141 (define_expand "indirect_jump"
11142 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11143
11144 (define_insn "*indirect_jump"
11145 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11146 ""
11147 "jmp\t%A0"
11148 [(set_attr "type" "ibr")
11149 (set_attr "length_immediate" "0")])
11150
11151 (define_expand "tablejump"
11152 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11153 (use (label_ref (match_operand 1 "" "")))])]
11154 ""
11155 {
11156 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11157 relative. Convert the relative address to an absolute address. */
11158 if (flag_pic)
11159 {
11160 rtx op0, op1;
11161 enum rtx_code code;
11162
11163 /* We can't use @GOTOFF for text labels on VxWorks;
11164 see gotoff_operand. */
11165 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11166 {
11167 code = PLUS;
11168 op0 = operands[0];
11169 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11170 }
11171 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11172 {
11173 code = PLUS;
11174 op0 = operands[0];
11175 op1 = pic_offset_table_rtx;
11176 }
11177 else
11178 {
11179 code = MINUS;
11180 op0 = pic_offset_table_rtx;
11181 op1 = operands[0];
11182 }
11183
11184 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11185 OPTAB_DIRECT);
11186 }
11187 else if (TARGET_X32)
11188 operands[0] = convert_memory_address (Pmode, operands[0]);
11189 })
11190
11191 (define_insn "*tablejump_1"
11192 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11193 (use (label_ref (match_operand 1 "" "")))]
11194 ""
11195 "jmp\t%A0"
11196 [(set_attr "type" "ibr")
11197 (set_attr "length_immediate" "0")])
11198 \f
11199 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11200
11201 (define_peephole2
11202 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11203 (set (match_operand:QI 1 "register_operand" "")
11204 (match_operator:QI 2 "ix86_comparison_operator"
11205 [(reg FLAGS_REG) (const_int 0)]))
11206 (set (match_operand 3 "q_regs_operand" "")
11207 (zero_extend (match_dup 1)))]
11208 "(peep2_reg_dead_p (3, operands[1])
11209 || operands_match_p (operands[1], operands[3]))
11210 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11211 [(set (match_dup 4) (match_dup 0))
11212 (set (strict_low_part (match_dup 5))
11213 (match_dup 2))]
11214 {
11215 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11216 operands[5] = gen_lowpart (QImode, operands[3]);
11217 ix86_expand_clear (operands[3]);
11218 })
11219
11220 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11221
11222 (define_peephole2
11223 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11224 (set (match_operand:QI 1 "register_operand" "")
11225 (match_operator:QI 2 "ix86_comparison_operator"
11226 [(reg FLAGS_REG) (const_int 0)]))
11227 (parallel [(set (match_operand 3 "q_regs_operand" "")
11228 (zero_extend (match_dup 1)))
11229 (clobber (reg:CC FLAGS_REG))])]
11230 "(peep2_reg_dead_p (3, operands[1])
11231 || operands_match_p (operands[1], operands[3]))
11232 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11233 [(set (match_dup 4) (match_dup 0))
11234 (set (strict_low_part (match_dup 5))
11235 (match_dup 2))]
11236 {
11237 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11238 operands[5] = gen_lowpart (QImode, operands[3]);
11239 ix86_expand_clear (operands[3]);
11240 })
11241 \f
11242 ;; Call instructions.
11243
11244 ;; The predicates normally associated with named expanders are not properly
11245 ;; checked for calls. This is a bug in the generic code, but it isn't that
11246 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11247
11248 ;; P6 processors will jump to the address after the decrement when %esp
11249 ;; is used as a call operand, so they will execute return address as a code.
11250 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11251
11252 ;; Register constraint for call instruction.
11253 (define_mode_attr c [(SI "l") (DI "r")])
11254
11255 ;; Call subroutine returning no value.
11256
11257 (define_expand "call"
11258 [(call (match_operand:QI 0 "" "")
11259 (match_operand 1 "" ""))
11260 (use (match_operand 2 "" ""))]
11261 ""
11262 {
11263 ix86_expand_call (NULL, operands[0], operands[1],
11264 operands[2], NULL, false);
11265 DONE;
11266 })
11267
11268 (define_expand "sibcall"
11269 [(call (match_operand:QI 0 "" "")
11270 (match_operand 1 "" ""))
11271 (use (match_operand 2 "" ""))]
11272 ""
11273 {
11274 ix86_expand_call (NULL, operands[0], operands[1],
11275 operands[2], NULL, true);
11276 DONE;
11277 })
11278
11279 (define_insn_and_split "*call_vzeroupper"
11280 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11281 (match_operand 1 "" ""))
11282 (unspec [(match_operand 2 "const_int_operand" "")]
11283 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11284 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11285 "#"
11286 "&& reload_completed"
11287 [(const_int 0)]
11288 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11289 [(set_attr "type" "call")])
11290
11291 (define_insn "*call"
11292 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11293 (match_operand 1 "" ""))]
11294 "!SIBLING_CALL_P (insn)"
11295 "* return ix86_output_call_insn (insn, operands[0]);"
11296 [(set_attr "type" "call")])
11297
11298 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11299 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11300 (match_operand 1 "" ""))
11301 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11302 (clobber (reg:TI XMM6_REG))
11303 (clobber (reg:TI XMM7_REG))
11304 (clobber (reg:TI XMM8_REG))
11305 (clobber (reg:TI XMM9_REG))
11306 (clobber (reg:TI XMM10_REG))
11307 (clobber (reg:TI XMM11_REG))
11308 (clobber (reg:TI XMM12_REG))
11309 (clobber (reg:TI XMM13_REG))
11310 (clobber (reg:TI XMM14_REG))
11311 (clobber (reg:TI XMM15_REG))
11312 (clobber (reg:DI SI_REG))
11313 (clobber (reg:DI DI_REG))
11314 (unspec [(match_operand 2 "const_int_operand" "")]
11315 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11316 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11317 "#"
11318 "&& reload_completed"
11319 [(const_int 0)]
11320 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11321 [(set_attr "type" "call")])
11322
11323 (define_insn "*call_rex64_ms_sysv"
11324 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11325 (match_operand 1 "" ""))
11326 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11327 (clobber (reg:TI XMM6_REG))
11328 (clobber (reg:TI XMM7_REG))
11329 (clobber (reg:TI XMM8_REG))
11330 (clobber (reg:TI XMM9_REG))
11331 (clobber (reg:TI XMM10_REG))
11332 (clobber (reg:TI XMM11_REG))
11333 (clobber (reg:TI XMM12_REG))
11334 (clobber (reg:TI XMM13_REG))
11335 (clobber (reg:TI XMM14_REG))
11336 (clobber (reg:TI XMM15_REG))
11337 (clobber (reg:DI SI_REG))
11338 (clobber (reg:DI DI_REG))]
11339 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11340 "* return ix86_output_call_insn (insn, operands[0]);"
11341 [(set_attr "type" "call")])
11342
11343 (define_insn_and_split "*sibcall_vzeroupper"
11344 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11345 (match_operand 1 "" ""))
11346 (unspec [(match_operand 2 "const_int_operand" "")]
11347 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11348 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11349 "#"
11350 "&& reload_completed"
11351 [(const_int 0)]
11352 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11353 [(set_attr "type" "call")])
11354
11355 (define_insn "*sibcall"
11356 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11357 (match_operand 1 "" ""))]
11358 "SIBLING_CALL_P (insn)"
11359 "* return ix86_output_call_insn (insn, operands[0]);"
11360 [(set_attr "type" "call")])
11361
11362 (define_expand "call_pop"
11363 [(parallel [(call (match_operand:QI 0 "" "")
11364 (match_operand:SI 1 "" ""))
11365 (set (reg:SI SP_REG)
11366 (plus:SI (reg:SI SP_REG)
11367 (match_operand:SI 3 "" "")))])]
11368 "!TARGET_64BIT"
11369 {
11370 ix86_expand_call (NULL, operands[0], operands[1],
11371 operands[2], operands[3], false);
11372 DONE;
11373 })
11374
11375 (define_insn_and_split "*call_pop_vzeroupper"
11376 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11377 (match_operand:SI 1 "" ""))
11378 (set (reg:SI SP_REG)
11379 (plus:SI (reg:SI SP_REG)
11380 (match_operand:SI 2 "immediate_operand" "i")))
11381 (unspec [(match_operand 3 "const_int_operand" "")]
11382 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11383 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11384 "#"
11385 "&& reload_completed"
11386 [(const_int 0)]
11387 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11388 [(set_attr "type" "call")])
11389
11390 (define_insn "*call_pop"
11391 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11392 (match_operand 1 "" ""))
11393 (set (reg:SI SP_REG)
11394 (plus:SI (reg:SI SP_REG)
11395 (match_operand:SI 2 "immediate_operand" "i")))]
11396 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11397 "* return ix86_output_call_insn (insn, operands[0]);"
11398 [(set_attr "type" "call")])
11399
11400 (define_insn_and_split "*sibcall_pop_vzeroupper"
11401 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11402 (match_operand 1 "" ""))
11403 (set (reg:SI SP_REG)
11404 (plus:SI (reg:SI SP_REG)
11405 (match_operand:SI 2 "immediate_operand" "i")))
11406 (unspec [(match_operand 3 "const_int_operand" "")]
11407 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11408 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11409 "#"
11410 "&& reload_completed"
11411 [(const_int 0)]
11412 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11413 [(set_attr "type" "call")])
11414
11415 (define_insn "*sibcall_pop"
11416 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11417 (match_operand 1 "" ""))
11418 (set (reg:SI SP_REG)
11419 (plus:SI (reg:SI SP_REG)
11420 (match_operand:SI 2 "immediate_operand" "i")))]
11421 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11422 "* return ix86_output_call_insn (insn, operands[0]);"
11423 [(set_attr "type" "call")])
11424
11425 ;; Call subroutine, returning value in operand 0
11426
11427 (define_expand "call_value"
11428 [(set (match_operand 0 "" "")
11429 (call (match_operand:QI 1 "" "")
11430 (match_operand 2 "" "")))
11431 (use (match_operand 3 "" ""))]
11432 ""
11433 {
11434 ix86_expand_call (operands[0], operands[1], operands[2],
11435 operands[3], NULL, false);
11436 DONE;
11437 })
11438
11439 (define_expand "sibcall_value"
11440 [(set (match_operand 0 "" "")
11441 (call (match_operand:QI 1 "" "")
11442 (match_operand 2 "" "")))
11443 (use (match_operand 3 "" ""))]
11444 ""
11445 {
11446 ix86_expand_call (operands[0], operands[1], operands[2],
11447 operands[3], NULL, true);
11448 DONE;
11449 })
11450
11451 (define_insn_and_split "*call_value_vzeroupper"
11452 [(set (match_operand 0 "" "")
11453 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11454 (match_operand 2 "" "")))
11455 (unspec [(match_operand 3 "const_int_operand" "")]
11456 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11457 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11458 "#"
11459 "&& reload_completed"
11460 [(const_int 0)]
11461 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11462 [(set_attr "type" "callv")])
11463
11464 (define_insn "*call_value"
11465 [(set (match_operand 0 "" "")
11466 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11467 (match_operand 2 "" "")))]
11468 "!SIBLING_CALL_P (insn)"
11469 "* return ix86_output_call_insn (insn, operands[1]);"
11470 [(set_attr "type" "callv")])
11471
11472 (define_insn_and_split "*sibcall_value_vzeroupper"
11473 [(set (match_operand 0 "" "")
11474 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11475 (match_operand 2 "" "")))
11476 (unspec [(match_operand 3 "const_int_operand" "")]
11477 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11478 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11479 "#"
11480 "&& reload_completed"
11481 [(const_int 0)]
11482 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11483 [(set_attr "type" "callv")])
11484
11485 (define_insn "*sibcall_value"
11486 [(set (match_operand 0 "" "")
11487 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11488 (match_operand 2 "" "")))]
11489 "SIBLING_CALL_P (insn)"
11490 "* return ix86_output_call_insn (insn, operands[1]);"
11491 [(set_attr "type" "callv")])
11492
11493 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11494 [(set (match_operand 0 "" "")
11495 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11496 (match_operand 2 "" "")))
11497 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11498 (clobber (reg:TI XMM6_REG))
11499 (clobber (reg:TI XMM7_REG))
11500 (clobber (reg:TI XMM8_REG))
11501 (clobber (reg:TI XMM9_REG))
11502 (clobber (reg:TI XMM10_REG))
11503 (clobber (reg:TI XMM11_REG))
11504 (clobber (reg:TI XMM12_REG))
11505 (clobber (reg:TI XMM13_REG))
11506 (clobber (reg:TI XMM14_REG))
11507 (clobber (reg:TI XMM15_REG))
11508 (clobber (reg:DI SI_REG))
11509 (clobber (reg:DI DI_REG))
11510 (unspec [(match_operand 3 "const_int_operand" "")]
11511 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11512 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11513 "#"
11514 "&& reload_completed"
11515 [(const_int 0)]
11516 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11517 [(set_attr "type" "callv")])
11518
11519 (define_insn "*call_value_rex64_ms_sysv"
11520 [(set (match_operand 0 "" "")
11521 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11522 (match_operand 2 "" "")))
11523 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11524 (clobber (reg:TI XMM6_REG))
11525 (clobber (reg:TI XMM7_REG))
11526 (clobber (reg:TI XMM8_REG))
11527 (clobber (reg:TI XMM9_REG))
11528 (clobber (reg:TI XMM10_REG))
11529 (clobber (reg:TI XMM11_REG))
11530 (clobber (reg:TI XMM12_REG))
11531 (clobber (reg:TI XMM13_REG))
11532 (clobber (reg:TI XMM14_REG))
11533 (clobber (reg:TI XMM15_REG))
11534 (clobber (reg:DI SI_REG))
11535 (clobber (reg:DI DI_REG))]
11536 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11537 "* return ix86_output_call_insn (insn, operands[1]);"
11538 [(set_attr "type" "callv")])
11539
11540 (define_expand "call_value_pop"
11541 [(parallel [(set (match_operand 0 "" "")
11542 (call (match_operand:QI 1 "" "")
11543 (match_operand:SI 2 "" "")))
11544 (set (reg:SI SP_REG)
11545 (plus:SI (reg:SI SP_REG)
11546 (match_operand:SI 4 "" "")))])]
11547 "!TARGET_64BIT"
11548 {
11549 ix86_expand_call (operands[0], operands[1], operands[2],
11550 operands[3], operands[4], false);
11551 DONE;
11552 })
11553
11554 (define_insn_and_split "*call_value_pop_vzeroupper"
11555 [(set (match_operand 0 "" "")
11556 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11557 (match_operand 2 "" "")))
11558 (set (reg:SI SP_REG)
11559 (plus:SI (reg:SI SP_REG)
11560 (match_operand:SI 3 "immediate_operand" "i")))
11561 (unspec [(match_operand 4 "const_int_operand" "")]
11562 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11563 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11564 "#"
11565 "&& reload_completed"
11566 [(const_int 0)]
11567 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11568 [(set_attr "type" "callv")])
11569
11570 (define_insn "*call_value_pop"
11571 [(set (match_operand 0 "" "")
11572 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11573 (match_operand 2 "" "")))
11574 (set (reg:SI SP_REG)
11575 (plus:SI (reg:SI SP_REG)
11576 (match_operand:SI 3 "immediate_operand" "i")))]
11577 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11578 "* return ix86_output_call_insn (insn, operands[1]);"
11579 [(set_attr "type" "callv")])
11580
11581 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11582 [(set (match_operand 0 "" "")
11583 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11584 (match_operand 2 "" "")))
11585 (set (reg:SI SP_REG)
11586 (plus:SI (reg:SI SP_REG)
11587 (match_operand:SI 3 "immediate_operand" "i")))
11588 (unspec [(match_operand 4 "const_int_operand" "")]
11589 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11590 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11591 "#"
11592 "&& reload_completed"
11593 [(const_int 0)]
11594 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11595 [(set_attr "type" "callv")])
11596
11597 (define_insn "*sibcall_value_pop"
11598 [(set (match_operand 0 "" "")
11599 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11600 (match_operand 2 "" "")))
11601 (set (reg:SI SP_REG)
11602 (plus:SI (reg:SI SP_REG)
11603 (match_operand:SI 3 "immediate_operand" "i")))]
11604 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11605 "* return ix86_output_call_insn (insn, operands[1]);"
11606 [(set_attr "type" "callv")])
11607
11608 ;; Call subroutine returning any type.
11609
11610 (define_expand "untyped_call"
11611 [(parallel [(call (match_operand 0 "" "")
11612 (const_int 0))
11613 (match_operand 1 "" "")
11614 (match_operand 2 "" "")])]
11615 ""
11616 {
11617 int i;
11618
11619 /* In order to give reg-stack an easier job in validating two
11620 coprocessor registers as containing a possible return value,
11621 simply pretend the untyped call returns a complex long double
11622 value.
11623
11624 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11625 and should have the default ABI. */
11626
11627 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11628 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11629 operands[0], const0_rtx,
11630 GEN_INT ((TARGET_64BIT
11631 ? (ix86_abi == SYSV_ABI
11632 ? X86_64_SSE_REGPARM_MAX
11633 : X86_64_MS_SSE_REGPARM_MAX)
11634 : X86_32_SSE_REGPARM_MAX)
11635 - 1),
11636 NULL, false);
11637
11638 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11639 {
11640 rtx set = XVECEXP (operands[2], 0, i);
11641 emit_move_insn (SET_DEST (set), SET_SRC (set));
11642 }
11643
11644 /* The optimizer does not know that the call sets the function value
11645 registers we stored in the result block. We avoid problems by
11646 claiming that all hard registers are used and clobbered at this
11647 point. */
11648 emit_insn (gen_blockage ());
11649
11650 DONE;
11651 })
11652 \f
11653 ;; Prologue and epilogue instructions
11654
11655 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11656 ;; all of memory. This blocks insns from being moved across this point.
11657
11658 (define_insn "blockage"
11659 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11660 ""
11661 ""
11662 [(set_attr "length" "0")])
11663
11664 ;; Do not schedule instructions accessing memory across this point.
11665
11666 (define_expand "memory_blockage"
11667 [(set (match_dup 0)
11668 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11669 ""
11670 {
11671 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11672 MEM_VOLATILE_P (operands[0]) = 1;
11673 })
11674
11675 (define_insn "*memory_blockage"
11676 [(set (match_operand:BLK 0 "" "")
11677 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11678 ""
11679 ""
11680 [(set_attr "length" "0")])
11681
11682 ;; As USE insns aren't meaningful after reload, this is used instead
11683 ;; to prevent deleting instructions setting registers for PIC code
11684 (define_insn "prologue_use"
11685 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11686 ""
11687 ""
11688 [(set_attr "length" "0")])
11689
11690 ;; Insn emitted into the body of a function to return from a function.
11691 ;; This is only done if the function's epilogue is known to be simple.
11692 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11693
11694 (define_expand "return"
11695 [(simple_return)]
11696 "ix86_can_use_return_insn_p ()"
11697 {
11698 if (crtl->args.pops_args)
11699 {
11700 rtx popc = GEN_INT (crtl->args.pops_args);
11701 emit_jump_insn (gen_simple_return_pop_internal (popc));
11702 DONE;
11703 }
11704 })
11705
11706 ;; We need to disable this for TARGET_SEH, as otherwise
11707 ;; shrink-wrapped prologue gets enabled too. This might exceed
11708 ;; the maximum size of prologue in unwind information.
11709
11710 (define_expand "simple_return"
11711 [(simple_return)]
11712 "!TARGET_SEH"
11713 {
11714 if (crtl->args.pops_args)
11715 {
11716 rtx popc = GEN_INT (crtl->args.pops_args);
11717 emit_jump_insn (gen_simple_return_pop_internal (popc));
11718 DONE;
11719 }
11720 })
11721
11722 (define_insn "simple_return_internal"
11723 [(simple_return)]
11724 "reload_completed"
11725 "ret"
11726 [(set_attr "length" "1")
11727 (set_attr "atom_unit" "jeu")
11728 (set_attr "length_immediate" "0")
11729 (set_attr "modrm" "0")])
11730
11731 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11732 ;; instruction Athlon and K8 have.
11733
11734 (define_insn "simple_return_internal_long"
11735 [(simple_return)
11736 (unspec [(const_int 0)] UNSPEC_REP)]
11737 "reload_completed"
11738 "rep\;ret"
11739 [(set_attr "length" "2")
11740 (set_attr "atom_unit" "jeu")
11741 (set_attr "length_immediate" "0")
11742 (set_attr "prefix_rep" "1")
11743 (set_attr "modrm" "0")])
11744
11745 (define_insn "simple_return_pop_internal"
11746 [(simple_return)
11747 (use (match_operand:SI 0 "const_int_operand" ""))]
11748 "reload_completed"
11749 "ret\t%0"
11750 [(set_attr "length" "3")
11751 (set_attr "atom_unit" "jeu")
11752 (set_attr "length_immediate" "2")
11753 (set_attr "modrm" "0")])
11754
11755 (define_insn "simple_return_indirect_internal"
11756 [(simple_return)
11757 (use (match_operand:SI 0 "register_operand" "r"))]
11758 "reload_completed"
11759 "jmp\t%A0"
11760 [(set_attr "type" "ibr")
11761 (set_attr "length_immediate" "0")])
11762
11763 (define_insn "nop"
11764 [(const_int 0)]
11765 ""
11766 "nop"
11767 [(set_attr "length" "1")
11768 (set_attr "length_immediate" "0")
11769 (set_attr "modrm" "0")])
11770
11771 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11772 (define_insn "nops"
11773 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11774 UNSPECV_NOPS)]
11775 "reload_completed"
11776 {
11777 int num = INTVAL (operands[0]);
11778
11779 gcc_assert (num >= 1 && num <= 8);
11780
11781 while (num--)
11782 fputs ("\tnop\n", asm_out_file);
11783
11784 return "";
11785 }
11786 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11787 (set_attr "length_immediate" "0")
11788 (set_attr "modrm" "0")])
11789
11790 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11791 ;; branch prediction penalty for the third jump in a 16-byte
11792 ;; block on K8.
11793
11794 (define_insn "pad"
11795 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11796 ""
11797 {
11798 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11799 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11800 #else
11801 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11802 The align insn is used to avoid 3 jump instructions in the row to improve
11803 branch prediction and the benefits hardly outweigh the cost of extra 8
11804 nops on the average inserted by full alignment pseudo operation. */
11805 #endif
11806 return "";
11807 }
11808 [(set_attr "length" "16")])
11809
11810 (define_expand "prologue"
11811 [(const_int 0)]
11812 ""
11813 "ix86_expand_prologue (); DONE;")
11814
11815 (define_insn "set_got"
11816 [(set (match_operand:SI 0 "register_operand" "=r")
11817 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11818 (clobber (reg:CC FLAGS_REG))]
11819 "!TARGET_64BIT"
11820 "* return output_set_got (operands[0], NULL_RTX);"
11821 [(set_attr "type" "multi")
11822 (set_attr "length" "12")])
11823
11824 (define_insn "set_got_labelled"
11825 [(set (match_operand:SI 0 "register_operand" "=r")
11826 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11827 UNSPEC_SET_GOT))
11828 (clobber (reg:CC FLAGS_REG))]
11829 "!TARGET_64BIT"
11830 "* return output_set_got (operands[0], operands[1]);"
11831 [(set_attr "type" "multi")
11832 (set_attr "length" "12")])
11833
11834 (define_insn "set_got_rex64"
11835 [(set (match_operand:DI 0 "register_operand" "=r")
11836 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11837 "TARGET_64BIT"
11838 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11839 [(set_attr "type" "lea")
11840 (set_attr "length_address" "4")
11841 (set_attr "mode" "DI")])
11842
11843 (define_insn "set_rip_rex64"
11844 [(set (match_operand:DI 0 "register_operand" "=r")
11845 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11846 "TARGET_64BIT"
11847 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11848 [(set_attr "type" "lea")
11849 (set_attr "length_address" "4")
11850 (set_attr "mode" "DI")])
11851
11852 (define_insn "set_got_offset_rex64"
11853 [(set (match_operand:DI 0 "register_operand" "=r")
11854 (unspec:DI
11855 [(label_ref (match_operand 1 "" ""))]
11856 UNSPEC_SET_GOT_OFFSET))]
11857 "TARGET_LP64"
11858 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11859 [(set_attr "type" "imov")
11860 (set_attr "length_immediate" "0")
11861 (set_attr "length_address" "8")
11862 (set_attr "mode" "DI")])
11863
11864 (define_expand "epilogue"
11865 [(const_int 0)]
11866 ""
11867 "ix86_expand_epilogue (1); DONE;")
11868
11869 (define_expand "sibcall_epilogue"
11870 [(const_int 0)]
11871 ""
11872 "ix86_expand_epilogue (0); DONE;")
11873
11874 (define_expand "eh_return"
11875 [(use (match_operand 0 "register_operand" ""))]
11876 ""
11877 {
11878 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11879
11880 /* Tricky bit: we write the address of the handler to which we will
11881 be returning into someone else's stack frame, one word below the
11882 stack address we wish to restore. */
11883 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11884 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11885 tmp = gen_rtx_MEM (Pmode, tmp);
11886 emit_move_insn (tmp, ra);
11887
11888 emit_jump_insn (gen_eh_return_internal ());
11889 emit_barrier ();
11890 DONE;
11891 })
11892
11893 (define_insn_and_split "eh_return_internal"
11894 [(eh_return)]
11895 ""
11896 "#"
11897 "epilogue_completed"
11898 [(const_int 0)]
11899 "ix86_expand_epilogue (2); DONE;")
11900
11901 (define_insn "leave"
11902 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11903 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11904 (clobber (mem:BLK (scratch)))]
11905 "!TARGET_64BIT"
11906 "leave"
11907 [(set_attr "type" "leave")])
11908
11909 (define_insn "leave_rex64"
11910 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11911 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11912 (clobber (mem:BLK (scratch)))]
11913 "TARGET_64BIT"
11914 "leave"
11915 [(set_attr "type" "leave")])
11916 \f
11917 ;; Handle -fsplit-stack.
11918
11919 (define_expand "split_stack_prologue"
11920 [(const_int 0)]
11921 ""
11922 {
11923 ix86_expand_split_stack_prologue ();
11924 DONE;
11925 })
11926
11927 ;; In order to support the call/return predictor, we use a return
11928 ;; instruction which the middle-end doesn't see.
11929 (define_insn "split_stack_return"
11930 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11931 UNSPECV_SPLIT_STACK_RETURN)]
11932 ""
11933 {
11934 if (operands[0] == const0_rtx)
11935 return "ret";
11936 else
11937 return "ret\t%0";
11938 }
11939 [(set_attr "atom_unit" "jeu")
11940 (set_attr "modrm" "0")
11941 (set (attr "length")
11942 (if_then_else (match_operand:SI 0 "const0_operand" "")
11943 (const_int 1)
11944 (const_int 3)))
11945 (set (attr "length_immediate")
11946 (if_then_else (match_operand:SI 0 "const0_operand" "")
11947 (const_int 0)
11948 (const_int 2)))])
11949
11950 ;; If there are operand 0 bytes available on the stack, jump to
11951 ;; operand 1.
11952
11953 (define_expand "split_stack_space_check"
11954 [(set (pc) (if_then_else
11955 (ltu (minus (reg SP_REG)
11956 (match_operand 0 "register_operand" ""))
11957 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11958 (label_ref (match_operand 1 "" ""))
11959 (pc)))]
11960 ""
11961 {
11962 rtx reg, size, limit;
11963
11964 reg = gen_reg_rtx (Pmode);
11965 size = force_reg (Pmode, operands[0]);
11966 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11967 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11968 UNSPEC_STACK_CHECK);
11969 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11970 ix86_expand_branch (GEU, reg, limit, operands[1]);
11971
11972 DONE;
11973 })
11974 \f
11975 ;; Bit manipulation instructions.
11976
11977 (define_expand "ffs<mode>2"
11978 [(set (match_dup 2) (const_int -1))
11979 (parallel [(set (reg:CCZ FLAGS_REG)
11980 (compare:CCZ
11981 (match_operand:SWI48 1 "nonimmediate_operand" "")
11982 (const_int 0)))
11983 (set (match_operand:SWI48 0 "register_operand" "")
11984 (ctz:SWI48 (match_dup 1)))])
11985 (set (match_dup 0) (if_then_else:SWI48
11986 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11987 (match_dup 2)
11988 (match_dup 0)))
11989 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11990 (clobber (reg:CC FLAGS_REG))])]
11991 ""
11992 {
11993 if (<MODE>mode == SImode && !TARGET_CMOVE)
11994 {
11995 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11996 DONE;
11997 }
11998 operands[2] = gen_reg_rtx (<MODE>mode);
11999 })
12000
12001 (define_insn_and_split "ffssi2_no_cmove"
12002 [(set (match_operand:SI 0 "register_operand" "=r")
12003 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12004 (clobber (match_scratch:SI 2 "=&q"))
12005 (clobber (reg:CC FLAGS_REG))]
12006 "!TARGET_CMOVE"
12007 "#"
12008 "&& reload_completed"
12009 [(parallel [(set (reg:CCZ FLAGS_REG)
12010 (compare:CCZ (match_dup 1) (const_int 0)))
12011 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12012 (set (strict_low_part (match_dup 3))
12013 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12014 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12015 (clobber (reg:CC FLAGS_REG))])
12016 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12017 (clobber (reg:CC FLAGS_REG))])
12018 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12019 (clobber (reg:CC FLAGS_REG))])]
12020 {
12021 operands[3] = gen_lowpart (QImode, operands[2]);
12022 ix86_expand_clear (operands[2]);
12023 })
12024
12025 (define_insn "*ffs<mode>_1"
12026 [(set (reg:CCZ FLAGS_REG)
12027 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12028 (const_int 0)))
12029 (set (match_operand:SWI48 0 "register_operand" "=r")
12030 (ctz:SWI48 (match_dup 1)))]
12031 ""
12032 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12033 [(set_attr "type" "alu1")
12034 (set_attr "prefix_0f" "1")
12035 (set_attr "mode" "<MODE>")])
12036
12037 (define_insn "ctz<mode>2"
12038 [(set (match_operand:SWI248 0 "register_operand" "=r")
12039 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12040 (clobber (reg:CC FLAGS_REG))]
12041 ""
12042 {
12043 if (TARGET_BMI)
12044 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12045 else
12046 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12047 }
12048 [(set_attr "type" "alu1")
12049 (set_attr "prefix_0f" "1")
12050 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12051 (set_attr "mode" "<MODE>")])
12052
12053 (define_expand "clz<mode>2"
12054 [(parallel
12055 [(set (match_operand:SWI248 0 "register_operand" "")
12056 (minus:SWI248
12057 (match_dup 2)
12058 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12059 (clobber (reg:CC FLAGS_REG))])
12060 (parallel
12061 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12062 (clobber (reg:CC FLAGS_REG))])]
12063 ""
12064 {
12065 if (TARGET_LZCNT)
12066 {
12067 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12068 DONE;
12069 }
12070 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12071 })
12072
12073 (define_insn "clz<mode>2_lzcnt"
12074 [(set (match_operand:SWI248 0 "register_operand" "=r")
12075 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12076 (clobber (reg:CC FLAGS_REG))]
12077 "TARGET_LZCNT"
12078 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12079 [(set_attr "prefix_rep" "1")
12080 (set_attr "type" "bitmanip")
12081 (set_attr "mode" "<MODE>")])
12082
12083 ;; BMI instructions.
12084 (define_insn "*bmi_andn_<mode>"
12085 [(set (match_operand:SWI48 0 "register_operand" "=r")
12086 (and:SWI48
12087 (not:SWI48
12088 (match_operand:SWI48 1 "register_operand" "r"))
12089 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12090 (clobber (reg:CC FLAGS_REG))]
12091 "TARGET_BMI"
12092 "andn\t{%2, %1, %0|%0, %1, %2}"
12093 [(set_attr "type" "bitmanip")
12094 (set_attr "mode" "<MODE>")])
12095
12096 (define_insn "bmi_bextr_<mode>"
12097 [(set (match_operand:SWI48 0 "register_operand" "=r")
12098 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12099 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12100 UNSPEC_BEXTR))
12101 (clobber (reg:CC FLAGS_REG))]
12102 "TARGET_BMI"
12103 "bextr\t{%2, %1, %0|%0, %1, %2}"
12104 [(set_attr "type" "bitmanip")
12105 (set_attr "mode" "<MODE>")])
12106
12107 (define_insn "*bmi_blsi_<mode>"
12108 [(set (match_operand:SWI48 0 "register_operand" "=r")
12109 (and:SWI48
12110 (neg:SWI48
12111 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12112 (match_dup 1)))
12113 (clobber (reg:CC FLAGS_REG))]
12114 "TARGET_BMI"
12115 "blsi\t{%1, %0|%0, %1}"
12116 [(set_attr "type" "bitmanip")
12117 (set_attr "mode" "<MODE>")])
12118
12119 (define_insn "*bmi_blsmsk_<mode>"
12120 [(set (match_operand:SWI48 0 "register_operand" "=r")
12121 (xor:SWI48
12122 (plus:SWI48
12123 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12124 (const_int -1))
12125 (match_dup 1)))
12126 (clobber (reg:CC FLAGS_REG))]
12127 "TARGET_BMI"
12128 "blsmsk\t{%1, %0|%0, %1}"
12129 [(set_attr "type" "bitmanip")
12130 (set_attr "mode" "<MODE>")])
12131
12132 (define_insn "*bmi_blsr_<mode>"
12133 [(set (match_operand:SWI48 0 "register_operand" "=r")
12134 (and:SWI48
12135 (plus:SWI48
12136 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12137 (const_int -1))
12138 (match_dup 1)))
12139 (clobber (reg:CC FLAGS_REG))]
12140 "TARGET_BMI"
12141 "blsr\t{%1, %0|%0, %1}"
12142 [(set_attr "type" "bitmanip")
12143 (set_attr "mode" "<MODE>")])
12144
12145 ;; BMI2 instructions.
12146 (define_insn "bmi2_bzhi_<mode>3"
12147 [(set (match_operand:SWI48 0 "register_operand" "=r")
12148 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12149 (lshiftrt:SWI48 (const_int -1)
12150 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12151 (clobber (reg:CC FLAGS_REG))]
12152 "TARGET_BMI2"
12153 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12154 [(set_attr "type" "bitmanip")
12155 (set_attr "prefix" "vex")
12156 (set_attr "mode" "<MODE>")])
12157
12158 (define_insn "bmi2_pdep_<mode>3"
12159 [(set (match_operand:SWI48 0 "register_operand" "=r")
12160 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12161 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12162 UNSPEC_PDEP))]
12163 "TARGET_BMI2"
12164 "pdep\t{%2, %1, %0|%0, %1, %2}"
12165 [(set_attr "type" "bitmanip")
12166 (set_attr "prefix" "vex")
12167 (set_attr "mode" "<MODE>")])
12168
12169 (define_insn "bmi2_pext_<mode>3"
12170 [(set (match_operand:SWI48 0 "register_operand" "=r")
12171 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12172 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12173 UNSPEC_PEXT))]
12174 "TARGET_BMI2"
12175 "pext\t{%2, %1, %0|%0, %1, %2}"
12176 [(set_attr "type" "bitmanip")
12177 (set_attr "prefix" "vex")
12178 (set_attr "mode" "<MODE>")])
12179
12180 ;; TBM instructions.
12181 (define_insn "tbm_bextri_<mode>"
12182 [(set (match_operand:SWI48 0 "register_operand" "=r")
12183 (zero_extract:SWI48
12184 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12185 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12186 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12187 (clobber (reg:CC FLAGS_REG))]
12188 "TARGET_TBM"
12189 {
12190 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12191 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12192 }
12193 [(set_attr "type" "bitmanip")
12194 (set_attr "mode" "<MODE>")])
12195
12196 (define_insn "*tbm_blcfill_<mode>"
12197 [(set (match_operand:SWI48 0 "register_operand" "=r")
12198 (and:SWI48
12199 (plus:SWI48
12200 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12201 (const_int 1))
12202 (match_dup 1)))
12203 (clobber (reg:CC FLAGS_REG))]
12204 "TARGET_TBM"
12205 "blcfill\t{%1, %0|%0, %1}"
12206 [(set_attr "type" "bitmanip")
12207 (set_attr "mode" "<MODE>")])
12208
12209 (define_insn "*tbm_blci_<mode>"
12210 [(set (match_operand:SWI48 0 "register_operand" "=r")
12211 (ior:SWI48
12212 (not:SWI48
12213 (plus:SWI48
12214 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12215 (const_int 1)))
12216 (match_dup 1)))
12217 (clobber (reg:CC FLAGS_REG))]
12218 "TARGET_TBM"
12219 "blci\t{%1, %0|%0, %1}"
12220 [(set_attr "type" "bitmanip")
12221 (set_attr "mode" "<MODE>")])
12222
12223 (define_insn "*tbm_blcic_<mode>"
12224 [(set (match_operand:SWI48 0 "register_operand" "=r")
12225 (and:SWI48
12226 (plus:SWI48
12227 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12228 (const_int 1))
12229 (not:SWI48
12230 (match_dup 1))))
12231 (clobber (reg:CC FLAGS_REG))]
12232 "TARGET_TBM"
12233 "blcic\t{%1, %0|%0, %1}"
12234 [(set_attr "type" "bitmanip")
12235 (set_attr "mode" "<MODE>")])
12236
12237 (define_insn "*tbm_blcmsk_<mode>"
12238 [(set (match_operand:SWI48 0 "register_operand" "=r")
12239 (xor:SWI48
12240 (plus:SWI48
12241 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12242 (const_int 1))
12243 (match_dup 1)))
12244 (clobber (reg:CC FLAGS_REG))]
12245 "TARGET_TBM"
12246 "blcmsk\t{%1, %0|%0, %1}"
12247 [(set_attr "type" "bitmanip")
12248 (set_attr "mode" "<MODE>")])
12249
12250 (define_insn "*tbm_blcs_<mode>"
12251 [(set (match_operand:SWI48 0 "register_operand" "=r")
12252 (ior:SWI48
12253 (plus:SWI48
12254 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12255 (const_int 1))
12256 (match_dup 1)))
12257 (clobber (reg:CC FLAGS_REG))]
12258 "TARGET_TBM"
12259 "blcs\t{%1, %0|%0, %1}"
12260 [(set_attr "type" "bitmanip")
12261 (set_attr "mode" "<MODE>")])
12262
12263 (define_insn "*tbm_blsfill_<mode>"
12264 [(set (match_operand:SWI48 0 "register_operand" "=r")
12265 (ior:SWI48
12266 (plus:SWI48
12267 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12268 (const_int -1))
12269 (match_dup 1)))
12270 (clobber (reg:CC FLAGS_REG))]
12271 "TARGET_TBM"
12272 "blsfill\t{%1, %0|%0, %1}"
12273 [(set_attr "type" "bitmanip")
12274 (set_attr "mode" "<MODE>")])
12275
12276 (define_insn "*tbm_blsic_<mode>"
12277 [(set (match_operand:SWI48 0 "register_operand" "=r")
12278 (ior:SWI48
12279 (plus:SWI48
12280 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12281 (const_int -1))
12282 (not:SWI48
12283 (match_dup 1))))
12284 (clobber (reg:CC FLAGS_REG))]
12285 "TARGET_TBM"
12286 "blsic\t{%1, %0|%0, %1}"
12287 [(set_attr "type" "bitmanip")
12288 (set_attr "mode" "<MODE>")])
12289
12290 (define_insn "*tbm_t1mskc_<mode>"
12291 [(set (match_operand:SWI48 0 "register_operand" "=r")
12292 (ior:SWI48
12293 (plus:SWI48
12294 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12295 (const_int 1))
12296 (not:SWI48
12297 (match_dup 1))))
12298 (clobber (reg:CC FLAGS_REG))]
12299 "TARGET_TBM"
12300 "t1mskc\t{%1, %0|%0, %1}"
12301 [(set_attr "type" "bitmanip")
12302 (set_attr "mode" "<MODE>")])
12303
12304 (define_insn "*tbm_tzmsk_<mode>"
12305 [(set (match_operand:SWI48 0 "register_operand" "=r")
12306 (and:SWI48
12307 (plus:SWI48
12308 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12309 (const_int -1))
12310 (not:SWI48
12311 (match_dup 1))))
12312 (clobber (reg:CC FLAGS_REG))]
12313 "TARGET_TBM"
12314 "tzmsk\t{%1, %0|%0, %1}"
12315 [(set_attr "type" "bitmanip")
12316 (set_attr "mode" "<MODE>")])
12317
12318 (define_insn "bsr_rex64"
12319 [(set (match_operand:DI 0 "register_operand" "=r")
12320 (minus:DI (const_int 63)
12321 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12322 (clobber (reg:CC FLAGS_REG))]
12323 "TARGET_64BIT"
12324 "bsr{q}\t{%1, %0|%0, %1}"
12325 [(set_attr "type" "alu1")
12326 (set_attr "prefix_0f" "1")
12327 (set_attr "mode" "DI")])
12328
12329 (define_insn "bsr"
12330 [(set (match_operand:SI 0 "register_operand" "=r")
12331 (minus:SI (const_int 31)
12332 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12333 (clobber (reg:CC FLAGS_REG))]
12334 ""
12335 "bsr{l}\t{%1, %0|%0, %1}"
12336 [(set_attr "type" "alu1")
12337 (set_attr "prefix_0f" "1")
12338 (set_attr "mode" "SI")])
12339
12340 (define_insn "*bsrhi"
12341 [(set (match_operand:HI 0 "register_operand" "=r")
12342 (minus:HI (const_int 15)
12343 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12344 (clobber (reg:CC FLAGS_REG))]
12345 ""
12346 "bsr{w}\t{%1, %0|%0, %1}"
12347 [(set_attr "type" "alu1")
12348 (set_attr "prefix_0f" "1")
12349 (set_attr "mode" "HI")])
12350
12351 (define_insn "popcount<mode>2"
12352 [(set (match_operand:SWI248 0 "register_operand" "=r")
12353 (popcount:SWI248
12354 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12355 (clobber (reg:CC FLAGS_REG))]
12356 "TARGET_POPCNT"
12357 {
12358 #if TARGET_MACHO
12359 return "popcnt\t{%1, %0|%0, %1}";
12360 #else
12361 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12362 #endif
12363 }
12364 [(set_attr "prefix_rep" "1")
12365 (set_attr "type" "bitmanip")
12366 (set_attr "mode" "<MODE>")])
12367
12368 (define_insn "*popcount<mode>2_cmp"
12369 [(set (reg FLAGS_REG)
12370 (compare
12371 (popcount:SWI248
12372 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12373 (const_int 0)))
12374 (set (match_operand:SWI248 0 "register_operand" "=r")
12375 (popcount:SWI248 (match_dup 1)))]
12376 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12377 {
12378 #if TARGET_MACHO
12379 return "popcnt\t{%1, %0|%0, %1}";
12380 #else
12381 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12382 #endif
12383 }
12384 [(set_attr "prefix_rep" "1")
12385 (set_attr "type" "bitmanip")
12386 (set_attr "mode" "<MODE>")])
12387
12388 (define_insn "*popcountsi2_cmp_zext"
12389 [(set (reg FLAGS_REG)
12390 (compare
12391 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12392 (const_int 0)))
12393 (set (match_operand:DI 0 "register_operand" "=r")
12394 (zero_extend:DI(popcount:SI (match_dup 1))))]
12395 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12396 {
12397 #if TARGET_MACHO
12398 return "popcnt\t{%1, %0|%0, %1}";
12399 #else
12400 return "popcnt{l}\t{%1, %0|%0, %1}";
12401 #endif
12402 }
12403 [(set_attr "prefix_rep" "1")
12404 (set_attr "type" "bitmanip")
12405 (set_attr "mode" "SI")])
12406
12407 (define_expand "bswap<mode>2"
12408 [(set (match_operand:SWI48 0 "register_operand" "")
12409 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12410 ""
12411 {
12412 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12413 {
12414 rtx x = operands[0];
12415
12416 emit_move_insn (x, operands[1]);
12417 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12418 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12419 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12420 DONE;
12421 }
12422 })
12423
12424 (define_insn "*bswap<mode>2_movbe"
12425 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12426 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12427 "TARGET_MOVBE
12428 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12429 "@
12430 bswap\t%0
12431 movbe\t{%1, %0|%0, %1}
12432 movbe\t{%1, %0|%0, %1}"
12433 [(set_attr "type" "bitmanip,imov,imov")
12434 (set_attr "modrm" "0,1,1")
12435 (set_attr "prefix_0f" "*,1,1")
12436 (set_attr "prefix_extra" "*,1,1")
12437 (set_attr "mode" "<MODE>")])
12438
12439 (define_insn "*bswap<mode>2_1"
12440 [(set (match_operand:SWI48 0 "register_operand" "=r")
12441 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12442 "TARGET_BSWAP"
12443 "bswap\t%0"
12444 [(set_attr "type" "bitmanip")
12445 (set_attr "modrm" "0")
12446 (set_attr "mode" "<MODE>")])
12447
12448 (define_insn "*bswaphi_lowpart_1"
12449 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12450 (bswap:HI (match_dup 0)))
12451 (clobber (reg:CC FLAGS_REG))]
12452 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12453 "@
12454 xchg{b}\t{%h0, %b0|%b0, %h0}
12455 rol{w}\t{$8, %0|%0, 8}"
12456 [(set_attr "length" "2,4")
12457 (set_attr "mode" "QI,HI")])
12458
12459 (define_insn "bswaphi_lowpart"
12460 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12461 (bswap:HI (match_dup 0)))
12462 (clobber (reg:CC FLAGS_REG))]
12463 ""
12464 "rol{w}\t{$8, %0|%0, 8}"
12465 [(set_attr "length" "4")
12466 (set_attr "mode" "HI")])
12467
12468 (define_expand "paritydi2"
12469 [(set (match_operand:DI 0 "register_operand" "")
12470 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12471 "! TARGET_POPCNT"
12472 {
12473 rtx scratch = gen_reg_rtx (QImode);
12474 rtx cond;
12475
12476 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12477 NULL_RTX, operands[1]));
12478
12479 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12480 gen_rtx_REG (CCmode, FLAGS_REG),
12481 const0_rtx);
12482 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12483
12484 if (TARGET_64BIT)
12485 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12486 else
12487 {
12488 rtx tmp = gen_reg_rtx (SImode);
12489
12490 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12491 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12492 }
12493 DONE;
12494 })
12495
12496 (define_expand "paritysi2"
12497 [(set (match_operand:SI 0 "register_operand" "")
12498 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12499 "! TARGET_POPCNT"
12500 {
12501 rtx scratch = gen_reg_rtx (QImode);
12502 rtx cond;
12503
12504 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12505
12506 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12507 gen_rtx_REG (CCmode, FLAGS_REG),
12508 const0_rtx);
12509 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12510
12511 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12512 DONE;
12513 })
12514
12515 (define_insn_and_split "paritydi2_cmp"
12516 [(set (reg:CC FLAGS_REG)
12517 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12518 UNSPEC_PARITY))
12519 (clobber (match_scratch:DI 0 "=r"))
12520 (clobber (match_scratch:SI 1 "=&r"))
12521 (clobber (match_scratch:HI 2 "=Q"))]
12522 "! TARGET_POPCNT"
12523 "#"
12524 "&& reload_completed"
12525 [(parallel
12526 [(set (match_dup 1)
12527 (xor:SI (match_dup 1) (match_dup 4)))
12528 (clobber (reg:CC FLAGS_REG))])
12529 (parallel
12530 [(set (reg:CC FLAGS_REG)
12531 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12532 (clobber (match_dup 1))
12533 (clobber (match_dup 2))])]
12534 {
12535 operands[4] = gen_lowpart (SImode, operands[3]);
12536
12537 if (TARGET_64BIT)
12538 {
12539 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12540 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12541 }
12542 else
12543 operands[1] = gen_highpart (SImode, operands[3]);
12544 })
12545
12546 (define_insn_and_split "paritysi2_cmp"
12547 [(set (reg:CC FLAGS_REG)
12548 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12549 UNSPEC_PARITY))
12550 (clobber (match_scratch:SI 0 "=r"))
12551 (clobber (match_scratch:HI 1 "=&Q"))]
12552 "! TARGET_POPCNT"
12553 "#"
12554 "&& reload_completed"
12555 [(parallel
12556 [(set (match_dup 1)
12557 (xor:HI (match_dup 1) (match_dup 3)))
12558 (clobber (reg:CC FLAGS_REG))])
12559 (parallel
12560 [(set (reg:CC FLAGS_REG)
12561 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12562 (clobber (match_dup 1))])]
12563 {
12564 operands[3] = gen_lowpart (HImode, operands[2]);
12565
12566 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12567 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12568 })
12569
12570 (define_insn "*parityhi2_cmp"
12571 [(set (reg:CC FLAGS_REG)
12572 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12573 UNSPEC_PARITY))
12574 (clobber (match_scratch:HI 0 "=Q"))]
12575 "! TARGET_POPCNT"
12576 "xor{b}\t{%h0, %b0|%b0, %h0}"
12577 [(set_attr "length" "2")
12578 (set_attr "mode" "HI")])
12579
12580 \f
12581 ;; Thread-local storage patterns for ELF.
12582 ;;
12583 ;; Note that these code sequences must appear exactly as shown
12584 ;; in order to allow linker relaxation.
12585
12586 (define_insn "*tls_global_dynamic_32_gnu"
12587 [(set (match_operand:SI 0 "register_operand" "=a")
12588 (unspec:SI
12589 [(match_operand:SI 1 "register_operand" "b")
12590 (match_operand:SI 2 "tls_symbolic_operand" "")
12591 (match_operand:SI 3 "constant_call_address_operand" "z")]
12592 UNSPEC_TLS_GD))
12593 (clobber (match_scratch:SI 4 "=d"))
12594 (clobber (match_scratch:SI 5 "=c"))
12595 (clobber (reg:CC FLAGS_REG))]
12596 "!TARGET_64BIT && TARGET_GNU_TLS"
12597 {
12598 output_asm_insn
12599 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12600 if (TARGET_SUN_TLS)
12601 #ifdef HAVE_AS_IX86_TLSGDPLT
12602 return "call\t%a2@tlsgdplt";
12603 #else
12604 return "call\t%p3@plt";
12605 #endif
12606 return "call\t%P3";
12607 }
12608 [(set_attr "type" "multi")
12609 (set_attr "length" "12")])
12610
12611 (define_expand "tls_global_dynamic_32"
12612 [(parallel
12613 [(set (match_operand:SI 0 "register_operand" "")
12614 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12615 (match_operand:SI 1 "tls_symbolic_operand" "")
12616 (match_operand:SI 3 "constant_call_address_operand" "")]
12617 UNSPEC_TLS_GD))
12618 (clobber (match_scratch:SI 4 ""))
12619 (clobber (match_scratch:SI 5 ""))
12620 (clobber (reg:CC FLAGS_REG))])])
12621
12622 (define_insn "*tls_global_dynamic_64"
12623 [(set (match_operand:DI 0 "register_operand" "=a")
12624 (call:DI
12625 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12626 (match_operand:DI 3 "" "")))
12627 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12628 UNSPEC_TLS_GD)]
12629 "TARGET_64BIT"
12630 {
12631 if (!TARGET_X32)
12632 fputs (ASM_BYTE "0x66\n", asm_out_file);
12633 output_asm_insn
12634 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12635 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12636 fputs ("\trex64\n", asm_out_file);
12637 if (TARGET_SUN_TLS)
12638 return "call\t%p2@plt";
12639 return "call\t%P2";
12640 }
12641 [(set_attr "type" "multi")
12642 (set (attr "length")
12643 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12644
12645 (define_expand "tls_global_dynamic_64"
12646 [(parallel
12647 [(set (match_operand:DI 0 "register_operand" "")
12648 (call:DI
12649 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12650 (const_int 0)))
12651 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12652 UNSPEC_TLS_GD)])])
12653
12654 (define_insn "*tls_local_dynamic_base_32_gnu"
12655 [(set (match_operand:SI 0 "register_operand" "=a")
12656 (unspec:SI
12657 [(match_operand:SI 1 "register_operand" "b")
12658 (match_operand:SI 2 "constant_call_address_operand" "z")]
12659 UNSPEC_TLS_LD_BASE))
12660 (clobber (match_scratch:SI 3 "=d"))
12661 (clobber (match_scratch:SI 4 "=c"))
12662 (clobber (reg:CC FLAGS_REG))]
12663 "!TARGET_64BIT && TARGET_GNU_TLS"
12664 {
12665 output_asm_insn
12666 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12667 if (TARGET_SUN_TLS)
12668 #ifdef HAVE_AS_IX86_TLSLDMPLT
12669 return "call\t%&@tlsldmplt";
12670 #else
12671 return "call\t%p2@plt";
12672 #endif
12673 return "call\t%P2";
12674 }
12675 [(set_attr "type" "multi")
12676 (set_attr "length" "11")])
12677
12678 (define_expand "tls_local_dynamic_base_32"
12679 [(parallel
12680 [(set (match_operand:SI 0 "register_operand" "")
12681 (unspec:SI
12682 [(match_operand:SI 1 "register_operand" "")
12683 (match_operand:SI 2 "constant_call_address_operand" "")]
12684 UNSPEC_TLS_LD_BASE))
12685 (clobber (match_scratch:SI 3 ""))
12686 (clobber (match_scratch:SI 4 ""))
12687 (clobber (reg:CC FLAGS_REG))])])
12688
12689 (define_insn "*tls_local_dynamic_base_64"
12690 [(set (match_operand:DI 0 "register_operand" "=a")
12691 (call:DI
12692 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12693 (match_operand:DI 2 "" "")))
12694 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12695 "TARGET_64BIT"
12696 {
12697 output_asm_insn
12698 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12699 if (TARGET_SUN_TLS)
12700 return "call\t%p1@plt";
12701 return "call\t%P1";
12702 }
12703 [(set_attr "type" "multi")
12704 (set_attr "length" "12")])
12705
12706 (define_expand "tls_local_dynamic_base_64"
12707 [(parallel
12708 [(set (match_operand:DI 0 "register_operand" "")
12709 (call:DI
12710 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12711 (const_int 0)))
12712 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12713
12714 ;; Local dynamic of a single variable is a lose. Show combine how
12715 ;; to convert that back to global dynamic.
12716
12717 (define_insn_and_split "*tls_local_dynamic_32_once"
12718 [(set (match_operand:SI 0 "register_operand" "=a")
12719 (plus:SI
12720 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12721 (match_operand:SI 2 "constant_call_address_operand" "z")]
12722 UNSPEC_TLS_LD_BASE)
12723 (const:SI (unspec:SI
12724 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12725 UNSPEC_DTPOFF))))
12726 (clobber (match_scratch:SI 4 "=d"))
12727 (clobber (match_scratch:SI 5 "=c"))
12728 (clobber (reg:CC FLAGS_REG))]
12729 ""
12730 "#"
12731 ""
12732 [(parallel
12733 [(set (match_dup 0)
12734 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12735 UNSPEC_TLS_GD))
12736 (clobber (match_dup 4))
12737 (clobber (match_dup 5))
12738 (clobber (reg:CC FLAGS_REG))])])
12739
12740 ;; Segment register for the thread base ptr load
12741 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12742
12743 ;; Load and add the thread base pointer from %<tp_seg>:0.
12744 (define_insn "*load_tp_x32"
12745 [(set (match_operand:SI 0 "register_operand" "=r")
12746 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12747 "TARGET_X32"
12748 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12749 [(set_attr "type" "imov")
12750 (set_attr "modrm" "0")
12751 (set_attr "length" "7")
12752 (set_attr "memory" "load")
12753 (set_attr "imm_disp" "false")])
12754
12755 (define_insn "*load_tp_x32_zext"
12756 [(set (match_operand:DI 0 "register_operand" "=r")
12757 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12758 "TARGET_X32"
12759 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12760 [(set_attr "type" "imov")
12761 (set_attr "modrm" "0")
12762 (set_attr "length" "7")
12763 (set_attr "memory" "load")
12764 (set_attr "imm_disp" "false")])
12765
12766 (define_insn "*load_tp_<mode>"
12767 [(set (match_operand:P 0 "register_operand" "=r")
12768 (unspec:P [(const_int 0)] UNSPEC_TP))]
12769 "!TARGET_X32"
12770 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12771 [(set_attr "type" "imov")
12772 (set_attr "modrm" "0")
12773 (set_attr "length" "7")
12774 (set_attr "memory" "load")
12775 (set_attr "imm_disp" "false")])
12776
12777 (define_insn "*add_tp_x32"
12778 [(set (match_operand:SI 0 "register_operand" "=r")
12779 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12780 (match_operand:SI 1 "register_operand" "0")))
12781 (clobber (reg:CC FLAGS_REG))]
12782 "TARGET_X32"
12783 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12784 [(set_attr "type" "alu")
12785 (set_attr "modrm" "0")
12786 (set_attr "length" "7")
12787 (set_attr "memory" "load")
12788 (set_attr "imm_disp" "false")])
12789
12790 (define_insn "*add_tp_x32_zext"
12791 [(set (match_operand:DI 0 "register_operand" "=r")
12792 (zero_extend:DI
12793 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12794 (match_operand:SI 1 "register_operand" "0"))))
12795 (clobber (reg:CC FLAGS_REG))]
12796 "TARGET_X32"
12797 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12798 [(set_attr "type" "alu")
12799 (set_attr "modrm" "0")
12800 (set_attr "length" "7")
12801 (set_attr "memory" "load")
12802 (set_attr "imm_disp" "false")])
12803
12804 (define_insn "*add_tp_<mode>"
12805 [(set (match_operand:P 0 "register_operand" "=r")
12806 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12807 (match_operand:P 1 "register_operand" "0")))
12808 (clobber (reg:CC FLAGS_REG))]
12809 "!TARGET_X32"
12810 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12811 [(set_attr "type" "alu")
12812 (set_attr "modrm" "0")
12813 (set_attr "length" "7")
12814 (set_attr "memory" "load")
12815 (set_attr "imm_disp" "false")])
12816
12817 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12818 ;; %rax as destination of the initial executable code sequence.
12819 (define_insn "tls_initial_exec_64_sun"
12820 [(set (match_operand:DI 0 "register_operand" "=a")
12821 (unspec:DI
12822 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12823 UNSPEC_TLS_IE_SUN))
12824 (clobber (reg:CC FLAGS_REG))]
12825 "TARGET_64BIT && TARGET_SUN_TLS"
12826 {
12827 output_asm_insn
12828 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12829 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12830 }
12831 [(set_attr "type" "multi")])
12832
12833 ;; GNU2 TLS patterns can be split.
12834
12835 (define_expand "tls_dynamic_gnu2_32"
12836 [(set (match_dup 3)
12837 (plus:SI (match_operand:SI 2 "register_operand" "")
12838 (const:SI
12839 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12840 UNSPEC_TLSDESC))))
12841 (parallel
12842 [(set (match_operand:SI 0 "register_operand" "")
12843 (unspec:SI [(match_dup 1) (match_dup 3)
12844 (match_dup 2) (reg:SI SP_REG)]
12845 UNSPEC_TLSDESC))
12846 (clobber (reg:CC FLAGS_REG))])]
12847 "!TARGET_64BIT && TARGET_GNU2_TLS"
12848 {
12849 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12850 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12851 })
12852
12853 (define_insn "*tls_dynamic_gnu2_lea_32"
12854 [(set (match_operand:SI 0 "register_operand" "=r")
12855 (plus:SI (match_operand:SI 1 "register_operand" "b")
12856 (const:SI
12857 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12858 UNSPEC_TLSDESC))))]
12859 "!TARGET_64BIT && TARGET_GNU2_TLS"
12860 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12861 [(set_attr "type" "lea")
12862 (set_attr "mode" "SI")
12863 (set_attr "length" "6")
12864 (set_attr "length_address" "4")])
12865
12866 (define_insn "*tls_dynamic_gnu2_call_32"
12867 [(set (match_operand:SI 0 "register_operand" "=a")
12868 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12869 (match_operand:SI 2 "register_operand" "0")
12870 ;; we have to make sure %ebx still points to the GOT
12871 (match_operand:SI 3 "register_operand" "b")
12872 (reg:SI SP_REG)]
12873 UNSPEC_TLSDESC))
12874 (clobber (reg:CC FLAGS_REG))]
12875 "!TARGET_64BIT && TARGET_GNU2_TLS"
12876 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12877 [(set_attr "type" "call")
12878 (set_attr "length" "2")
12879 (set_attr "length_address" "0")])
12880
12881 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12882 [(set (match_operand:SI 0 "register_operand" "=&a")
12883 (plus:SI
12884 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12885 (match_operand:SI 4 "" "")
12886 (match_operand:SI 2 "register_operand" "b")
12887 (reg:SI SP_REG)]
12888 UNSPEC_TLSDESC)
12889 (const:SI (unspec:SI
12890 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12891 UNSPEC_DTPOFF))))
12892 (clobber (reg:CC FLAGS_REG))]
12893 "!TARGET_64BIT && TARGET_GNU2_TLS"
12894 "#"
12895 ""
12896 [(set (match_dup 0) (match_dup 5))]
12897 {
12898 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12899 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12900 })
12901
12902 (define_expand "tls_dynamic_gnu2_64"
12903 [(set (match_dup 2)
12904 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12905 UNSPEC_TLSDESC))
12906 (parallel
12907 [(set (match_operand:DI 0 "register_operand" "")
12908 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12909 UNSPEC_TLSDESC))
12910 (clobber (reg:CC FLAGS_REG))])]
12911 "TARGET_64BIT && TARGET_GNU2_TLS"
12912 {
12913 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12914 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12915 })
12916
12917 (define_insn "*tls_dynamic_gnu2_lea_64"
12918 [(set (match_operand:DI 0 "register_operand" "=r")
12919 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12920 UNSPEC_TLSDESC))]
12921 "TARGET_64BIT && TARGET_GNU2_TLS"
12922 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12923 [(set_attr "type" "lea")
12924 (set_attr "mode" "DI")
12925 (set_attr "length" "7")
12926 (set_attr "length_address" "4")])
12927
12928 (define_insn "*tls_dynamic_gnu2_call_64"
12929 [(set (match_operand:DI 0 "register_operand" "=a")
12930 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12931 (match_operand:DI 2 "register_operand" "0")
12932 (reg:DI SP_REG)]
12933 UNSPEC_TLSDESC))
12934 (clobber (reg:CC FLAGS_REG))]
12935 "TARGET_64BIT && TARGET_GNU2_TLS"
12936 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12937 [(set_attr "type" "call")
12938 (set_attr "length" "2")
12939 (set_attr "length_address" "0")])
12940
12941 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12942 [(set (match_operand:DI 0 "register_operand" "=&a")
12943 (plus:DI
12944 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12945 (match_operand:DI 3 "" "")
12946 (reg:DI SP_REG)]
12947 UNSPEC_TLSDESC)
12948 (const:DI (unspec:DI
12949 [(match_operand 1 "tls_symbolic_operand" "")]
12950 UNSPEC_DTPOFF))))
12951 (clobber (reg:CC FLAGS_REG))]
12952 "TARGET_64BIT && TARGET_GNU2_TLS"
12953 "#"
12954 ""
12955 [(set (match_dup 0) (match_dup 4))]
12956 {
12957 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12958 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12959 })
12960 \f
12961 ;; These patterns match the binary 387 instructions for addM3, subM3,
12962 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12963 ;; SFmode. The first is the normal insn, the second the same insn but
12964 ;; with one operand a conversion, and the third the same insn but with
12965 ;; the other operand a conversion. The conversion may be SFmode or
12966 ;; SImode if the target mode DFmode, but only SImode if the target mode
12967 ;; is SFmode.
12968
12969 ;; Gcc is slightly more smart about handling normal two address instructions
12970 ;; so use special patterns for add and mull.
12971
12972 (define_insn "*fop_<mode>_comm_mixed"
12973 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12974 (match_operator:MODEF 3 "binary_fp_operator"
12975 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12976 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12977 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12978 && COMMUTATIVE_ARITH_P (operands[3])
12979 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12980 "* return output_387_binary_op (insn, operands);"
12981 [(set (attr "type")
12982 (if_then_else (eq_attr "alternative" "1,2")
12983 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12984 (const_string "ssemul")
12985 (const_string "sseadd"))
12986 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12987 (const_string "fmul")
12988 (const_string "fop"))))
12989 (set_attr "isa" "*,noavx,avx")
12990 (set_attr "prefix" "orig,orig,vex")
12991 (set_attr "mode" "<MODE>")])
12992
12993 (define_insn "*fop_<mode>_comm_sse"
12994 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12995 (match_operator:MODEF 3 "binary_fp_operator"
12996 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12997 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12998 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12999 && COMMUTATIVE_ARITH_P (operands[3])
13000 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13001 "* return output_387_binary_op (insn, operands);"
13002 [(set (attr "type")
13003 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13004 (const_string "ssemul")
13005 (const_string "sseadd")))
13006 (set_attr "isa" "noavx,avx")
13007 (set_attr "prefix" "orig,vex")
13008 (set_attr "mode" "<MODE>")])
13009
13010 (define_insn "*fop_<mode>_comm_i387"
13011 [(set (match_operand:MODEF 0 "register_operand" "=f")
13012 (match_operator:MODEF 3 "binary_fp_operator"
13013 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13014 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13015 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13016 && COMMUTATIVE_ARITH_P (operands[3])
13017 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13018 "* return output_387_binary_op (insn, operands);"
13019 [(set (attr "type")
13020 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13021 (const_string "fmul")
13022 (const_string "fop")))
13023 (set_attr "mode" "<MODE>")])
13024
13025 (define_insn "*fop_<mode>_1_mixed"
13026 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13027 (match_operator:MODEF 3 "binary_fp_operator"
13028 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13029 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13030 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13031 && !COMMUTATIVE_ARITH_P (operands[3])
13032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13033 "* return output_387_binary_op (insn, operands);"
13034 [(set (attr "type")
13035 (cond [(and (eq_attr "alternative" "2,3")
13036 (match_operand:MODEF 3 "mult_operator" ""))
13037 (const_string "ssemul")
13038 (and (eq_attr "alternative" "2,3")
13039 (match_operand:MODEF 3 "div_operator" ""))
13040 (const_string "ssediv")
13041 (eq_attr "alternative" "2,3")
13042 (const_string "sseadd")
13043 (match_operand:MODEF 3 "mult_operator" "")
13044 (const_string "fmul")
13045 (match_operand:MODEF 3 "div_operator" "")
13046 (const_string "fdiv")
13047 ]
13048 (const_string "fop")))
13049 (set_attr "isa" "*,*,noavx,avx")
13050 (set_attr "prefix" "orig,orig,orig,vex")
13051 (set_attr "mode" "<MODE>")])
13052
13053 (define_insn "*rcpsf2_sse"
13054 [(set (match_operand:SF 0 "register_operand" "=x")
13055 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13056 UNSPEC_RCP))]
13057 "TARGET_SSE_MATH"
13058 "%vrcpss\t{%1, %d0|%d0, %1}"
13059 [(set_attr "type" "sse")
13060 (set_attr "atom_sse_attr" "rcp")
13061 (set_attr "prefix" "maybe_vex")
13062 (set_attr "mode" "SF")])
13063
13064 (define_insn "*fop_<mode>_1_sse"
13065 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13066 (match_operator:MODEF 3 "binary_fp_operator"
13067 [(match_operand:MODEF 1 "register_operand" "0,x")
13068 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13069 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13070 && !COMMUTATIVE_ARITH_P (operands[3])"
13071 "* return output_387_binary_op (insn, operands);"
13072 [(set (attr "type")
13073 (cond [(match_operand:MODEF 3 "mult_operator" "")
13074 (const_string "ssemul")
13075 (match_operand:MODEF 3 "div_operator" "")
13076 (const_string "ssediv")
13077 ]
13078 (const_string "sseadd")))
13079 (set_attr "isa" "noavx,avx")
13080 (set_attr "prefix" "orig,vex")
13081 (set_attr "mode" "<MODE>")])
13082
13083 ;; This pattern is not fully shadowed by the pattern above.
13084 (define_insn "*fop_<mode>_1_i387"
13085 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13086 (match_operator:MODEF 3 "binary_fp_operator"
13087 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13088 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13089 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13090 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13091 && !COMMUTATIVE_ARITH_P (operands[3])
13092 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13093 "* return output_387_binary_op (insn, operands);"
13094 [(set (attr "type")
13095 (cond [(match_operand:MODEF 3 "mult_operator" "")
13096 (const_string "fmul")
13097 (match_operand:MODEF 3 "div_operator" "")
13098 (const_string "fdiv")
13099 ]
13100 (const_string "fop")))
13101 (set_attr "mode" "<MODE>")])
13102
13103 ;; ??? Add SSE splitters for these!
13104 (define_insn "*fop_<MODEF:mode>_2_i387"
13105 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13106 (match_operator:MODEF 3 "binary_fp_operator"
13107 [(float:MODEF
13108 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13109 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13110 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13111 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13112 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13113 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13114 [(set (attr "type")
13115 (cond [(match_operand:MODEF 3 "mult_operator" "")
13116 (const_string "fmul")
13117 (match_operand:MODEF 3 "div_operator" "")
13118 (const_string "fdiv")
13119 ]
13120 (const_string "fop")))
13121 (set_attr "fp_int_src" "true")
13122 (set_attr "mode" "<SWI24:MODE>")])
13123
13124 (define_insn "*fop_<MODEF:mode>_3_i387"
13125 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13126 (match_operator:MODEF 3 "binary_fp_operator"
13127 [(match_operand:MODEF 1 "register_operand" "0,0")
13128 (float:MODEF
13129 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13130 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13131 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13132 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13133 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13134 [(set (attr "type")
13135 (cond [(match_operand:MODEF 3 "mult_operator" "")
13136 (const_string "fmul")
13137 (match_operand:MODEF 3 "div_operator" "")
13138 (const_string "fdiv")
13139 ]
13140 (const_string "fop")))
13141 (set_attr "fp_int_src" "true")
13142 (set_attr "mode" "<MODE>")])
13143
13144 (define_insn "*fop_df_4_i387"
13145 [(set (match_operand:DF 0 "register_operand" "=f,f")
13146 (match_operator:DF 3 "binary_fp_operator"
13147 [(float_extend:DF
13148 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13149 (match_operand:DF 2 "register_operand" "0,f")]))]
13150 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13151 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13152 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13153 "* return output_387_binary_op (insn, operands);"
13154 [(set (attr "type")
13155 (cond [(match_operand:DF 3 "mult_operator" "")
13156 (const_string "fmul")
13157 (match_operand:DF 3 "div_operator" "")
13158 (const_string "fdiv")
13159 ]
13160 (const_string "fop")))
13161 (set_attr "mode" "SF")])
13162
13163 (define_insn "*fop_df_5_i387"
13164 [(set (match_operand:DF 0 "register_operand" "=f,f")
13165 (match_operator:DF 3 "binary_fp_operator"
13166 [(match_operand:DF 1 "register_operand" "0,f")
13167 (float_extend:DF
13168 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13169 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13170 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13171 "* return output_387_binary_op (insn, operands);"
13172 [(set (attr "type")
13173 (cond [(match_operand:DF 3 "mult_operator" "")
13174 (const_string "fmul")
13175 (match_operand:DF 3 "div_operator" "")
13176 (const_string "fdiv")
13177 ]
13178 (const_string "fop")))
13179 (set_attr "mode" "SF")])
13180
13181 (define_insn "*fop_df_6_i387"
13182 [(set (match_operand:DF 0 "register_operand" "=f,f")
13183 (match_operator:DF 3 "binary_fp_operator"
13184 [(float_extend:DF
13185 (match_operand:SF 1 "register_operand" "0,f"))
13186 (float_extend:DF
13187 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13188 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13189 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13190 "* return output_387_binary_op (insn, operands);"
13191 [(set (attr "type")
13192 (cond [(match_operand:DF 3 "mult_operator" "")
13193 (const_string "fmul")
13194 (match_operand:DF 3 "div_operator" "")
13195 (const_string "fdiv")
13196 ]
13197 (const_string "fop")))
13198 (set_attr "mode" "SF")])
13199
13200 (define_insn "*fop_xf_comm_i387"
13201 [(set (match_operand:XF 0 "register_operand" "=f")
13202 (match_operator:XF 3 "binary_fp_operator"
13203 [(match_operand:XF 1 "register_operand" "%0")
13204 (match_operand:XF 2 "register_operand" "f")]))]
13205 "TARGET_80387
13206 && COMMUTATIVE_ARITH_P (operands[3])"
13207 "* return output_387_binary_op (insn, operands);"
13208 [(set (attr "type")
13209 (if_then_else (match_operand:XF 3 "mult_operator" "")
13210 (const_string "fmul")
13211 (const_string "fop")))
13212 (set_attr "mode" "XF")])
13213
13214 (define_insn "*fop_xf_1_i387"
13215 [(set (match_operand:XF 0 "register_operand" "=f,f")
13216 (match_operator:XF 3 "binary_fp_operator"
13217 [(match_operand:XF 1 "register_operand" "0,f")
13218 (match_operand:XF 2 "register_operand" "f,0")]))]
13219 "TARGET_80387
13220 && !COMMUTATIVE_ARITH_P (operands[3])"
13221 "* return output_387_binary_op (insn, operands);"
13222 [(set (attr "type")
13223 (cond [(match_operand:XF 3 "mult_operator" "")
13224 (const_string "fmul")
13225 (match_operand:XF 3 "div_operator" "")
13226 (const_string "fdiv")
13227 ]
13228 (const_string "fop")))
13229 (set_attr "mode" "XF")])
13230
13231 (define_insn "*fop_xf_2_i387"
13232 [(set (match_operand:XF 0 "register_operand" "=f,f")
13233 (match_operator:XF 3 "binary_fp_operator"
13234 [(float:XF
13235 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13236 (match_operand:XF 2 "register_operand" "0,0")]))]
13237 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13238 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13239 [(set (attr "type")
13240 (cond [(match_operand:XF 3 "mult_operator" "")
13241 (const_string "fmul")
13242 (match_operand:XF 3 "div_operator" "")
13243 (const_string "fdiv")
13244 ]
13245 (const_string "fop")))
13246 (set_attr "fp_int_src" "true")
13247 (set_attr "mode" "<MODE>")])
13248
13249 (define_insn "*fop_xf_3_i387"
13250 [(set (match_operand:XF 0 "register_operand" "=f,f")
13251 (match_operator:XF 3 "binary_fp_operator"
13252 [(match_operand:XF 1 "register_operand" "0,0")
13253 (float:XF
13254 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13255 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13256 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13257 [(set (attr "type")
13258 (cond [(match_operand:XF 3 "mult_operator" "")
13259 (const_string "fmul")
13260 (match_operand:XF 3 "div_operator" "")
13261 (const_string "fdiv")
13262 ]
13263 (const_string "fop")))
13264 (set_attr "fp_int_src" "true")
13265 (set_attr "mode" "<MODE>")])
13266
13267 (define_insn "*fop_xf_4_i387"
13268 [(set (match_operand:XF 0 "register_operand" "=f,f")
13269 (match_operator:XF 3 "binary_fp_operator"
13270 [(float_extend:XF
13271 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13272 (match_operand:XF 2 "register_operand" "0,f")]))]
13273 "TARGET_80387"
13274 "* return output_387_binary_op (insn, operands);"
13275 [(set (attr "type")
13276 (cond [(match_operand:XF 3 "mult_operator" "")
13277 (const_string "fmul")
13278 (match_operand:XF 3 "div_operator" "")
13279 (const_string "fdiv")
13280 ]
13281 (const_string "fop")))
13282 (set_attr "mode" "<MODE>")])
13283
13284 (define_insn "*fop_xf_5_i387"
13285 [(set (match_operand:XF 0 "register_operand" "=f,f")
13286 (match_operator:XF 3 "binary_fp_operator"
13287 [(match_operand:XF 1 "register_operand" "0,f")
13288 (float_extend:XF
13289 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13290 "TARGET_80387"
13291 "* return output_387_binary_op (insn, operands);"
13292 [(set (attr "type")
13293 (cond [(match_operand:XF 3 "mult_operator" "")
13294 (const_string "fmul")
13295 (match_operand:XF 3 "div_operator" "")
13296 (const_string "fdiv")
13297 ]
13298 (const_string "fop")))
13299 (set_attr "mode" "<MODE>")])
13300
13301 (define_insn "*fop_xf_6_i387"
13302 [(set (match_operand:XF 0 "register_operand" "=f,f")
13303 (match_operator:XF 3 "binary_fp_operator"
13304 [(float_extend:XF
13305 (match_operand:MODEF 1 "register_operand" "0,f"))
13306 (float_extend:XF
13307 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13308 "TARGET_80387"
13309 "* return output_387_binary_op (insn, operands);"
13310 [(set (attr "type")
13311 (cond [(match_operand:XF 3 "mult_operator" "")
13312 (const_string "fmul")
13313 (match_operand:XF 3 "div_operator" "")
13314 (const_string "fdiv")
13315 ]
13316 (const_string "fop")))
13317 (set_attr "mode" "<MODE>")])
13318
13319 (define_split
13320 [(set (match_operand 0 "register_operand" "")
13321 (match_operator 3 "binary_fp_operator"
13322 [(float (match_operand:SWI24 1 "register_operand" ""))
13323 (match_operand 2 "register_operand" "")]))]
13324 "reload_completed
13325 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13326 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13327 [(const_int 0)]
13328 {
13329 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13330 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13331 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13332 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13333 GET_MODE (operands[3]),
13334 operands[4],
13335 operands[2])));
13336 ix86_free_from_memory (GET_MODE (operands[1]));
13337 DONE;
13338 })
13339
13340 (define_split
13341 [(set (match_operand 0 "register_operand" "")
13342 (match_operator 3 "binary_fp_operator"
13343 [(match_operand 1 "register_operand" "")
13344 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13345 "reload_completed
13346 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13347 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13348 [(const_int 0)]
13349 {
13350 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13351 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13352 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13353 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13354 GET_MODE (operands[3]),
13355 operands[1],
13356 operands[4])));
13357 ix86_free_from_memory (GET_MODE (operands[2]));
13358 DONE;
13359 })
13360 \f
13361 ;; FPU special functions.
13362
13363 ;; This pattern implements a no-op XFmode truncation for
13364 ;; all fancy i386 XFmode math functions.
13365
13366 (define_insn "truncxf<mode>2_i387_noop_unspec"
13367 [(set (match_operand:MODEF 0 "register_operand" "=f")
13368 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13369 UNSPEC_TRUNC_NOOP))]
13370 "TARGET_USE_FANCY_MATH_387"
13371 "* return output_387_reg_move (insn, operands);"
13372 [(set_attr "type" "fmov")
13373 (set_attr "mode" "<MODE>")])
13374
13375 (define_insn "sqrtxf2"
13376 [(set (match_operand:XF 0 "register_operand" "=f")
13377 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13378 "TARGET_USE_FANCY_MATH_387"
13379 "fsqrt"
13380 [(set_attr "type" "fpspc")
13381 (set_attr "mode" "XF")
13382 (set_attr "athlon_decode" "direct")
13383 (set_attr "amdfam10_decode" "direct")
13384 (set_attr "bdver1_decode" "direct")])
13385
13386 (define_insn "sqrt_extend<mode>xf2_i387"
13387 [(set (match_operand:XF 0 "register_operand" "=f")
13388 (sqrt:XF
13389 (float_extend:XF
13390 (match_operand:MODEF 1 "register_operand" "0"))))]
13391 "TARGET_USE_FANCY_MATH_387"
13392 "fsqrt"
13393 [(set_attr "type" "fpspc")
13394 (set_attr "mode" "XF")
13395 (set_attr "athlon_decode" "direct")
13396 (set_attr "amdfam10_decode" "direct")
13397 (set_attr "bdver1_decode" "direct")])
13398
13399 (define_insn "*rsqrtsf2_sse"
13400 [(set (match_operand:SF 0 "register_operand" "=x")
13401 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13402 UNSPEC_RSQRT))]
13403 "TARGET_SSE_MATH"
13404 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13405 [(set_attr "type" "sse")
13406 (set_attr "atom_sse_attr" "rcp")
13407 (set_attr "prefix" "maybe_vex")
13408 (set_attr "mode" "SF")])
13409
13410 (define_expand "rsqrtsf2"
13411 [(set (match_operand:SF 0 "register_operand" "")
13412 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13413 UNSPEC_RSQRT))]
13414 "TARGET_SSE_MATH"
13415 {
13416 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13417 DONE;
13418 })
13419
13420 (define_insn "*sqrt<mode>2_sse"
13421 [(set (match_operand:MODEF 0 "register_operand" "=x")
13422 (sqrt:MODEF
13423 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13424 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13425 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13426 [(set_attr "type" "sse")
13427 (set_attr "atom_sse_attr" "sqrt")
13428 (set_attr "prefix" "maybe_vex")
13429 (set_attr "mode" "<MODE>")
13430 (set_attr "athlon_decode" "*")
13431 (set_attr "amdfam10_decode" "*")
13432 (set_attr "bdver1_decode" "*")])
13433
13434 (define_expand "sqrt<mode>2"
13435 [(set (match_operand:MODEF 0 "register_operand" "")
13436 (sqrt:MODEF
13437 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13438 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13439 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13440 {
13441 if (<MODE>mode == SFmode
13442 && TARGET_SSE_MATH
13443 && TARGET_RECIP_SQRT
13444 && !optimize_function_for_size_p (cfun)
13445 && flag_finite_math_only && !flag_trapping_math
13446 && flag_unsafe_math_optimizations)
13447 {
13448 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13449 DONE;
13450 }
13451
13452 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13453 {
13454 rtx op0 = gen_reg_rtx (XFmode);
13455 rtx op1 = force_reg (<MODE>mode, operands[1]);
13456
13457 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13458 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13459 DONE;
13460 }
13461 })
13462
13463 (define_insn "fpremxf4_i387"
13464 [(set (match_operand:XF 0 "register_operand" "=f")
13465 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13466 (match_operand:XF 3 "register_operand" "1")]
13467 UNSPEC_FPREM_F))
13468 (set (match_operand:XF 1 "register_operand" "=u")
13469 (unspec:XF [(match_dup 2) (match_dup 3)]
13470 UNSPEC_FPREM_U))
13471 (set (reg:CCFP FPSR_REG)
13472 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13473 UNSPEC_C2_FLAG))]
13474 "TARGET_USE_FANCY_MATH_387"
13475 "fprem"
13476 [(set_attr "type" "fpspc")
13477 (set_attr "mode" "XF")])
13478
13479 (define_expand "fmodxf3"
13480 [(use (match_operand:XF 0 "register_operand" ""))
13481 (use (match_operand:XF 1 "general_operand" ""))
13482 (use (match_operand:XF 2 "general_operand" ""))]
13483 "TARGET_USE_FANCY_MATH_387"
13484 {
13485 rtx label = gen_label_rtx ();
13486
13487 rtx op1 = gen_reg_rtx (XFmode);
13488 rtx op2 = gen_reg_rtx (XFmode);
13489
13490 emit_move_insn (op2, operands[2]);
13491 emit_move_insn (op1, operands[1]);
13492
13493 emit_label (label);
13494 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13495 ix86_emit_fp_unordered_jump (label);
13496 LABEL_NUSES (label) = 1;
13497
13498 emit_move_insn (operands[0], op1);
13499 DONE;
13500 })
13501
13502 (define_expand "fmod<mode>3"
13503 [(use (match_operand:MODEF 0 "register_operand" ""))
13504 (use (match_operand:MODEF 1 "general_operand" ""))
13505 (use (match_operand:MODEF 2 "general_operand" ""))]
13506 "TARGET_USE_FANCY_MATH_387"
13507 {
13508 rtx (*gen_truncxf) (rtx, rtx);
13509
13510 rtx label = gen_label_rtx ();
13511
13512 rtx op1 = gen_reg_rtx (XFmode);
13513 rtx op2 = gen_reg_rtx (XFmode);
13514
13515 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13516 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13517
13518 emit_label (label);
13519 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13520 ix86_emit_fp_unordered_jump (label);
13521 LABEL_NUSES (label) = 1;
13522
13523 /* Truncate the result properly for strict SSE math. */
13524 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13525 && !TARGET_MIX_SSE_I387)
13526 gen_truncxf = gen_truncxf<mode>2;
13527 else
13528 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13529
13530 emit_insn (gen_truncxf (operands[0], op1));
13531 DONE;
13532 })
13533
13534 (define_insn "fprem1xf4_i387"
13535 [(set (match_operand:XF 0 "register_operand" "=f")
13536 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13537 (match_operand:XF 3 "register_operand" "1")]
13538 UNSPEC_FPREM1_F))
13539 (set (match_operand:XF 1 "register_operand" "=u")
13540 (unspec:XF [(match_dup 2) (match_dup 3)]
13541 UNSPEC_FPREM1_U))
13542 (set (reg:CCFP FPSR_REG)
13543 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13544 UNSPEC_C2_FLAG))]
13545 "TARGET_USE_FANCY_MATH_387"
13546 "fprem1"
13547 [(set_attr "type" "fpspc")
13548 (set_attr "mode" "XF")])
13549
13550 (define_expand "remainderxf3"
13551 [(use (match_operand:XF 0 "register_operand" ""))
13552 (use (match_operand:XF 1 "general_operand" ""))
13553 (use (match_operand:XF 2 "general_operand" ""))]
13554 "TARGET_USE_FANCY_MATH_387"
13555 {
13556 rtx label = gen_label_rtx ();
13557
13558 rtx op1 = gen_reg_rtx (XFmode);
13559 rtx op2 = gen_reg_rtx (XFmode);
13560
13561 emit_move_insn (op2, operands[2]);
13562 emit_move_insn (op1, operands[1]);
13563
13564 emit_label (label);
13565 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13566 ix86_emit_fp_unordered_jump (label);
13567 LABEL_NUSES (label) = 1;
13568
13569 emit_move_insn (operands[0], op1);
13570 DONE;
13571 })
13572
13573 (define_expand "remainder<mode>3"
13574 [(use (match_operand:MODEF 0 "register_operand" ""))
13575 (use (match_operand:MODEF 1 "general_operand" ""))
13576 (use (match_operand:MODEF 2 "general_operand" ""))]
13577 "TARGET_USE_FANCY_MATH_387"
13578 {
13579 rtx (*gen_truncxf) (rtx, rtx);
13580
13581 rtx label = gen_label_rtx ();
13582
13583 rtx op1 = gen_reg_rtx (XFmode);
13584 rtx op2 = gen_reg_rtx (XFmode);
13585
13586 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13587 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13588
13589 emit_label (label);
13590
13591 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13592 ix86_emit_fp_unordered_jump (label);
13593 LABEL_NUSES (label) = 1;
13594
13595 /* Truncate the result properly for strict SSE math. */
13596 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13597 && !TARGET_MIX_SSE_I387)
13598 gen_truncxf = gen_truncxf<mode>2;
13599 else
13600 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13601
13602 emit_insn (gen_truncxf (operands[0], op1));
13603 DONE;
13604 })
13605
13606 (define_insn "*sinxf2_i387"
13607 [(set (match_operand:XF 0 "register_operand" "=f")
13608 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13609 "TARGET_USE_FANCY_MATH_387
13610 && flag_unsafe_math_optimizations"
13611 "fsin"
13612 [(set_attr "type" "fpspc")
13613 (set_attr "mode" "XF")])
13614
13615 (define_insn "*sin_extend<mode>xf2_i387"
13616 [(set (match_operand:XF 0 "register_operand" "=f")
13617 (unspec:XF [(float_extend:XF
13618 (match_operand:MODEF 1 "register_operand" "0"))]
13619 UNSPEC_SIN))]
13620 "TARGET_USE_FANCY_MATH_387
13621 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13622 || TARGET_MIX_SSE_I387)
13623 && flag_unsafe_math_optimizations"
13624 "fsin"
13625 [(set_attr "type" "fpspc")
13626 (set_attr "mode" "XF")])
13627
13628 (define_insn "*cosxf2_i387"
13629 [(set (match_operand:XF 0 "register_operand" "=f")
13630 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13631 "TARGET_USE_FANCY_MATH_387
13632 && flag_unsafe_math_optimizations"
13633 "fcos"
13634 [(set_attr "type" "fpspc")
13635 (set_attr "mode" "XF")])
13636
13637 (define_insn "*cos_extend<mode>xf2_i387"
13638 [(set (match_operand:XF 0 "register_operand" "=f")
13639 (unspec:XF [(float_extend:XF
13640 (match_operand:MODEF 1 "register_operand" "0"))]
13641 UNSPEC_COS))]
13642 "TARGET_USE_FANCY_MATH_387
13643 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13644 || TARGET_MIX_SSE_I387)
13645 && flag_unsafe_math_optimizations"
13646 "fcos"
13647 [(set_attr "type" "fpspc")
13648 (set_attr "mode" "XF")])
13649
13650 ;; When sincos pattern is defined, sin and cos builtin functions will be
13651 ;; expanded to sincos pattern with one of its outputs left unused.
13652 ;; CSE pass will figure out if two sincos patterns can be combined,
13653 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13654 ;; depending on the unused output.
13655
13656 (define_insn "sincosxf3"
13657 [(set (match_operand:XF 0 "register_operand" "=f")
13658 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13659 UNSPEC_SINCOS_COS))
13660 (set (match_operand:XF 1 "register_operand" "=u")
13661 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13662 "TARGET_USE_FANCY_MATH_387
13663 && flag_unsafe_math_optimizations"
13664 "fsincos"
13665 [(set_attr "type" "fpspc")
13666 (set_attr "mode" "XF")])
13667
13668 (define_split
13669 [(set (match_operand:XF 0 "register_operand" "")
13670 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13671 UNSPEC_SINCOS_COS))
13672 (set (match_operand:XF 1 "register_operand" "")
13673 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13674 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13675 && can_create_pseudo_p ()"
13676 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13677
13678 (define_split
13679 [(set (match_operand:XF 0 "register_operand" "")
13680 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13681 UNSPEC_SINCOS_COS))
13682 (set (match_operand:XF 1 "register_operand" "")
13683 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13684 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13685 && can_create_pseudo_p ()"
13686 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13687
13688 (define_insn "sincos_extend<mode>xf3_i387"
13689 [(set (match_operand:XF 0 "register_operand" "=f")
13690 (unspec:XF [(float_extend:XF
13691 (match_operand:MODEF 2 "register_operand" "0"))]
13692 UNSPEC_SINCOS_COS))
13693 (set (match_operand:XF 1 "register_operand" "=u")
13694 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13695 "TARGET_USE_FANCY_MATH_387
13696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13697 || TARGET_MIX_SSE_I387)
13698 && flag_unsafe_math_optimizations"
13699 "fsincos"
13700 [(set_attr "type" "fpspc")
13701 (set_attr "mode" "XF")])
13702
13703 (define_split
13704 [(set (match_operand:XF 0 "register_operand" "")
13705 (unspec:XF [(float_extend:XF
13706 (match_operand:MODEF 2 "register_operand" ""))]
13707 UNSPEC_SINCOS_COS))
13708 (set (match_operand:XF 1 "register_operand" "")
13709 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13710 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13711 && can_create_pseudo_p ()"
13712 [(set (match_dup 1)
13713 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13714
13715 (define_split
13716 [(set (match_operand:XF 0 "register_operand" "")
13717 (unspec:XF [(float_extend:XF
13718 (match_operand:MODEF 2 "register_operand" ""))]
13719 UNSPEC_SINCOS_COS))
13720 (set (match_operand:XF 1 "register_operand" "")
13721 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13722 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13723 && can_create_pseudo_p ()"
13724 [(set (match_dup 0)
13725 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13726
13727 (define_expand "sincos<mode>3"
13728 [(use (match_operand:MODEF 0 "register_operand" ""))
13729 (use (match_operand:MODEF 1 "register_operand" ""))
13730 (use (match_operand:MODEF 2 "register_operand" ""))]
13731 "TARGET_USE_FANCY_MATH_387
13732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13733 || TARGET_MIX_SSE_I387)
13734 && flag_unsafe_math_optimizations"
13735 {
13736 rtx op0 = gen_reg_rtx (XFmode);
13737 rtx op1 = gen_reg_rtx (XFmode);
13738
13739 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13740 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13741 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13742 DONE;
13743 })
13744
13745 (define_insn "fptanxf4_i387"
13746 [(set (match_operand:XF 0 "register_operand" "=f")
13747 (match_operand:XF 3 "const_double_operand" "F"))
13748 (set (match_operand:XF 1 "register_operand" "=u")
13749 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13750 UNSPEC_TAN))]
13751 "TARGET_USE_FANCY_MATH_387
13752 && flag_unsafe_math_optimizations
13753 && standard_80387_constant_p (operands[3]) == 2"
13754 "fptan"
13755 [(set_attr "type" "fpspc")
13756 (set_attr "mode" "XF")])
13757
13758 (define_insn "fptan_extend<mode>xf4_i387"
13759 [(set (match_operand:MODEF 0 "register_operand" "=f")
13760 (match_operand:MODEF 3 "const_double_operand" "F"))
13761 (set (match_operand:XF 1 "register_operand" "=u")
13762 (unspec:XF [(float_extend:XF
13763 (match_operand:MODEF 2 "register_operand" "0"))]
13764 UNSPEC_TAN))]
13765 "TARGET_USE_FANCY_MATH_387
13766 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13767 || TARGET_MIX_SSE_I387)
13768 && flag_unsafe_math_optimizations
13769 && standard_80387_constant_p (operands[3]) == 2"
13770 "fptan"
13771 [(set_attr "type" "fpspc")
13772 (set_attr "mode" "XF")])
13773
13774 (define_expand "tanxf2"
13775 [(use (match_operand:XF 0 "register_operand" ""))
13776 (use (match_operand:XF 1 "register_operand" ""))]
13777 "TARGET_USE_FANCY_MATH_387
13778 && flag_unsafe_math_optimizations"
13779 {
13780 rtx one = gen_reg_rtx (XFmode);
13781 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13782
13783 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13784 DONE;
13785 })
13786
13787 (define_expand "tan<mode>2"
13788 [(use (match_operand:MODEF 0 "register_operand" ""))
13789 (use (match_operand:MODEF 1 "register_operand" ""))]
13790 "TARGET_USE_FANCY_MATH_387
13791 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13792 || TARGET_MIX_SSE_I387)
13793 && flag_unsafe_math_optimizations"
13794 {
13795 rtx op0 = gen_reg_rtx (XFmode);
13796
13797 rtx one = gen_reg_rtx (<MODE>mode);
13798 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13799
13800 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13801 operands[1], op2));
13802 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13803 DONE;
13804 })
13805
13806 (define_insn "*fpatanxf3_i387"
13807 [(set (match_operand:XF 0 "register_operand" "=f")
13808 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13809 (match_operand:XF 2 "register_operand" "u")]
13810 UNSPEC_FPATAN))
13811 (clobber (match_scratch:XF 3 "=2"))]
13812 "TARGET_USE_FANCY_MATH_387
13813 && flag_unsafe_math_optimizations"
13814 "fpatan"
13815 [(set_attr "type" "fpspc")
13816 (set_attr "mode" "XF")])
13817
13818 (define_insn "fpatan_extend<mode>xf3_i387"
13819 [(set (match_operand:XF 0 "register_operand" "=f")
13820 (unspec:XF [(float_extend:XF
13821 (match_operand:MODEF 1 "register_operand" "0"))
13822 (float_extend:XF
13823 (match_operand:MODEF 2 "register_operand" "u"))]
13824 UNSPEC_FPATAN))
13825 (clobber (match_scratch:XF 3 "=2"))]
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 "fpatan"
13831 [(set_attr "type" "fpspc")
13832 (set_attr "mode" "XF")])
13833
13834 (define_expand "atan2xf3"
13835 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13836 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13837 (match_operand:XF 1 "register_operand" "")]
13838 UNSPEC_FPATAN))
13839 (clobber (match_scratch:XF 3 ""))])]
13840 "TARGET_USE_FANCY_MATH_387
13841 && flag_unsafe_math_optimizations")
13842
13843 (define_expand "atan2<mode>3"
13844 [(use (match_operand:MODEF 0 "register_operand" ""))
13845 (use (match_operand:MODEF 1 "register_operand" ""))
13846 (use (match_operand:MODEF 2 "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
13854 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13855 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13856 DONE;
13857 })
13858
13859 (define_expand "atanxf2"
13860 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13861 (unspec:XF [(match_dup 2)
13862 (match_operand:XF 1 "register_operand" "")]
13863 UNSPEC_FPATAN))
13864 (clobber (match_scratch:XF 3 ""))])]
13865 "TARGET_USE_FANCY_MATH_387
13866 && flag_unsafe_math_optimizations"
13867 {
13868 operands[2] = gen_reg_rtx (XFmode);
13869 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13870 })
13871
13872 (define_expand "atan<mode>2"
13873 [(use (match_operand:MODEF 0 "register_operand" ""))
13874 (use (match_operand:MODEF 1 "register_operand" ""))]
13875 "TARGET_USE_FANCY_MATH_387
13876 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13877 || TARGET_MIX_SSE_I387)
13878 && flag_unsafe_math_optimizations"
13879 {
13880 rtx op0 = gen_reg_rtx (XFmode);
13881
13882 rtx op2 = gen_reg_rtx (<MODE>mode);
13883 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13884
13885 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13886 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13887 DONE;
13888 })
13889
13890 (define_expand "asinxf2"
13891 [(set (match_dup 2)
13892 (mult:XF (match_operand:XF 1 "register_operand" "")
13893 (match_dup 1)))
13894 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13895 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13896 (parallel [(set (match_operand:XF 0 "register_operand" "")
13897 (unspec:XF [(match_dup 5) (match_dup 1)]
13898 UNSPEC_FPATAN))
13899 (clobber (match_scratch:XF 6 ""))])]
13900 "TARGET_USE_FANCY_MATH_387
13901 && flag_unsafe_math_optimizations"
13902 {
13903 int i;
13904
13905 if (optimize_insn_for_size_p ())
13906 FAIL;
13907
13908 for (i = 2; i < 6; i++)
13909 operands[i] = gen_reg_rtx (XFmode);
13910
13911 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13912 })
13913
13914 (define_expand "asin<mode>2"
13915 [(use (match_operand:MODEF 0 "register_operand" ""))
13916 (use (match_operand:MODEF 1 "general_operand" ""))]
13917 "TARGET_USE_FANCY_MATH_387
13918 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13919 || TARGET_MIX_SSE_I387)
13920 && flag_unsafe_math_optimizations"
13921 {
13922 rtx op0 = gen_reg_rtx (XFmode);
13923 rtx op1 = gen_reg_rtx (XFmode);
13924
13925 if (optimize_insn_for_size_p ())
13926 FAIL;
13927
13928 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13929 emit_insn (gen_asinxf2 (op0, op1));
13930 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13931 DONE;
13932 })
13933
13934 (define_expand "acosxf2"
13935 [(set (match_dup 2)
13936 (mult:XF (match_operand:XF 1 "register_operand" "")
13937 (match_dup 1)))
13938 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13939 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13940 (parallel [(set (match_operand:XF 0 "register_operand" "")
13941 (unspec:XF [(match_dup 1) (match_dup 5)]
13942 UNSPEC_FPATAN))
13943 (clobber (match_scratch:XF 6 ""))])]
13944 "TARGET_USE_FANCY_MATH_387
13945 && flag_unsafe_math_optimizations"
13946 {
13947 int i;
13948
13949 if (optimize_insn_for_size_p ())
13950 FAIL;
13951
13952 for (i = 2; i < 6; i++)
13953 operands[i] = gen_reg_rtx (XFmode);
13954
13955 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13956 })
13957
13958 (define_expand "acos<mode>2"
13959 [(use (match_operand:MODEF 0 "register_operand" ""))
13960 (use (match_operand:MODEF 1 "general_operand" ""))]
13961 "TARGET_USE_FANCY_MATH_387
13962 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13963 || TARGET_MIX_SSE_I387)
13964 && flag_unsafe_math_optimizations"
13965 {
13966 rtx op0 = gen_reg_rtx (XFmode);
13967 rtx op1 = gen_reg_rtx (XFmode);
13968
13969 if (optimize_insn_for_size_p ())
13970 FAIL;
13971
13972 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13973 emit_insn (gen_acosxf2 (op0, op1));
13974 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13975 DONE;
13976 })
13977
13978 (define_insn "fyl2xxf3_i387"
13979 [(set (match_operand:XF 0 "register_operand" "=f")
13980 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13981 (match_operand:XF 2 "register_operand" "u")]
13982 UNSPEC_FYL2X))
13983 (clobber (match_scratch:XF 3 "=2"))]
13984 "TARGET_USE_FANCY_MATH_387
13985 && flag_unsafe_math_optimizations"
13986 "fyl2x"
13987 [(set_attr "type" "fpspc")
13988 (set_attr "mode" "XF")])
13989
13990 (define_insn "fyl2x_extend<mode>xf3_i387"
13991 [(set (match_operand:XF 0 "register_operand" "=f")
13992 (unspec:XF [(float_extend:XF
13993 (match_operand:MODEF 1 "register_operand" "0"))
13994 (match_operand:XF 2 "register_operand" "u")]
13995 UNSPEC_FYL2X))
13996 (clobber (match_scratch:XF 3 "=2"))]
13997 "TARGET_USE_FANCY_MATH_387
13998 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13999 || TARGET_MIX_SSE_I387)
14000 && flag_unsafe_math_optimizations"
14001 "fyl2x"
14002 [(set_attr "type" "fpspc")
14003 (set_attr "mode" "XF")])
14004
14005 (define_expand "logxf2"
14006 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14007 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14008 (match_dup 2)] UNSPEC_FYL2X))
14009 (clobber (match_scratch:XF 3 ""))])]
14010 "TARGET_USE_FANCY_MATH_387
14011 && flag_unsafe_math_optimizations"
14012 {
14013 operands[2] = gen_reg_rtx (XFmode);
14014 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14015 })
14016
14017 (define_expand "log<mode>2"
14018 [(use (match_operand:MODEF 0 "register_operand" ""))
14019 (use (match_operand:MODEF 1 "register_operand" ""))]
14020 "TARGET_USE_FANCY_MATH_387
14021 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14022 || TARGET_MIX_SSE_I387)
14023 && flag_unsafe_math_optimizations"
14024 {
14025 rtx op0 = gen_reg_rtx (XFmode);
14026
14027 rtx op2 = gen_reg_rtx (XFmode);
14028 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14029
14030 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14031 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14032 DONE;
14033 })
14034
14035 (define_expand "log10xf2"
14036 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14037 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14038 (match_dup 2)] UNSPEC_FYL2X))
14039 (clobber (match_scratch:XF 3 ""))])]
14040 "TARGET_USE_FANCY_MATH_387
14041 && flag_unsafe_math_optimizations"
14042 {
14043 operands[2] = gen_reg_rtx (XFmode);
14044 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14045 })
14046
14047 (define_expand "log10<mode>2"
14048 [(use (match_operand:MODEF 0 "register_operand" ""))
14049 (use (match_operand:MODEF 1 "register_operand" ""))]
14050 "TARGET_USE_FANCY_MATH_387
14051 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14052 || TARGET_MIX_SSE_I387)
14053 && flag_unsafe_math_optimizations"
14054 {
14055 rtx op0 = gen_reg_rtx (XFmode);
14056
14057 rtx op2 = gen_reg_rtx (XFmode);
14058 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14059
14060 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14061 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14062 DONE;
14063 })
14064
14065 (define_expand "log2xf2"
14066 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14067 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14068 (match_dup 2)] UNSPEC_FYL2X))
14069 (clobber (match_scratch:XF 3 ""))])]
14070 "TARGET_USE_FANCY_MATH_387
14071 && flag_unsafe_math_optimizations"
14072 {
14073 operands[2] = gen_reg_rtx (XFmode);
14074 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14075 })
14076
14077 (define_expand "log2<mode>2"
14078 [(use (match_operand:MODEF 0 "register_operand" ""))
14079 (use (match_operand:MODEF 1 "register_operand" ""))]
14080 "TARGET_USE_FANCY_MATH_387
14081 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14082 || TARGET_MIX_SSE_I387)
14083 && flag_unsafe_math_optimizations"
14084 {
14085 rtx op0 = gen_reg_rtx (XFmode);
14086
14087 rtx op2 = gen_reg_rtx (XFmode);
14088 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14089
14090 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14091 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14092 DONE;
14093 })
14094
14095 (define_insn "fyl2xp1xf3_i387"
14096 [(set (match_operand:XF 0 "register_operand" "=f")
14097 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14098 (match_operand:XF 2 "register_operand" "u")]
14099 UNSPEC_FYL2XP1))
14100 (clobber (match_scratch:XF 3 "=2"))]
14101 "TARGET_USE_FANCY_MATH_387
14102 && flag_unsafe_math_optimizations"
14103 "fyl2xp1"
14104 [(set_attr "type" "fpspc")
14105 (set_attr "mode" "XF")])
14106
14107 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14108 [(set (match_operand:XF 0 "register_operand" "=f")
14109 (unspec:XF [(float_extend:XF
14110 (match_operand:MODEF 1 "register_operand" "0"))
14111 (match_operand:XF 2 "register_operand" "u")]
14112 UNSPEC_FYL2XP1))
14113 (clobber (match_scratch:XF 3 "=2"))]
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 "fyl2xp1"
14119 [(set_attr "type" "fpspc")
14120 (set_attr "mode" "XF")])
14121
14122 (define_expand "log1pxf2"
14123 [(use (match_operand:XF 0 "register_operand" ""))
14124 (use (match_operand:XF 1 "register_operand" ""))]
14125 "TARGET_USE_FANCY_MATH_387
14126 && flag_unsafe_math_optimizations"
14127 {
14128 if (optimize_insn_for_size_p ())
14129 FAIL;
14130
14131 ix86_emit_i387_log1p (operands[0], operands[1]);
14132 DONE;
14133 })
14134
14135 (define_expand "log1p<mode>2"
14136 [(use (match_operand:MODEF 0 "register_operand" ""))
14137 (use (match_operand:MODEF 1 "register_operand" ""))]
14138 "TARGET_USE_FANCY_MATH_387
14139 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14140 || TARGET_MIX_SSE_I387)
14141 && flag_unsafe_math_optimizations"
14142 {
14143 rtx op0;
14144
14145 if (optimize_insn_for_size_p ())
14146 FAIL;
14147
14148 op0 = gen_reg_rtx (XFmode);
14149
14150 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14151
14152 ix86_emit_i387_log1p (op0, operands[1]);
14153 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14154 DONE;
14155 })
14156
14157 (define_insn "fxtractxf3_i387"
14158 [(set (match_operand:XF 0 "register_operand" "=f")
14159 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14160 UNSPEC_XTRACT_FRACT))
14161 (set (match_operand:XF 1 "register_operand" "=u")
14162 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14163 "TARGET_USE_FANCY_MATH_387
14164 && flag_unsafe_math_optimizations"
14165 "fxtract"
14166 [(set_attr "type" "fpspc")
14167 (set_attr "mode" "XF")])
14168
14169 (define_insn "fxtract_extend<mode>xf3_i387"
14170 [(set (match_operand:XF 0 "register_operand" "=f")
14171 (unspec:XF [(float_extend:XF
14172 (match_operand:MODEF 2 "register_operand" "0"))]
14173 UNSPEC_XTRACT_FRACT))
14174 (set (match_operand:XF 1 "register_operand" "=u")
14175 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14176 "TARGET_USE_FANCY_MATH_387
14177 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14178 || TARGET_MIX_SSE_I387)
14179 && flag_unsafe_math_optimizations"
14180 "fxtract"
14181 [(set_attr "type" "fpspc")
14182 (set_attr "mode" "XF")])
14183
14184 (define_expand "logbxf2"
14185 [(parallel [(set (match_dup 2)
14186 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14187 UNSPEC_XTRACT_FRACT))
14188 (set (match_operand:XF 0 "register_operand" "")
14189 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14190 "TARGET_USE_FANCY_MATH_387
14191 && flag_unsafe_math_optimizations"
14192 "operands[2] = gen_reg_rtx (XFmode);")
14193
14194 (define_expand "logb<mode>2"
14195 [(use (match_operand:MODEF 0 "register_operand" ""))
14196 (use (match_operand:MODEF 1 "register_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 = gen_reg_rtx (XFmode);
14203 rtx op1 = gen_reg_rtx (XFmode);
14204
14205 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14206 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14207 DONE;
14208 })
14209
14210 (define_expand "ilogbxf2"
14211 [(use (match_operand:SI 0 "register_operand" ""))
14212 (use (match_operand:XF 1 "register_operand" ""))]
14213 "TARGET_USE_FANCY_MATH_387
14214 && flag_unsafe_math_optimizations"
14215 {
14216 rtx op0, op1;
14217
14218 if (optimize_insn_for_size_p ())
14219 FAIL;
14220
14221 op0 = gen_reg_rtx (XFmode);
14222 op1 = gen_reg_rtx (XFmode);
14223
14224 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14225 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14226 DONE;
14227 })
14228
14229 (define_expand "ilogb<mode>2"
14230 [(use (match_operand:SI 0 "register_operand" ""))
14231 (use (match_operand:MODEF 1 "register_operand" ""))]
14232 "TARGET_USE_FANCY_MATH_387
14233 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14234 || TARGET_MIX_SSE_I387)
14235 && flag_unsafe_math_optimizations"
14236 {
14237 rtx op0, op1;
14238
14239 if (optimize_insn_for_size_p ())
14240 FAIL;
14241
14242 op0 = gen_reg_rtx (XFmode);
14243 op1 = gen_reg_rtx (XFmode);
14244
14245 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14246 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14247 DONE;
14248 })
14249
14250 (define_insn "*f2xm1xf2_i387"
14251 [(set (match_operand:XF 0 "register_operand" "=f")
14252 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14253 UNSPEC_F2XM1))]
14254 "TARGET_USE_FANCY_MATH_387
14255 && flag_unsafe_math_optimizations"
14256 "f2xm1"
14257 [(set_attr "type" "fpspc")
14258 (set_attr "mode" "XF")])
14259
14260 (define_insn "*fscalexf4_i387"
14261 [(set (match_operand:XF 0 "register_operand" "=f")
14262 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14263 (match_operand:XF 3 "register_operand" "1")]
14264 UNSPEC_FSCALE_FRACT))
14265 (set (match_operand:XF 1 "register_operand" "=u")
14266 (unspec:XF [(match_dup 2) (match_dup 3)]
14267 UNSPEC_FSCALE_EXP))]
14268 "TARGET_USE_FANCY_MATH_387
14269 && flag_unsafe_math_optimizations"
14270 "fscale"
14271 [(set_attr "type" "fpspc")
14272 (set_attr "mode" "XF")])
14273
14274 (define_expand "expNcorexf3"
14275 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14276 (match_operand:XF 2 "register_operand" "")))
14277 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14278 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14279 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14280 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14281 (parallel [(set (match_operand:XF 0 "register_operand" "")
14282 (unspec:XF [(match_dup 8) (match_dup 4)]
14283 UNSPEC_FSCALE_FRACT))
14284 (set (match_dup 9)
14285 (unspec:XF [(match_dup 8) (match_dup 4)]
14286 UNSPEC_FSCALE_EXP))])]
14287 "TARGET_USE_FANCY_MATH_387
14288 && flag_unsafe_math_optimizations"
14289 {
14290 int i;
14291
14292 if (optimize_insn_for_size_p ())
14293 FAIL;
14294
14295 for (i = 3; i < 10; i++)
14296 operands[i] = gen_reg_rtx (XFmode);
14297
14298 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14299 })
14300
14301 (define_expand "expxf2"
14302 [(use (match_operand:XF 0 "register_operand" ""))
14303 (use (match_operand:XF 1 "register_operand" ""))]
14304 "TARGET_USE_FANCY_MATH_387
14305 && flag_unsafe_math_optimizations"
14306 {
14307 rtx op2;
14308
14309 if (optimize_insn_for_size_p ())
14310 FAIL;
14311
14312 op2 = gen_reg_rtx (XFmode);
14313 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14314
14315 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14316 DONE;
14317 })
14318
14319 (define_expand "exp<mode>2"
14320 [(use (match_operand:MODEF 0 "register_operand" ""))
14321 (use (match_operand:MODEF 1 "general_operand" ""))]
14322 "TARGET_USE_FANCY_MATH_387
14323 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14324 || TARGET_MIX_SSE_I387)
14325 && flag_unsafe_math_optimizations"
14326 {
14327 rtx op0, op1;
14328
14329 if (optimize_insn_for_size_p ())
14330 FAIL;
14331
14332 op0 = gen_reg_rtx (XFmode);
14333 op1 = gen_reg_rtx (XFmode);
14334
14335 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14336 emit_insn (gen_expxf2 (op0, op1));
14337 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14338 DONE;
14339 })
14340
14341 (define_expand "exp10xf2"
14342 [(use (match_operand:XF 0 "register_operand" ""))
14343 (use (match_operand:XF 1 "register_operand" ""))]
14344 "TARGET_USE_FANCY_MATH_387
14345 && flag_unsafe_math_optimizations"
14346 {
14347 rtx op2;
14348
14349 if (optimize_insn_for_size_p ())
14350 FAIL;
14351
14352 op2 = gen_reg_rtx (XFmode);
14353 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14354
14355 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14356 DONE;
14357 })
14358
14359 (define_expand "exp10<mode>2"
14360 [(use (match_operand:MODEF 0 "register_operand" ""))
14361 (use (match_operand:MODEF 1 "general_operand" ""))]
14362 "TARGET_USE_FANCY_MATH_387
14363 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14364 || TARGET_MIX_SSE_I387)
14365 && flag_unsafe_math_optimizations"
14366 {
14367 rtx op0, op1;
14368
14369 if (optimize_insn_for_size_p ())
14370 FAIL;
14371
14372 op0 = gen_reg_rtx (XFmode);
14373 op1 = gen_reg_rtx (XFmode);
14374
14375 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14376 emit_insn (gen_exp10xf2 (op0, op1));
14377 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14378 DONE;
14379 })
14380
14381 (define_expand "exp2xf2"
14382 [(use (match_operand:XF 0 "register_operand" ""))
14383 (use (match_operand:XF 1 "register_operand" ""))]
14384 "TARGET_USE_FANCY_MATH_387
14385 && flag_unsafe_math_optimizations"
14386 {
14387 rtx op2;
14388
14389 if (optimize_insn_for_size_p ())
14390 FAIL;
14391
14392 op2 = gen_reg_rtx (XFmode);
14393 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14394
14395 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14396 DONE;
14397 })
14398
14399 (define_expand "exp2<mode>2"
14400 [(use (match_operand:MODEF 0 "register_operand" ""))
14401 (use (match_operand:MODEF 1 "general_operand" ""))]
14402 "TARGET_USE_FANCY_MATH_387
14403 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14404 || TARGET_MIX_SSE_I387)
14405 && flag_unsafe_math_optimizations"
14406 {
14407 rtx op0, op1;
14408
14409 if (optimize_insn_for_size_p ())
14410 FAIL;
14411
14412 op0 = gen_reg_rtx (XFmode);
14413 op1 = gen_reg_rtx (XFmode);
14414
14415 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14416 emit_insn (gen_exp2xf2 (op0, op1));
14417 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14418 DONE;
14419 })
14420
14421 (define_expand "expm1xf2"
14422 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14423 (match_dup 2)))
14424 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14425 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14426 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14427 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14428 (parallel [(set (match_dup 7)
14429 (unspec:XF [(match_dup 6) (match_dup 4)]
14430 UNSPEC_FSCALE_FRACT))
14431 (set (match_dup 8)
14432 (unspec:XF [(match_dup 6) (match_dup 4)]
14433 UNSPEC_FSCALE_EXP))])
14434 (parallel [(set (match_dup 10)
14435 (unspec:XF [(match_dup 9) (match_dup 8)]
14436 UNSPEC_FSCALE_FRACT))
14437 (set (match_dup 11)
14438 (unspec:XF [(match_dup 9) (match_dup 8)]
14439 UNSPEC_FSCALE_EXP))])
14440 (set (match_dup 12) (minus:XF (match_dup 10)
14441 (float_extend:XF (match_dup 13))))
14442 (set (match_operand:XF 0 "register_operand" "")
14443 (plus:XF (match_dup 12) (match_dup 7)))]
14444 "TARGET_USE_FANCY_MATH_387
14445 && flag_unsafe_math_optimizations"
14446 {
14447 int i;
14448
14449 if (optimize_insn_for_size_p ())
14450 FAIL;
14451
14452 for (i = 2; i < 13; i++)
14453 operands[i] = gen_reg_rtx (XFmode);
14454
14455 operands[13]
14456 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14457
14458 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14459 })
14460
14461 (define_expand "expm1<mode>2"
14462 [(use (match_operand:MODEF 0 "register_operand" ""))
14463 (use (match_operand:MODEF 1 "general_operand" ""))]
14464 "TARGET_USE_FANCY_MATH_387
14465 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14466 || TARGET_MIX_SSE_I387)
14467 && flag_unsafe_math_optimizations"
14468 {
14469 rtx op0, op1;
14470
14471 if (optimize_insn_for_size_p ())
14472 FAIL;
14473
14474 op0 = gen_reg_rtx (XFmode);
14475 op1 = gen_reg_rtx (XFmode);
14476
14477 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14478 emit_insn (gen_expm1xf2 (op0, op1));
14479 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14480 DONE;
14481 })
14482
14483 (define_expand "ldexpxf3"
14484 [(set (match_dup 3)
14485 (float:XF (match_operand:SI 2 "register_operand" "")))
14486 (parallel [(set (match_operand:XF 0 " register_operand" "")
14487 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14488 (match_dup 3)]
14489 UNSPEC_FSCALE_FRACT))
14490 (set (match_dup 4)
14491 (unspec:XF [(match_dup 1) (match_dup 3)]
14492 UNSPEC_FSCALE_EXP))])]
14493 "TARGET_USE_FANCY_MATH_387
14494 && flag_unsafe_math_optimizations"
14495 {
14496 if (optimize_insn_for_size_p ())
14497 FAIL;
14498
14499 operands[3] = gen_reg_rtx (XFmode);
14500 operands[4] = gen_reg_rtx (XFmode);
14501 })
14502
14503 (define_expand "ldexp<mode>3"
14504 [(use (match_operand:MODEF 0 "register_operand" ""))
14505 (use (match_operand:MODEF 1 "general_operand" ""))
14506 (use (match_operand:SI 2 "register_operand" ""))]
14507 "TARGET_USE_FANCY_MATH_387
14508 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14509 || TARGET_MIX_SSE_I387)
14510 && flag_unsafe_math_optimizations"
14511 {
14512 rtx op0, op1;
14513
14514 if (optimize_insn_for_size_p ())
14515 FAIL;
14516
14517 op0 = gen_reg_rtx (XFmode);
14518 op1 = gen_reg_rtx (XFmode);
14519
14520 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14521 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14522 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14523 DONE;
14524 })
14525
14526 (define_expand "scalbxf3"
14527 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14528 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14529 (match_operand:XF 2 "register_operand" "")]
14530 UNSPEC_FSCALE_FRACT))
14531 (set (match_dup 3)
14532 (unspec:XF [(match_dup 1) (match_dup 2)]
14533 UNSPEC_FSCALE_EXP))])]
14534 "TARGET_USE_FANCY_MATH_387
14535 && flag_unsafe_math_optimizations"
14536 {
14537 if (optimize_insn_for_size_p ())
14538 FAIL;
14539
14540 operands[3] = gen_reg_rtx (XFmode);
14541 })
14542
14543 (define_expand "scalb<mode>3"
14544 [(use (match_operand:MODEF 0 "register_operand" ""))
14545 (use (match_operand:MODEF 1 "general_operand" ""))
14546 (use (match_operand:MODEF 2 "general_operand" ""))]
14547 "TARGET_USE_FANCY_MATH_387
14548 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14549 || TARGET_MIX_SSE_I387)
14550 && flag_unsafe_math_optimizations"
14551 {
14552 rtx op0, op1, op2;
14553
14554 if (optimize_insn_for_size_p ())
14555 FAIL;
14556
14557 op0 = gen_reg_rtx (XFmode);
14558 op1 = gen_reg_rtx (XFmode);
14559 op2 = gen_reg_rtx (XFmode);
14560
14561 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14562 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14563 emit_insn (gen_scalbxf3 (op0, op1, op2));
14564 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14565 DONE;
14566 })
14567
14568 (define_expand "significandxf2"
14569 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14570 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14571 UNSPEC_XTRACT_FRACT))
14572 (set (match_dup 2)
14573 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14574 "TARGET_USE_FANCY_MATH_387
14575 && flag_unsafe_math_optimizations"
14576 "operands[2] = gen_reg_rtx (XFmode);")
14577
14578 (define_expand "significand<mode>2"
14579 [(use (match_operand:MODEF 0 "register_operand" ""))
14580 (use (match_operand:MODEF 1 "register_operand" ""))]
14581 "TARGET_USE_FANCY_MATH_387
14582 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14583 || TARGET_MIX_SSE_I387)
14584 && flag_unsafe_math_optimizations"
14585 {
14586 rtx op0 = gen_reg_rtx (XFmode);
14587 rtx op1 = gen_reg_rtx (XFmode);
14588
14589 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14590 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14591 DONE;
14592 })
14593 \f
14594
14595 (define_insn "sse4_1_round<mode>2"
14596 [(set (match_operand:MODEF 0 "register_operand" "=x")
14597 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14598 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14599 UNSPEC_ROUND))]
14600 "TARGET_ROUND"
14601 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14602 [(set_attr "type" "ssecvt")
14603 (set_attr "prefix_extra" "1")
14604 (set_attr "prefix" "maybe_vex")
14605 (set_attr "mode" "<MODE>")])
14606
14607 (define_insn "rintxf2"
14608 [(set (match_operand:XF 0 "register_operand" "=f")
14609 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14610 UNSPEC_FRNDINT))]
14611 "TARGET_USE_FANCY_MATH_387
14612 && flag_unsafe_math_optimizations"
14613 "frndint"
14614 [(set_attr "type" "fpspc")
14615 (set_attr "mode" "XF")])
14616
14617 (define_expand "rint<mode>2"
14618 [(use (match_operand:MODEF 0 "register_operand" ""))
14619 (use (match_operand:MODEF 1 "register_operand" ""))]
14620 "(TARGET_USE_FANCY_MATH_387
14621 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14622 || TARGET_MIX_SSE_I387)
14623 && flag_unsafe_math_optimizations)
14624 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14625 && !flag_trapping_math)"
14626 {
14627 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14628 && !flag_trapping_math)
14629 {
14630 if (TARGET_ROUND)
14631 emit_insn (gen_sse4_1_round<mode>2
14632 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14633 else if (optimize_insn_for_size_p ())
14634 FAIL;
14635 else
14636 ix86_expand_rint (operand0, operand1);
14637 }
14638 else
14639 {
14640 rtx op0 = gen_reg_rtx (XFmode);
14641 rtx op1 = gen_reg_rtx (XFmode);
14642
14643 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14644 emit_insn (gen_rintxf2 (op0, op1));
14645
14646 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14647 }
14648 DONE;
14649 })
14650
14651 (define_expand "round<mode>2"
14652 [(match_operand:X87MODEF 0 "register_operand" "")
14653 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14654 "(TARGET_USE_FANCY_MATH_387
14655 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14656 || TARGET_MIX_SSE_I387)
14657 && flag_unsafe_math_optimizations)
14658 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14659 && !flag_trapping_math && !flag_rounding_math)"
14660 {
14661 if (optimize_insn_for_size_p ())
14662 FAIL;
14663
14664 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14665 && !flag_trapping_math && !flag_rounding_math)
14666 {
14667 if (TARGET_ROUND)
14668 {
14669 operands[1] = force_reg (<MODE>mode, operands[1]);
14670 ix86_expand_round_sse4 (operands[0], operands[1]);
14671 }
14672 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14673 ix86_expand_round (operands[0], operands[1]);
14674 else
14675 ix86_expand_rounddf_32 (operands[0], operands[1]);
14676 }
14677 else
14678 {
14679 operands[1] = force_reg (<MODE>mode, operands[1]);
14680 ix86_emit_i387_round (operands[0], operands[1]);
14681 }
14682 DONE;
14683 })
14684
14685 (define_insn_and_split "*fistdi2_1"
14686 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14687 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14688 UNSPEC_FIST))]
14689 "TARGET_USE_FANCY_MATH_387
14690 && can_create_pseudo_p ()"
14691 "#"
14692 "&& 1"
14693 [(const_int 0)]
14694 {
14695 if (memory_operand (operands[0], VOIDmode))
14696 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14697 else
14698 {
14699 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14700 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14701 operands[2]));
14702 }
14703 DONE;
14704 }
14705 [(set_attr "type" "fpspc")
14706 (set_attr "mode" "DI")])
14707
14708 (define_insn "fistdi2"
14709 [(set (match_operand:DI 0 "memory_operand" "=m")
14710 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14711 UNSPEC_FIST))
14712 (clobber (match_scratch:XF 2 "=&1f"))]
14713 "TARGET_USE_FANCY_MATH_387"
14714 "* return output_fix_trunc (insn, operands, false);"
14715 [(set_attr "type" "fpspc")
14716 (set_attr "mode" "DI")])
14717
14718 (define_insn "fistdi2_with_temp"
14719 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14720 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14721 UNSPEC_FIST))
14722 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14723 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14724 "TARGET_USE_FANCY_MATH_387"
14725 "#"
14726 [(set_attr "type" "fpspc")
14727 (set_attr "mode" "DI")])
14728
14729 (define_split
14730 [(set (match_operand:DI 0 "register_operand" "")
14731 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14732 UNSPEC_FIST))
14733 (clobber (match_operand:DI 2 "memory_operand" ""))
14734 (clobber (match_scratch 3 ""))]
14735 "reload_completed"
14736 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14737 (clobber (match_dup 3))])
14738 (set (match_dup 0) (match_dup 2))])
14739
14740 (define_split
14741 [(set (match_operand:DI 0 "memory_operand" "")
14742 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14743 UNSPEC_FIST))
14744 (clobber (match_operand:DI 2 "memory_operand" ""))
14745 (clobber (match_scratch 3 ""))]
14746 "reload_completed"
14747 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14748 (clobber (match_dup 3))])])
14749
14750 (define_insn_and_split "*fist<mode>2_1"
14751 [(set (match_operand:SWI24 0 "register_operand" "")
14752 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14753 UNSPEC_FIST))]
14754 "TARGET_USE_FANCY_MATH_387
14755 && can_create_pseudo_p ()"
14756 "#"
14757 "&& 1"
14758 [(const_int 0)]
14759 {
14760 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14761 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14762 operands[2]));
14763 DONE;
14764 }
14765 [(set_attr "type" "fpspc")
14766 (set_attr "mode" "<MODE>")])
14767
14768 (define_insn "fist<mode>2"
14769 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14770 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14771 UNSPEC_FIST))]
14772 "TARGET_USE_FANCY_MATH_387"
14773 "* return output_fix_trunc (insn, operands, false);"
14774 [(set_attr "type" "fpspc")
14775 (set_attr "mode" "<MODE>")])
14776
14777 (define_insn "fist<mode>2_with_temp"
14778 [(set (match_operand:SWI24 0 "register_operand" "=r")
14779 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14780 UNSPEC_FIST))
14781 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14782 "TARGET_USE_FANCY_MATH_387"
14783 "#"
14784 [(set_attr "type" "fpspc")
14785 (set_attr "mode" "<MODE>")])
14786
14787 (define_split
14788 [(set (match_operand:SWI24 0 "register_operand" "")
14789 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14790 UNSPEC_FIST))
14791 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14792 "reload_completed"
14793 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14794 (set (match_dup 0) (match_dup 2))])
14795
14796 (define_split
14797 [(set (match_operand:SWI24 0 "memory_operand" "")
14798 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14799 UNSPEC_FIST))
14800 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14801 "reload_completed"
14802 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14803
14804 (define_expand "lrintxf<mode>2"
14805 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14806 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14807 UNSPEC_FIST))]
14808 "TARGET_USE_FANCY_MATH_387")
14809
14810 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14811 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14812 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14813 UNSPEC_FIX_NOTRUNC))]
14814 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14815 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14816
14817 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14818 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14819 (match_operand:X87MODEF 1 "register_operand" "")]
14820 "(TARGET_USE_FANCY_MATH_387
14821 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14822 || TARGET_MIX_SSE_I387)
14823 && flag_unsafe_math_optimizations)
14824 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14825 && <SWI248x:MODE>mode != HImode
14826 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14827 && !flag_trapping_math && !flag_rounding_math)"
14828 {
14829 if (optimize_insn_for_size_p ())
14830 FAIL;
14831
14832 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14833 && <SWI248x:MODE>mode != HImode
14834 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14835 && !flag_trapping_math && !flag_rounding_math)
14836 ix86_expand_lround (operand0, operand1);
14837 else
14838 ix86_emit_i387_round (operands[0], operands[1]);
14839 DONE;
14840 })
14841
14842 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14843 (define_insn_and_split "frndintxf2_floor"
14844 [(set (match_operand:XF 0 "register_operand" "")
14845 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14846 UNSPEC_FRNDINT_FLOOR))
14847 (clobber (reg:CC FLAGS_REG))]
14848 "TARGET_USE_FANCY_MATH_387
14849 && flag_unsafe_math_optimizations
14850 && can_create_pseudo_p ()"
14851 "#"
14852 "&& 1"
14853 [(const_int 0)]
14854 {
14855 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14856
14857 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14858 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14859
14860 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14861 operands[2], operands[3]));
14862 DONE;
14863 }
14864 [(set_attr "type" "frndint")
14865 (set_attr "i387_cw" "floor")
14866 (set_attr "mode" "XF")])
14867
14868 (define_insn "frndintxf2_floor_i387"
14869 [(set (match_operand:XF 0 "register_operand" "=f")
14870 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14871 UNSPEC_FRNDINT_FLOOR))
14872 (use (match_operand:HI 2 "memory_operand" "m"))
14873 (use (match_operand:HI 3 "memory_operand" "m"))]
14874 "TARGET_USE_FANCY_MATH_387
14875 && flag_unsafe_math_optimizations"
14876 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14877 [(set_attr "type" "frndint")
14878 (set_attr "i387_cw" "floor")
14879 (set_attr "mode" "XF")])
14880
14881 (define_expand "floorxf2"
14882 [(use (match_operand:XF 0 "register_operand" ""))
14883 (use (match_operand:XF 1 "register_operand" ""))]
14884 "TARGET_USE_FANCY_MATH_387
14885 && flag_unsafe_math_optimizations"
14886 {
14887 if (optimize_insn_for_size_p ())
14888 FAIL;
14889 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14890 DONE;
14891 })
14892
14893 (define_expand "floor<mode>2"
14894 [(use (match_operand:MODEF 0 "register_operand" ""))
14895 (use (match_operand:MODEF 1 "register_operand" ""))]
14896 "(TARGET_USE_FANCY_MATH_387
14897 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14898 || TARGET_MIX_SSE_I387)
14899 && flag_unsafe_math_optimizations)
14900 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14901 && !flag_trapping_math)"
14902 {
14903 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14904 && !flag_trapping_math)
14905 {
14906 if (TARGET_ROUND)
14907 emit_insn (gen_sse4_1_round<mode>2
14908 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14909 else if (optimize_insn_for_size_p ())
14910 FAIL;
14911 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14912 ix86_expand_floorceil (operand0, operand1, true);
14913 else
14914 ix86_expand_floorceildf_32 (operand0, operand1, true);
14915 }
14916 else
14917 {
14918 rtx op0, op1;
14919
14920 if (optimize_insn_for_size_p ())
14921 FAIL;
14922
14923 op0 = gen_reg_rtx (XFmode);
14924 op1 = gen_reg_rtx (XFmode);
14925 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14926 emit_insn (gen_frndintxf2_floor (op0, op1));
14927
14928 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14929 }
14930 DONE;
14931 })
14932
14933 (define_insn_and_split "*fist<mode>2_floor_1"
14934 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14935 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14936 UNSPEC_FIST_FLOOR))
14937 (clobber (reg:CC FLAGS_REG))]
14938 "TARGET_USE_FANCY_MATH_387
14939 && flag_unsafe_math_optimizations
14940 && can_create_pseudo_p ()"
14941 "#"
14942 "&& 1"
14943 [(const_int 0)]
14944 {
14945 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14946
14947 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14948 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14949 if (memory_operand (operands[0], VOIDmode))
14950 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14951 operands[2], operands[3]));
14952 else
14953 {
14954 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14955 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14956 operands[2], operands[3],
14957 operands[4]));
14958 }
14959 DONE;
14960 }
14961 [(set_attr "type" "fistp")
14962 (set_attr "i387_cw" "floor")
14963 (set_attr "mode" "<MODE>")])
14964
14965 (define_insn "fistdi2_floor"
14966 [(set (match_operand:DI 0 "memory_operand" "=m")
14967 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14968 UNSPEC_FIST_FLOOR))
14969 (use (match_operand:HI 2 "memory_operand" "m"))
14970 (use (match_operand:HI 3 "memory_operand" "m"))
14971 (clobber (match_scratch:XF 4 "=&1f"))]
14972 "TARGET_USE_FANCY_MATH_387
14973 && flag_unsafe_math_optimizations"
14974 "* return output_fix_trunc (insn, operands, false);"
14975 [(set_attr "type" "fistp")
14976 (set_attr "i387_cw" "floor")
14977 (set_attr "mode" "DI")])
14978
14979 (define_insn "fistdi2_floor_with_temp"
14980 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14981 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14982 UNSPEC_FIST_FLOOR))
14983 (use (match_operand:HI 2 "memory_operand" "m,m"))
14984 (use (match_operand:HI 3 "memory_operand" "m,m"))
14985 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14986 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14987 "TARGET_USE_FANCY_MATH_387
14988 && flag_unsafe_math_optimizations"
14989 "#"
14990 [(set_attr "type" "fistp")
14991 (set_attr "i387_cw" "floor")
14992 (set_attr "mode" "DI")])
14993
14994 (define_split
14995 [(set (match_operand:DI 0 "register_operand" "")
14996 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14997 UNSPEC_FIST_FLOOR))
14998 (use (match_operand:HI 2 "memory_operand" ""))
14999 (use (match_operand:HI 3 "memory_operand" ""))
15000 (clobber (match_operand:DI 4 "memory_operand" ""))
15001 (clobber (match_scratch 5 ""))]
15002 "reload_completed"
15003 [(parallel [(set (match_dup 4)
15004 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15005 (use (match_dup 2))
15006 (use (match_dup 3))
15007 (clobber (match_dup 5))])
15008 (set (match_dup 0) (match_dup 4))])
15009
15010 (define_split
15011 [(set (match_operand:DI 0 "memory_operand" "")
15012 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15013 UNSPEC_FIST_FLOOR))
15014 (use (match_operand:HI 2 "memory_operand" ""))
15015 (use (match_operand:HI 3 "memory_operand" ""))
15016 (clobber (match_operand:DI 4 "memory_operand" ""))
15017 (clobber (match_scratch 5 ""))]
15018 "reload_completed"
15019 [(parallel [(set (match_dup 0)
15020 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15021 (use (match_dup 2))
15022 (use (match_dup 3))
15023 (clobber (match_dup 5))])])
15024
15025 (define_insn "fist<mode>2_floor"
15026 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15027 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15028 UNSPEC_FIST_FLOOR))
15029 (use (match_operand:HI 2 "memory_operand" "m"))
15030 (use (match_operand:HI 3 "memory_operand" "m"))]
15031 "TARGET_USE_FANCY_MATH_387
15032 && flag_unsafe_math_optimizations"
15033 "* return output_fix_trunc (insn, operands, false);"
15034 [(set_attr "type" "fistp")
15035 (set_attr "i387_cw" "floor")
15036 (set_attr "mode" "<MODE>")])
15037
15038 (define_insn "fist<mode>2_floor_with_temp"
15039 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15040 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15041 UNSPEC_FIST_FLOOR))
15042 (use (match_operand:HI 2 "memory_operand" "m,m"))
15043 (use (match_operand:HI 3 "memory_operand" "m,m"))
15044 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15045 "TARGET_USE_FANCY_MATH_387
15046 && flag_unsafe_math_optimizations"
15047 "#"
15048 [(set_attr "type" "fistp")
15049 (set_attr "i387_cw" "floor")
15050 (set_attr "mode" "<MODE>")])
15051
15052 (define_split
15053 [(set (match_operand:SWI24 0 "register_operand" "")
15054 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15055 UNSPEC_FIST_FLOOR))
15056 (use (match_operand:HI 2 "memory_operand" ""))
15057 (use (match_operand:HI 3 "memory_operand" ""))
15058 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15059 "reload_completed"
15060 [(parallel [(set (match_dup 4)
15061 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15062 (use (match_dup 2))
15063 (use (match_dup 3))])
15064 (set (match_dup 0) (match_dup 4))])
15065
15066 (define_split
15067 [(set (match_operand:SWI24 0 "memory_operand" "")
15068 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15069 UNSPEC_FIST_FLOOR))
15070 (use (match_operand:HI 2 "memory_operand" ""))
15071 (use (match_operand:HI 3 "memory_operand" ""))
15072 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15073 "reload_completed"
15074 [(parallel [(set (match_dup 0)
15075 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15076 (use (match_dup 2))
15077 (use (match_dup 3))])])
15078
15079 (define_expand "lfloorxf<mode>2"
15080 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15081 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15082 UNSPEC_FIST_FLOOR))
15083 (clobber (reg:CC FLAGS_REG))])]
15084 "TARGET_USE_FANCY_MATH_387
15085 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15086 && flag_unsafe_math_optimizations")
15087
15088 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15089 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15090 (match_operand:MODEF 1 "register_operand" "")]
15091 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15092 && !flag_trapping_math"
15093 {
15094 if (TARGET_64BIT && optimize_insn_for_size_p ())
15095 FAIL;
15096 ix86_expand_lfloorceil (operand0, operand1, true);
15097 DONE;
15098 })
15099
15100 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15101 (define_insn_and_split "frndintxf2_ceil"
15102 [(set (match_operand:XF 0 "register_operand" "")
15103 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15104 UNSPEC_FRNDINT_CEIL))
15105 (clobber (reg:CC FLAGS_REG))]
15106 "TARGET_USE_FANCY_MATH_387
15107 && flag_unsafe_math_optimizations
15108 && can_create_pseudo_p ()"
15109 "#"
15110 "&& 1"
15111 [(const_int 0)]
15112 {
15113 ix86_optimize_mode_switching[I387_CEIL] = 1;
15114
15115 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15116 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15117
15118 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15119 operands[2], operands[3]));
15120 DONE;
15121 }
15122 [(set_attr "type" "frndint")
15123 (set_attr "i387_cw" "ceil")
15124 (set_attr "mode" "XF")])
15125
15126 (define_insn "frndintxf2_ceil_i387"
15127 [(set (match_operand:XF 0 "register_operand" "=f")
15128 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15129 UNSPEC_FRNDINT_CEIL))
15130 (use (match_operand:HI 2 "memory_operand" "m"))
15131 (use (match_operand:HI 3 "memory_operand" "m"))]
15132 "TARGET_USE_FANCY_MATH_387
15133 && flag_unsafe_math_optimizations"
15134 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15135 [(set_attr "type" "frndint")
15136 (set_attr "i387_cw" "ceil")
15137 (set_attr "mode" "XF")])
15138
15139 (define_expand "ceilxf2"
15140 [(use (match_operand:XF 0 "register_operand" ""))
15141 (use (match_operand:XF 1 "register_operand" ""))]
15142 "TARGET_USE_FANCY_MATH_387
15143 && flag_unsafe_math_optimizations"
15144 {
15145 if (optimize_insn_for_size_p ())
15146 FAIL;
15147 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15148 DONE;
15149 })
15150
15151 (define_expand "ceil<mode>2"
15152 [(use (match_operand:MODEF 0 "register_operand" ""))
15153 (use (match_operand:MODEF 1 "register_operand" ""))]
15154 "(TARGET_USE_FANCY_MATH_387
15155 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15156 || TARGET_MIX_SSE_I387)
15157 && flag_unsafe_math_optimizations)
15158 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15159 && !flag_trapping_math)"
15160 {
15161 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15162 && !flag_trapping_math)
15163 {
15164 if (TARGET_ROUND)
15165 emit_insn (gen_sse4_1_round<mode>2
15166 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15167 else if (optimize_insn_for_size_p ())
15168 FAIL;
15169 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15170 ix86_expand_floorceil (operand0, operand1, false);
15171 else
15172 ix86_expand_floorceildf_32 (operand0, operand1, false);
15173 }
15174 else
15175 {
15176 rtx op0, op1;
15177
15178 if (optimize_insn_for_size_p ())
15179 FAIL;
15180
15181 op0 = gen_reg_rtx (XFmode);
15182 op1 = gen_reg_rtx (XFmode);
15183 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15184 emit_insn (gen_frndintxf2_ceil (op0, op1));
15185
15186 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15187 }
15188 DONE;
15189 })
15190
15191 (define_insn_and_split "*fist<mode>2_ceil_1"
15192 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15193 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15194 UNSPEC_FIST_CEIL))
15195 (clobber (reg:CC FLAGS_REG))]
15196 "TARGET_USE_FANCY_MATH_387
15197 && flag_unsafe_math_optimizations
15198 && can_create_pseudo_p ()"
15199 "#"
15200 "&& 1"
15201 [(const_int 0)]
15202 {
15203 ix86_optimize_mode_switching[I387_CEIL] = 1;
15204
15205 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15206 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15207 if (memory_operand (operands[0], VOIDmode))
15208 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15209 operands[2], operands[3]));
15210 else
15211 {
15212 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15213 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15214 operands[2], operands[3],
15215 operands[4]));
15216 }
15217 DONE;
15218 }
15219 [(set_attr "type" "fistp")
15220 (set_attr "i387_cw" "ceil")
15221 (set_attr "mode" "<MODE>")])
15222
15223 (define_insn "fistdi2_ceil"
15224 [(set (match_operand:DI 0 "memory_operand" "=m")
15225 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15226 UNSPEC_FIST_CEIL))
15227 (use (match_operand:HI 2 "memory_operand" "m"))
15228 (use (match_operand:HI 3 "memory_operand" "m"))
15229 (clobber (match_scratch:XF 4 "=&1f"))]
15230 "TARGET_USE_FANCY_MATH_387
15231 && flag_unsafe_math_optimizations"
15232 "* return output_fix_trunc (insn, operands, false);"
15233 [(set_attr "type" "fistp")
15234 (set_attr "i387_cw" "ceil")
15235 (set_attr "mode" "DI")])
15236
15237 (define_insn "fistdi2_ceil_with_temp"
15238 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15239 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15240 UNSPEC_FIST_CEIL))
15241 (use (match_operand:HI 2 "memory_operand" "m,m"))
15242 (use (match_operand:HI 3 "memory_operand" "m,m"))
15243 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15244 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15245 "TARGET_USE_FANCY_MATH_387
15246 && flag_unsafe_math_optimizations"
15247 "#"
15248 [(set_attr "type" "fistp")
15249 (set_attr "i387_cw" "ceil")
15250 (set_attr "mode" "DI")])
15251
15252 (define_split
15253 [(set (match_operand:DI 0 "register_operand" "")
15254 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15255 UNSPEC_FIST_CEIL))
15256 (use (match_operand:HI 2 "memory_operand" ""))
15257 (use (match_operand:HI 3 "memory_operand" ""))
15258 (clobber (match_operand:DI 4 "memory_operand" ""))
15259 (clobber (match_scratch 5 ""))]
15260 "reload_completed"
15261 [(parallel [(set (match_dup 4)
15262 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15263 (use (match_dup 2))
15264 (use (match_dup 3))
15265 (clobber (match_dup 5))])
15266 (set (match_dup 0) (match_dup 4))])
15267
15268 (define_split
15269 [(set (match_operand:DI 0 "memory_operand" "")
15270 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15271 UNSPEC_FIST_CEIL))
15272 (use (match_operand:HI 2 "memory_operand" ""))
15273 (use (match_operand:HI 3 "memory_operand" ""))
15274 (clobber (match_operand:DI 4 "memory_operand" ""))
15275 (clobber (match_scratch 5 ""))]
15276 "reload_completed"
15277 [(parallel [(set (match_dup 0)
15278 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15279 (use (match_dup 2))
15280 (use (match_dup 3))
15281 (clobber (match_dup 5))])])
15282
15283 (define_insn "fist<mode>2_ceil"
15284 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15285 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15286 UNSPEC_FIST_CEIL))
15287 (use (match_operand:HI 2 "memory_operand" "m"))
15288 (use (match_operand:HI 3 "memory_operand" "m"))]
15289 "TARGET_USE_FANCY_MATH_387
15290 && flag_unsafe_math_optimizations"
15291 "* return output_fix_trunc (insn, operands, false);"
15292 [(set_attr "type" "fistp")
15293 (set_attr "i387_cw" "ceil")
15294 (set_attr "mode" "<MODE>")])
15295
15296 (define_insn "fist<mode>2_ceil_with_temp"
15297 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15298 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15299 UNSPEC_FIST_CEIL))
15300 (use (match_operand:HI 2 "memory_operand" "m,m"))
15301 (use (match_operand:HI 3 "memory_operand" "m,m"))
15302 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15303 "TARGET_USE_FANCY_MATH_387
15304 && flag_unsafe_math_optimizations"
15305 "#"
15306 [(set_attr "type" "fistp")
15307 (set_attr "i387_cw" "ceil")
15308 (set_attr "mode" "<MODE>")])
15309
15310 (define_split
15311 [(set (match_operand:SWI24 0 "register_operand" "")
15312 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15313 UNSPEC_FIST_CEIL))
15314 (use (match_operand:HI 2 "memory_operand" ""))
15315 (use (match_operand:HI 3 "memory_operand" ""))
15316 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15317 "reload_completed"
15318 [(parallel [(set (match_dup 4)
15319 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15320 (use (match_dup 2))
15321 (use (match_dup 3))])
15322 (set (match_dup 0) (match_dup 4))])
15323
15324 (define_split
15325 [(set (match_operand:SWI24 0 "memory_operand" "")
15326 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15327 UNSPEC_FIST_CEIL))
15328 (use (match_operand:HI 2 "memory_operand" ""))
15329 (use (match_operand:HI 3 "memory_operand" ""))
15330 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15331 "reload_completed"
15332 [(parallel [(set (match_dup 0)
15333 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15334 (use (match_dup 2))
15335 (use (match_dup 3))])])
15336
15337 (define_expand "lceilxf<mode>2"
15338 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15339 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15340 UNSPEC_FIST_CEIL))
15341 (clobber (reg:CC FLAGS_REG))])]
15342 "TARGET_USE_FANCY_MATH_387
15343 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15344 && flag_unsafe_math_optimizations")
15345
15346 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15347 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15348 (match_operand:MODEF 1 "register_operand" "")]
15349 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15350 && !flag_trapping_math"
15351 {
15352 ix86_expand_lfloorceil (operand0, operand1, false);
15353 DONE;
15354 })
15355
15356 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15357 (define_insn_and_split "frndintxf2_trunc"
15358 [(set (match_operand:XF 0 "register_operand" "")
15359 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15360 UNSPEC_FRNDINT_TRUNC))
15361 (clobber (reg:CC FLAGS_REG))]
15362 "TARGET_USE_FANCY_MATH_387
15363 && flag_unsafe_math_optimizations
15364 && can_create_pseudo_p ()"
15365 "#"
15366 "&& 1"
15367 [(const_int 0)]
15368 {
15369 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15370
15371 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15372 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15373
15374 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15375 operands[2], operands[3]));
15376 DONE;
15377 }
15378 [(set_attr "type" "frndint")
15379 (set_attr "i387_cw" "trunc")
15380 (set_attr "mode" "XF")])
15381
15382 (define_insn "frndintxf2_trunc_i387"
15383 [(set (match_operand:XF 0 "register_operand" "=f")
15384 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15385 UNSPEC_FRNDINT_TRUNC))
15386 (use (match_operand:HI 2 "memory_operand" "m"))
15387 (use (match_operand:HI 3 "memory_operand" "m"))]
15388 "TARGET_USE_FANCY_MATH_387
15389 && flag_unsafe_math_optimizations"
15390 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15391 [(set_attr "type" "frndint")
15392 (set_attr "i387_cw" "trunc")
15393 (set_attr "mode" "XF")])
15394
15395 (define_expand "btruncxf2"
15396 [(use (match_operand:XF 0 "register_operand" ""))
15397 (use (match_operand:XF 1 "register_operand" ""))]
15398 "TARGET_USE_FANCY_MATH_387
15399 && flag_unsafe_math_optimizations"
15400 {
15401 if (optimize_insn_for_size_p ())
15402 FAIL;
15403 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15404 DONE;
15405 })
15406
15407 (define_expand "btrunc<mode>2"
15408 [(use (match_operand:MODEF 0 "register_operand" ""))
15409 (use (match_operand:MODEF 1 "register_operand" ""))]
15410 "(TARGET_USE_FANCY_MATH_387
15411 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15412 || TARGET_MIX_SSE_I387)
15413 && flag_unsafe_math_optimizations)
15414 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15415 && !flag_trapping_math)"
15416 {
15417 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15418 && !flag_trapping_math)
15419 {
15420 if (TARGET_ROUND)
15421 emit_insn (gen_sse4_1_round<mode>2
15422 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15423 else if (optimize_insn_for_size_p ())
15424 FAIL;
15425 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15426 ix86_expand_trunc (operand0, operand1);
15427 else
15428 ix86_expand_truncdf_32 (operand0, operand1);
15429 }
15430 else
15431 {
15432 rtx op0, op1;
15433
15434 if (optimize_insn_for_size_p ())
15435 FAIL;
15436
15437 op0 = gen_reg_rtx (XFmode);
15438 op1 = gen_reg_rtx (XFmode);
15439 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15440 emit_insn (gen_frndintxf2_trunc (op0, op1));
15441
15442 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15443 }
15444 DONE;
15445 })
15446
15447 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15448 (define_insn_and_split "frndintxf2_mask_pm"
15449 [(set (match_operand:XF 0 "register_operand" "")
15450 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15451 UNSPEC_FRNDINT_MASK_PM))
15452 (clobber (reg:CC FLAGS_REG))]
15453 "TARGET_USE_FANCY_MATH_387
15454 && flag_unsafe_math_optimizations
15455 && can_create_pseudo_p ()"
15456 "#"
15457 "&& 1"
15458 [(const_int 0)]
15459 {
15460 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15461
15462 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15463 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15464
15465 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15466 operands[2], operands[3]));
15467 DONE;
15468 }
15469 [(set_attr "type" "frndint")
15470 (set_attr "i387_cw" "mask_pm")
15471 (set_attr "mode" "XF")])
15472
15473 (define_insn "frndintxf2_mask_pm_i387"
15474 [(set (match_operand:XF 0 "register_operand" "=f")
15475 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15476 UNSPEC_FRNDINT_MASK_PM))
15477 (use (match_operand:HI 2 "memory_operand" "m"))
15478 (use (match_operand:HI 3 "memory_operand" "m"))]
15479 "TARGET_USE_FANCY_MATH_387
15480 && flag_unsafe_math_optimizations"
15481 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15482 [(set_attr "type" "frndint")
15483 (set_attr "i387_cw" "mask_pm")
15484 (set_attr "mode" "XF")])
15485
15486 (define_expand "nearbyintxf2"
15487 [(use (match_operand:XF 0 "register_operand" ""))
15488 (use (match_operand:XF 1 "register_operand" ""))]
15489 "TARGET_USE_FANCY_MATH_387
15490 && flag_unsafe_math_optimizations"
15491 {
15492 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15493 DONE;
15494 })
15495
15496 (define_expand "nearbyint<mode>2"
15497 [(use (match_operand:MODEF 0 "register_operand" ""))
15498 (use (match_operand:MODEF 1 "register_operand" ""))]
15499 "TARGET_USE_FANCY_MATH_387
15500 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15501 || TARGET_MIX_SSE_I387)
15502 && flag_unsafe_math_optimizations"
15503 {
15504 rtx op0 = gen_reg_rtx (XFmode);
15505 rtx op1 = gen_reg_rtx (XFmode);
15506
15507 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15508 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15509
15510 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15511 DONE;
15512 })
15513
15514 (define_insn "fxam<mode>2_i387"
15515 [(set (match_operand:HI 0 "register_operand" "=a")
15516 (unspec:HI
15517 [(match_operand:X87MODEF 1 "register_operand" "f")]
15518 UNSPEC_FXAM))]
15519 "TARGET_USE_FANCY_MATH_387"
15520 "fxam\n\tfnstsw\t%0"
15521 [(set_attr "type" "multi")
15522 (set_attr "length" "4")
15523 (set_attr "unit" "i387")
15524 (set_attr "mode" "<MODE>")])
15525
15526 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15527 [(set (match_operand:HI 0 "register_operand" "")
15528 (unspec:HI
15529 [(match_operand:MODEF 1 "memory_operand" "")]
15530 UNSPEC_FXAM_MEM))]
15531 "TARGET_USE_FANCY_MATH_387
15532 && can_create_pseudo_p ()"
15533 "#"
15534 "&& 1"
15535 [(set (match_dup 2)(match_dup 1))
15536 (set (match_dup 0)
15537 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15538 {
15539 operands[2] = gen_reg_rtx (<MODE>mode);
15540
15541 MEM_VOLATILE_P (operands[1]) = 1;
15542 }
15543 [(set_attr "type" "multi")
15544 (set_attr "unit" "i387")
15545 (set_attr "mode" "<MODE>")])
15546
15547 (define_expand "isinfxf2"
15548 [(use (match_operand:SI 0 "register_operand" ""))
15549 (use (match_operand:XF 1 "register_operand" ""))]
15550 "TARGET_USE_FANCY_MATH_387
15551 && TARGET_C99_FUNCTIONS"
15552 {
15553 rtx mask = GEN_INT (0x45);
15554 rtx val = GEN_INT (0x05);
15555
15556 rtx cond;
15557
15558 rtx scratch = gen_reg_rtx (HImode);
15559 rtx res = gen_reg_rtx (QImode);
15560
15561 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15562
15563 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15564 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15565 cond = gen_rtx_fmt_ee (EQ, QImode,
15566 gen_rtx_REG (CCmode, FLAGS_REG),
15567 const0_rtx);
15568 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15569 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15570 DONE;
15571 })
15572
15573 (define_expand "isinf<mode>2"
15574 [(use (match_operand:SI 0 "register_operand" ""))
15575 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15576 "TARGET_USE_FANCY_MATH_387
15577 && TARGET_C99_FUNCTIONS
15578 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15579 {
15580 rtx mask = GEN_INT (0x45);
15581 rtx val = GEN_INT (0x05);
15582
15583 rtx cond;
15584
15585 rtx scratch = gen_reg_rtx (HImode);
15586 rtx res = gen_reg_rtx (QImode);
15587
15588 /* Remove excess precision by forcing value through memory. */
15589 if (memory_operand (operands[1], VOIDmode))
15590 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15591 else
15592 {
15593 enum ix86_stack_slot slot = (virtuals_instantiated
15594 ? SLOT_TEMP
15595 : SLOT_VIRTUAL);
15596 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15597
15598 emit_move_insn (temp, operands[1]);
15599 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15600 }
15601
15602 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15603 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15604 cond = gen_rtx_fmt_ee (EQ, QImode,
15605 gen_rtx_REG (CCmode, FLAGS_REG),
15606 const0_rtx);
15607 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15608 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15609 DONE;
15610 })
15611
15612 (define_expand "signbitxf2"
15613 [(use (match_operand:SI 0 "register_operand" ""))
15614 (use (match_operand:XF 1 "register_operand" ""))]
15615 "TARGET_USE_FANCY_MATH_387"
15616 {
15617 rtx scratch = gen_reg_rtx (HImode);
15618
15619 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15620 emit_insn (gen_andsi3 (operands[0],
15621 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15622 DONE;
15623 })
15624
15625 (define_insn "movmsk_df"
15626 [(set (match_operand:SI 0 "register_operand" "=r")
15627 (unspec:SI
15628 [(match_operand:DF 1 "register_operand" "x")]
15629 UNSPEC_MOVMSK))]
15630 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15631 "%vmovmskpd\t{%1, %0|%0, %1}"
15632 [(set_attr "type" "ssemov")
15633 (set_attr "prefix" "maybe_vex")
15634 (set_attr "mode" "DF")])
15635
15636 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15637 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15638 (define_expand "signbitdf2"
15639 [(use (match_operand:SI 0 "register_operand" ""))
15640 (use (match_operand:DF 1 "register_operand" ""))]
15641 "TARGET_USE_FANCY_MATH_387
15642 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15643 {
15644 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15645 {
15646 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15647 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15648 }
15649 else
15650 {
15651 rtx scratch = gen_reg_rtx (HImode);
15652
15653 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15654 emit_insn (gen_andsi3 (operands[0],
15655 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15656 }
15657 DONE;
15658 })
15659
15660 (define_expand "signbitsf2"
15661 [(use (match_operand:SI 0 "register_operand" ""))
15662 (use (match_operand:SF 1 "register_operand" ""))]
15663 "TARGET_USE_FANCY_MATH_387
15664 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15665 {
15666 rtx scratch = gen_reg_rtx (HImode);
15667
15668 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15669 emit_insn (gen_andsi3 (operands[0],
15670 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15671 DONE;
15672 })
15673 \f
15674 ;; Block operation instructions
15675
15676 (define_insn "cld"
15677 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15678 ""
15679 "cld"
15680 [(set_attr "length" "1")
15681 (set_attr "length_immediate" "0")
15682 (set_attr "modrm" "0")])
15683
15684 (define_expand "movmem<mode>"
15685 [(use (match_operand:BLK 0 "memory_operand" ""))
15686 (use (match_operand:BLK 1 "memory_operand" ""))
15687 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15688 (use (match_operand:SWI48 3 "const_int_operand" ""))
15689 (use (match_operand:SI 4 "const_int_operand" ""))
15690 (use (match_operand:SI 5 "const_int_operand" ""))]
15691 ""
15692 {
15693 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15694 operands[4], operands[5]))
15695 DONE;
15696 else
15697 FAIL;
15698 })
15699
15700 ;; Most CPUs don't like single string operations
15701 ;; Handle this case here to simplify previous expander.
15702
15703 (define_expand "strmov"
15704 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15705 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15706 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15707 (clobber (reg:CC FLAGS_REG))])
15708 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15709 (clobber (reg:CC FLAGS_REG))])]
15710 ""
15711 {
15712 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15713
15714 /* If .md ever supports :P for Pmode, these can be directly
15715 in the pattern above. */
15716 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15717 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15718
15719 /* Can't use this if the user has appropriated esi or edi. */
15720 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15721 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15722 {
15723 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15724 operands[2], operands[3],
15725 operands[5], operands[6]));
15726 DONE;
15727 }
15728
15729 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15730 })
15731
15732 (define_expand "strmov_singleop"
15733 [(parallel [(set (match_operand 1 "memory_operand" "")
15734 (match_operand 3 "memory_operand" ""))
15735 (set (match_operand 0 "register_operand" "")
15736 (match_operand 4 "" ""))
15737 (set (match_operand 2 "register_operand" "")
15738 (match_operand 5 "" ""))])]
15739 ""
15740 "ix86_current_function_needs_cld = 1;")
15741
15742 (define_insn "*strmovdi_rex_1"
15743 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15744 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15745 (set (match_operand:DI 0 "register_operand" "=D")
15746 (plus:DI (match_dup 2)
15747 (const_int 8)))
15748 (set (match_operand:DI 1 "register_operand" "=S")
15749 (plus:DI (match_dup 3)
15750 (const_int 8)))]
15751 "TARGET_64BIT
15752 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15753 "movsq"
15754 [(set_attr "type" "str")
15755 (set_attr "memory" "both")
15756 (set_attr "mode" "DI")])
15757
15758 (define_insn "*strmovsi_1"
15759 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15760 (mem:SI (match_operand:P 3 "register_operand" "1")))
15761 (set (match_operand:P 0 "register_operand" "=D")
15762 (plus:P (match_dup 2)
15763 (const_int 4)))
15764 (set (match_operand:P 1 "register_operand" "=S")
15765 (plus:P (match_dup 3)
15766 (const_int 4)))]
15767 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15768 "movs{l|d}"
15769 [(set_attr "type" "str")
15770 (set_attr "memory" "both")
15771 (set_attr "mode" "SI")])
15772
15773 (define_insn "*strmovhi_1"
15774 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15775 (mem:HI (match_operand:P 3 "register_operand" "1")))
15776 (set (match_operand:P 0 "register_operand" "=D")
15777 (plus:P (match_dup 2)
15778 (const_int 2)))
15779 (set (match_operand:P 1 "register_operand" "=S")
15780 (plus:P (match_dup 3)
15781 (const_int 2)))]
15782 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15783 "movsw"
15784 [(set_attr "type" "str")
15785 (set_attr "memory" "both")
15786 (set_attr "mode" "HI")])
15787
15788 (define_insn "*strmovqi_1"
15789 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15790 (mem:QI (match_operand:P 3 "register_operand" "1")))
15791 (set (match_operand:P 0 "register_operand" "=D")
15792 (plus:P (match_dup 2)
15793 (const_int 1)))
15794 (set (match_operand:P 1 "register_operand" "=S")
15795 (plus:P (match_dup 3)
15796 (const_int 1)))]
15797 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15798 "movsb"
15799 [(set_attr "type" "str")
15800 (set_attr "memory" "both")
15801 (set (attr "prefix_rex")
15802 (if_then_else
15803 (match_test "<P:MODE>mode == DImode")
15804 (const_string "0")
15805 (const_string "*")))
15806 (set_attr "mode" "QI")])
15807
15808 (define_expand "rep_mov"
15809 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15810 (set (match_operand 0 "register_operand" "")
15811 (match_operand 5 "" ""))
15812 (set (match_operand 2 "register_operand" "")
15813 (match_operand 6 "" ""))
15814 (set (match_operand 1 "memory_operand" "")
15815 (match_operand 3 "memory_operand" ""))
15816 (use (match_dup 4))])]
15817 ""
15818 "ix86_current_function_needs_cld = 1;")
15819
15820 (define_insn "*rep_movdi_rex64"
15821 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15822 (set (match_operand:DI 0 "register_operand" "=D")
15823 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15824 (const_int 3))
15825 (match_operand:DI 3 "register_operand" "0")))
15826 (set (match_operand:DI 1 "register_operand" "=S")
15827 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15828 (match_operand:DI 4 "register_operand" "1")))
15829 (set (mem:BLK (match_dup 3))
15830 (mem:BLK (match_dup 4)))
15831 (use (match_dup 5))]
15832 "TARGET_64BIT
15833 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15834 "rep{%;} movsq"
15835 [(set_attr "type" "str")
15836 (set_attr "prefix_rep" "1")
15837 (set_attr "memory" "both")
15838 (set_attr "mode" "DI")])
15839
15840 (define_insn "*rep_movsi"
15841 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15842 (set (match_operand:P 0 "register_operand" "=D")
15843 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15844 (const_int 2))
15845 (match_operand:P 3 "register_operand" "0")))
15846 (set (match_operand:P 1 "register_operand" "=S")
15847 (plus:P (ashift:P (match_dup 5) (const_int 2))
15848 (match_operand:P 4 "register_operand" "1")))
15849 (set (mem:BLK (match_dup 3))
15850 (mem:BLK (match_dup 4)))
15851 (use (match_dup 5))]
15852 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15853 "rep{%;} movs{l|d}"
15854 [(set_attr "type" "str")
15855 (set_attr "prefix_rep" "1")
15856 (set_attr "memory" "both")
15857 (set_attr "mode" "SI")])
15858
15859 (define_insn "*rep_movqi"
15860 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15861 (set (match_operand:P 0 "register_operand" "=D")
15862 (plus:P (match_operand:P 3 "register_operand" "0")
15863 (match_operand:P 5 "register_operand" "2")))
15864 (set (match_operand:P 1 "register_operand" "=S")
15865 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15866 (set (mem:BLK (match_dup 3))
15867 (mem:BLK (match_dup 4)))
15868 (use (match_dup 5))]
15869 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15870 "rep{%;} movsb"
15871 [(set_attr "type" "str")
15872 (set_attr "prefix_rep" "1")
15873 (set_attr "memory" "both")
15874 (set_attr "mode" "QI")])
15875
15876 (define_expand "setmem<mode>"
15877 [(use (match_operand:BLK 0 "memory_operand" ""))
15878 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15879 (use (match_operand:QI 2 "nonmemory_operand" ""))
15880 (use (match_operand 3 "const_int_operand" ""))
15881 (use (match_operand:SI 4 "const_int_operand" ""))
15882 (use (match_operand:SI 5 "const_int_operand" ""))]
15883 ""
15884 {
15885 if (ix86_expand_setmem (operands[0], operands[1],
15886 operands[2], operands[3],
15887 operands[4], operands[5]))
15888 DONE;
15889 else
15890 FAIL;
15891 })
15892
15893 ;; Most CPUs don't like single string operations
15894 ;; Handle this case here to simplify previous expander.
15895
15896 (define_expand "strset"
15897 [(set (match_operand 1 "memory_operand" "")
15898 (match_operand 2 "register_operand" ""))
15899 (parallel [(set (match_operand 0 "register_operand" "")
15900 (match_dup 3))
15901 (clobber (reg:CC FLAGS_REG))])]
15902 ""
15903 {
15904 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15905 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15906
15907 /* If .md ever supports :P for Pmode, this can be directly
15908 in the pattern above. */
15909 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15910 GEN_INT (GET_MODE_SIZE (GET_MODE
15911 (operands[2]))));
15912 /* Can't use this if the user has appropriated eax or edi. */
15913 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15914 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15915 {
15916 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15917 operands[3]));
15918 DONE;
15919 }
15920 })
15921
15922 (define_expand "strset_singleop"
15923 [(parallel [(set (match_operand 1 "memory_operand" "")
15924 (match_operand 2 "register_operand" ""))
15925 (set (match_operand 0 "register_operand" "")
15926 (match_operand 3 "" ""))])]
15927 ""
15928 "ix86_current_function_needs_cld = 1;")
15929
15930 (define_insn "*strsetdi_rex_1"
15931 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15932 (match_operand:DI 2 "register_operand" "a"))
15933 (set (match_operand:DI 0 "register_operand" "=D")
15934 (plus:DI (match_dup 1)
15935 (const_int 8)))]
15936 "TARGET_64BIT
15937 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15938 "stosq"
15939 [(set_attr "type" "str")
15940 (set_attr "memory" "store")
15941 (set_attr "mode" "DI")])
15942
15943 (define_insn "*strsetsi_1"
15944 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15945 (match_operand:SI 2 "register_operand" "a"))
15946 (set (match_operand:P 0 "register_operand" "=D")
15947 (plus:P (match_dup 1)
15948 (const_int 4)))]
15949 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15950 "stos{l|d}"
15951 [(set_attr "type" "str")
15952 (set_attr "memory" "store")
15953 (set_attr "mode" "SI")])
15954
15955 (define_insn "*strsethi_1"
15956 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15957 (match_operand:HI 2 "register_operand" "a"))
15958 (set (match_operand:P 0 "register_operand" "=D")
15959 (plus:P (match_dup 1)
15960 (const_int 2)))]
15961 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15962 "stosw"
15963 [(set_attr "type" "str")
15964 (set_attr "memory" "store")
15965 (set_attr "mode" "HI")])
15966
15967 (define_insn "*strsetqi_1"
15968 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15969 (match_operand:QI 2 "register_operand" "a"))
15970 (set (match_operand:P 0 "register_operand" "=D")
15971 (plus:P (match_dup 1)
15972 (const_int 1)))]
15973 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15974 "stosb"
15975 [(set_attr "type" "str")
15976 (set_attr "memory" "store")
15977 (set (attr "prefix_rex")
15978 (if_then_else
15979 (match_test "<P:MODE>mode == DImode")
15980 (const_string "0")
15981 (const_string "*")))
15982 (set_attr "mode" "QI")])
15983
15984 (define_expand "rep_stos"
15985 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15986 (set (match_operand 0 "register_operand" "")
15987 (match_operand 4 "" ""))
15988 (set (match_operand 2 "memory_operand" "") (const_int 0))
15989 (use (match_operand 3 "register_operand" ""))
15990 (use (match_dup 1))])]
15991 ""
15992 "ix86_current_function_needs_cld = 1;")
15993
15994 (define_insn "*rep_stosdi_rex64"
15995 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15996 (set (match_operand:DI 0 "register_operand" "=D")
15997 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15998 (const_int 3))
15999 (match_operand:DI 3 "register_operand" "0")))
16000 (set (mem:BLK (match_dup 3))
16001 (const_int 0))
16002 (use (match_operand:DI 2 "register_operand" "a"))
16003 (use (match_dup 4))]
16004 "TARGET_64BIT
16005 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16006 "rep{%;} stosq"
16007 [(set_attr "type" "str")
16008 (set_attr "prefix_rep" "1")
16009 (set_attr "memory" "store")
16010 (set_attr "mode" "DI")])
16011
16012 (define_insn "*rep_stossi"
16013 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16014 (set (match_operand:P 0 "register_operand" "=D")
16015 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16016 (const_int 2))
16017 (match_operand:P 3 "register_operand" "0")))
16018 (set (mem:BLK (match_dup 3))
16019 (const_int 0))
16020 (use (match_operand:SI 2 "register_operand" "a"))
16021 (use (match_dup 4))]
16022 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16023 "rep{%;} stos{l|d}"
16024 [(set_attr "type" "str")
16025 (set_attr "prefix_rep" "1")
16026 (set_attr "memory" "store")
16027 (set_attr "mode" "SI")])
16028
16029 (define_insn "*rep_stosqi"
16030 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16031 (set (match_operand:P 0 "register_operand" "=D")
16032 (plus:P (match_operand:P 3 "register_operand" "0")
16033 (match_operand:P 4 "register_operand" "1")))
16034 (set (mem:BLK (match_dup 3))
16035 (const_int 0))
16036 (use (match_operand:QI 2 "register_operand" "a"))
16037 (use (match_dup 4))]
16038 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16039 "rep{%;} stosb"
16040 [(set_attr "type" "str")
16041 (set_attr "prefix_rep" "1")
16042 (set_attr "memory" "store")
16043 (set (attr "prefix_rex")
16044 (if_then_else
16045 (match_test "<P:MODE>mode == DImode")
16046 (const_string "0")
16047 (const_string "*")))
16048 (set_attr "mode" "QI")])
16049
16050 (define_expand "cmpstrnsi"
16051 [(set (match_operand:SI 0 "register_operand" "")
16052 (compare:SI (match_operand:BLK 1 "general_operand" "")
16053 (match_operand:BLK 2 "general_operand" "")))
16054 (use (match_operand 3 "general_operand" ""))
16055 (use (match_operand 4 "immediate_operand" ""))]
16056 ""
16057 {
16058 rtx addr1, addr2, out, outlow, count, countreg, align;
16059
16060 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16061 FAIL;
16062
16063 /* Can't use this if the user has appropriated ecx, esi or edi. */
16064 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16065 FAIL;
16066
16067 out = operands[0];
16068 if (!REG_P (out))
16069 out = gen_reg_rtx (SImode);
16070
16071 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16072 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16073 if (addr1 != XEXP (operands[1], 0))
16074 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16075 if (addr2 != XEXP (operands[2], 0))
16076 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16077
16078 count = operands[3];
16079 countreg = ix86_zero_extend_to_Pmode (count);
16080
16081 /* %%% Iff we are testing strict equality, we can use known alignment
16082 to good advantage. This may be possible with combine, particularly
16083 once cc0 is dead. */
16084 align = operands[4];
16085
16086 if (CONST_INT_P (count))
16087 {
16088 if (INTVAL (count) == 0)
16089 {
16090 emit_move_insn (operands[0], const0_rtx);
16091 DONE;
16092 }
16093 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16094 operands[1], operands[2]));
16095 }
16096 else
16097 {
16098 rtx (*gen_cmp) (rtx, rtx);
16099
16100 gen_cmp = (TARGET_64BIT
16101 ? gen_cmpdi_1 : gen_cmpsi_1);
16102
16103 emit_insn (gen_cmp (countreg, countreg));
16104 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16105 operands[1], operands[2]));
16106 }
16107
16108 outlow = gen_lowpart (QImode, out);
16109 emit_insn (gen_cmpintqi (outlow));
16110 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16111
16112 if (operands[0] != out)
16113 emit_move_insn (operands[0], out);
16114
16115 DONE;
16116 })
16117
16118 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16119
16120 (define_expand "cmpintqi"
16121 [(set (match_dup 1)
16122 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16123 (set (match_dup 2)
16124 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16125 (parallel [(set (match_operand:QI 0 "register_operand" "")
16126 (minus:QI (match_dup 1)
16127 (match_dup 2)))
16128 (clobber (reg:CC FLAGS_REG))])]
16129 ""
16130 {
16131 operands[1] = gen_reg_rtx (QImode);
16132 operands[2] = gen_reg_rtx (QImode);
16133 })
16134
16135 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16136 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16137
16138 (define_expand "cmpstrnqi_nz_1"
16139 [(parallel [(set (reg:CC FLAGS_REG)
16140 (compare:CC (match_operand 4 "memory_operand" "")
16141 (match_operand 5 "memory_operand" "")))
16142 (use (match_operand 2 "register_operand" ""))
16143 (use (match_operand:SI 3 "immediate_operand" ""))
16144 (clobber (match_operand 0 "register_operand" ""))
16145 (clobber (match_operand 1 "register_operand" ""))
16146 (clobber (match_dup 2))])]
16147 ""
16148 "ix86_current_function_needs_cld = 1;")
16149
16150 (define_insn "*cmpstrnqi_nz_1"
16151 [(set (reg:CC FLAGS_REG)
16152 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16153 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16154 (use (match_operand:P 6 "register_operand" "2"))
16155 (use (match_operand:SI 3 "immediate_operand" "i"))
16156 (clobber (match_operand:P 0 "register_operand" "=S"))
16157 (clobber (match_operand:P 1 "register_operand" "=D"))
16158 (clobber (match_operand:P 2 "register_operand" "=c"))]
16159 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16160 "repz{%;} cmpsb"
16161 [(set_attr "type" "str")
16162 (set_attr "mode" "QI")
16163 (set (attr "prefix_rex")
16164 (if_then_else
16165 (match_test "<P:MODE>mode == DImode")
16166 (const_string "0")
16167 (const_string "*")))
16168 (set_attr "prefix_rep" "1")])
16169
16170 ;; The same, but the count is not known to not be zero.
16171
16172 (define_expand "cmpstrnqi_1"
16173 [(parallel [(set (reg:CC FLAGS_REG)
16174 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16175 (const_int 0))
16176 (compare:CC (match_operand 4 "memory_operand" "")
16177 (match_operand 5 "memory_operand" ""))
16178 (const_int 0)))
16179 (use (match_operand:SI 3 "immediate_operand" ""))
16180 (use (reg:CC FLAGS_REG))
16181 (clobber (match_operand 0 "register_operand" ""))
16182 (clobber (match_operand 1 "register_operand" ""))
16183 (clobber (match_dup 2))])]
16184 ""
16185 "ix86_current_function_needs_cld = 1;")
16186
16187 (define_insn "*cmpstrnqi_1"
16188 [(set (reg:CC FLAGS_REG)
16189 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16190 (const_int 0))
16191 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16192 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16193 (const_int 0)))
16194 (use (match_operand:SI 3 "immediate_operand" "i"))
16195 (use (reg:CC FLAGS_REG))
16196 (clobber (match_operand:P 0 "register_operand" "=S"))
16197 (clobber (match_operand:P 1 "register_operand" "=D"))
16198 (clobber (match_operand:P 2 "register_operand" "=c"))]
16199 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16200 "repz{%;} cmpsb"
16201 [(set_attr "type" "str")
16202 (set_attr "mode" "QI")
16203 (set (attr "prefix_rex")
16204 (if_then_else
16205 (match_test "<P:MODE>mode == DImode")
16206 (const_string "0")
16207 (const_string "*")))
16208 (set_attr "prefix_rep" "1")])
16209
16210 (define_expand "strlen<mode>"
16211 [(set (match_operand:P 0 "register_operand" "")
16212 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16213 (match_operand:QI 2 "immediate_operand" "")
16214 (match_operand 3 "immediate_operand" "")]
16215 UNSPEC_SCAS))]
16216 ""
16217 {
16218 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16219 DONE;
16220 else
16221 FAIL;
16222 })
16223
16224 (define_expand "strlenqi_1"
16225 [(parallel [(set (match_operand 0 "register_operand" "")
16226 (match_operand 2 "" ""))
16227 (clobber (match_operand 1 "register_operand" ""))
16228 (clobber (reg:CC FLAGS_REG))])]
16229 ""
16230 "ix86_current_function_needs_cld = 1;")
16231
16232 (define_insn "*strlenqi_1"
16233 [(set (match_operand:P 0 "register_operand" "=&c")
16234 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16235 (match_operand:QI 2 "register_operand" "a")
16236 (match_operand:P 3 "immediate_operand" "i")
16237 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16238 (clobber (match_operand:P 1 "register_operand" "=D"))
16239 (clobber (reg:CC FLAGS_REG))]
16240 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16241 "repnz{%;} scasb"
16242 [(set_attr "type" "str")
16243 (set_attr "mode" "QI")
16244 (set (attr "prefix_rex")
16245 (if_then_else
16246 (match_test "<P:MODE>mode == DImode")
16247 (const_string "0")
16248 (const_string "*")))
16249 (set_attr "prefix_rep" "1")])
16250
16251 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16252 ;; handled in combine, but it is not currently up to the task.
16253 ;; When used for their truth value, the cmpstrn* expanders generate
16254 ;; code like this:
16255 ;;
16256 ;; repz cmpsb
16257 ;; seta %al
16258 ;; setb %dl
16259 ;; cmpb %al, %dl
16260 ;; jcc label
16261 ;;
16262 ;; The intermediate three instructions are unnecessary.
16263
16264 ;; This one handles cmpstrn*_nz_1...
16265 (define_peephole2
16266 [(parallel[
16267 (set (reg:CC FLAGS_REG)
16268 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16269 (mem:BLK (match_operand 5 "register_operand" ""))))
16270 (use (match_operand 6 "register_operand" ""))
16271 (use (match_operand:SI 3 "immediate_operand" ""))
16272 (clobber (match_operand 0 "register_operand" ""))
16273 (clobber (match_operand 1 "register_operand" ""))
16274 (clobber (match_operand 2 "register_operand" ""))])
16275 (set (match_operand:QI 7 "register_operand" "")
16276 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16277 (set (match_operand:QI 8 "register_operand" "")
16278 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16279 (set (reg FLAGS_REG)
16280 (compare (match_dup 7) (match_dup 8)))
16281 ]
16282 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16283 [(parallel[
16284 (set (reg:CC FLAGS_REG)
16285 (compare:CC (mem:BLK (match_dup 4))
16286 (mem:BLK (match_dup 5))))
16287 (use (match_dup 6))
16288 (use (match_dup 3))
16289 (clobber (match_dup 0))
16290 (clobber (match_dup 1))
16291 (clobber (match_dup 2))])])
16292
16293 ;; ...and this one handles cmpstrn*_1.
16294 (define_peephole2
16295 [(parallel[
16296 (set (reg:CC FLAGS_REG)
16297 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16298 (const_int 0))
16299 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16300 (mem:BLK (match_operand 5 "register_operand" "")))
16301 (const_int 0)))
16302 (use (match_operand:SI 3 "immediate_operand" ""))
16303 (use (reg:CC FLAGS_REG))
16304 (clobber (match_operand 0 "register_operand" ""))
16305 (clobber (match_operand 1 "register_operand" ""))
16306 (clobber (match_operand 2 "register_operand" ""))])
16307 (set (match_operand:QI 7 "register_operand" "")
16308 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16309 (set (match_operand:QI 8 "register_operand" "")
16310 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16311 (set (reg FLAGS_REG)
16312 (compare (match_dup 7) (match_dup 8)))
16313 ]
16314 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16315 [(parallel[
16316 (set (reg:CC FLAGS_REG)
16317 (if_then_else:CC (ne (match_dup 6)
16318 (const_int 0))
16319 (compare:CC (mem:BLK (match_dup 4))
16320 (mem:BLK (match_dup 5)))
16321 (const_int 0)))
16322 (use (match_dup 3))
16323 (use (reg:CC FLAGS_REG))
16324 (clobber (match_dup 0))
16325 (clobber (match_dup 1))
16326 (clobber (match_dup 2))])])
16327 \f
16328 ;; Conditional move instructions.
16329
16330 (define_expand "mov<mode>cc"
16331 [(set (match_operand:SWIM 0 "register_operand" "")
16332 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16333 (match_operand:SWIM 2 "<general_operand>" "")
16334 (match_operand:SWIM 3 "<general_operand>" "")))]
16335 ""
16336 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16337
16338 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16339 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16340 ;; So just document what we're doing explicitly.
16341
16342 (define_expand "x86_mov<mode>cc_0_m1"
16343 [(parallel
16344 [(set (match_operand:SWI48 0 "register_operand" "")
16345 (if_then_else:SWI48
16346 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16347 [(match_operand 1 "flags_reg_operand" "")
16348 (const_int 0)])
16349 (const_int -1)
16350 (const_int 0)))
16351 (clobber (reg:CC FLAGS_REG))])])
16352
16353 (define_insn "*x86_mov<mode>cc_0_m1"
16354 [(set (match_operand:SWI48 0 "register_operand" "=r")
16355 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16356 [(reg FLAGS_REG) (const_int 0)])
16357 (const_int -1)
16358 (const_int 0)))
16359 (clobber (reg:CC FLAGS_REG))]
16360 ""
16361 "sbb{<imodesuffix>}\t%0, %0"
16362 ; Since we don't have the proper number of operands for an alu insn,
16363 ; fill in all the blanks.
16364 [(set_attr "type" "alu")
16365 (set_attr "use_carry" "1")
16366 (set_attr "pent_pair" "pu")
16367 (set_attr "memory" "none")
16368 (set_attr "imm_disp" "false")
16369 (set_attr "mode" "<MODE>")
16370 (set_attr "length_immediate" "0")])
16371
16372 (define_insn "*x86_mov<mode>cc_0_m1_se"
16373 [(set (match_operand:SWI48 0 "register_operand" "=r")
16374 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16375 [(reg FLAGS_REG) (const_int 0)])
16376 (const_int 1)
16377 (const_int 0)))
16378 (clobber (reg:CC FLAGS_REG))]
16379 ""
16380 "sbb{<imodesuffix>}\t%0, %0"
16381 [(set_attr "type" "alu")
16382 (set_attr "use_carry" "1")
16383 (set_attr "pent_pair" "pu")
16384 (set_attr "memory" "none")
16385 (set_attr "imm_disp" "false")
16386 (set_attr "mode" "<MODE>")
16387 (set_attr "length_immediate" "0")])
16388
16389 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16390 [(set (match_operand:SWI48 0 "register_operand" "=r")
16391 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16392 [(reg FLAGS_REG) (const_int 0)])))]
16393 ""
16394 "sbb{<imodesuffix>}\t%0, %0"
16395 [(set_attr "type" "alu")
16396 (set_attr "use_carry" "1")
16397 (set_attr "pent_pair" "pu")
16398 (set_attr "memory" "none")
16399 (set_attr "imm_disp" "false")
16400 (set_attr "mode" "<MODE>")
16401 (set_attr "length_immediate" "0")])
16402
16403 (define_insn "*mov<mode>cc_noc"
16404 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16405 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16406 [(reg FLAGS_REG) (const_int 0)])
16407 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16408 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16409 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16410 "@
16411 cmov%O2%C1\t{%2, %0|%0, %2}
16412 cmov%O2%c1\t{%3, %0|%0, %3}"
16413 [(set_attr "type" "icmov")
16414 (set_attr "mode" "<MODE>")])
16415
16416 (define_insn_and_split "*movqicc_noc"
16417 [(set (match_operand:QI 0 "register_operand" "=r,r")
16418 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16419 [(match_operand 4 "flags_reg_operand" "")
16420 (const_int 0)])
16421 (match_operand:QI 2 "register_operand" "r,0")
16422 (match_operand:QI 3 "register_operand" "0,r")))]
16423 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16424 "#"
16425 "&& reload_completed"
16426 [(set (match_dup 0)
16427 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16428 (match_dup 2)
16429 (match_dup 3)))]
16430 "operands[0] = gen_lowpart (SImode, operands[0]);
16431 operands[2] = gen_lowpart (SImode, operands[2]);
16432 operands[3] = gen_lowpart (SImode, operands[3]);"
16433 [(set_attr "type" "icmov")
16434 (set_attr "mode" "SI")])
16435
16436 (define_expand "mov<mode>cc"
16437 [(set (match_operand:X87MODEF 0 "register_operand" "")
16438 (if_then_else:X87MODEF
16439 (match_operand 1 "ix86_fp_comparison_operator" "")
16440 (match_operand:X87MODEF 2 "register_operand" "")
16441 (match_operand:X87MODEF 3 "register_operand" "")))]
16442 "(TARGET_80387 && TARGET_CMOVE)
16443 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16444 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16445
16446 (define_insn "*movxfcc_1"
16447 [(set (match_operand:XF 0 "register_operand" "=f,f")
16448 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16449 [(reg FLAGS_REG) (const_int 0)])
16450 (match_operand:XF 2 "register_operand" "f,0")
16451 (match_operand:XF 3 "register_operand" "0,f")))]
16452 "TARGET_80387 && TARGET_CMOVE"
16453 "@
16454 fcmov%F1\t{%2, %0|%0, %2}
16455 fcmov%f1\t{%3, %0|%0, %3}"
16456 [(set_attr "type" "fcmov")
16457 (set_attr "mode" "XF")])
16458
16459 (define_insn "*movdfcc_1_rex64"
16460 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16461 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16462 [(reg FLAGS_REG) (const_int 0)])
16463 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16464 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16465 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16466 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16467 "@
16468 fcmov%F1\t{%2, %0|%0, %2}
16469 fcmov%f1\t{%3, %0|%0, %3}
16470 cmov%O2%C1\t{%2, %0|%0, %2}
16471 cmov%O2%c1\t{%3, %0|%0, %3}"
16472 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16473 (set_attr "mode" "DF,DF,DI,DI")])
16474
16475 (define_insn "*movdfcc_1"
16476 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16477 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16478 [(reg FLAGS_REG) (const_int 0)])
16479 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16480 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16481 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16482 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16483 "@
16484 fcmov%F1\t{%2, %0|%0, %2}
16485 fcmov%f1\t{%3, %0|%0, %3}
16486 #
16487 #"
16488 [(set_attr "type" "fcmov,fcmov,multi,multi")
16489 (set_attr "mode" "DF,DF,DI,DI")])
16490
16491 (define_split
16492 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16493 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16494 [(match_operand 4 "flags_reg_operand" "")
16495 (const_int 0)])
16496 (match_operand:DF 2 "nonimmediate_operand" "")
16497 (match_operand:DF 3 "nonimmediate_operand" "")))]
16498 "!TARGET_64BIT && reload_completed"
16499 [(set (match_dup 2)
16500 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16501 (match_dup 5)
16502 (match_dup 6)))
16503 (set (match_dup 3)
16504 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16505 (match_dup 7)
16506 (match_dup 8)))]
16507 {
16508 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16509 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16510 })
16511
16512 (define_insn "*movsfcc_1_387"
16513 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16514 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16515 [(reg FLAGS_REG) (const_int 0)])
16516 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16517 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16518 "TARGET_80387 && TARGET_CMOVE
16519 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16520 "@
16521 fcmov%F1\t{%2, %0|%0, %2}
16522 fcmov%f1\t{%3, %0|%0, %3}
16523 cmov%O2%C1\t{%2, %0|%0, %2}
16524 cmov%O2%c1\t{%3, %0|%0, %3}"
16525 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16526 (set_attr "mode" "SF,SF,SI,SI")])
16527
16528 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16529 ;; the scalar versions to have only XMM registers as operands.
16530
16531 ;; XOP conditional move
16532 (define_insn "*xop_pcmov_<mode>"
16533 [(set (match_operand:MODEF 0 "register_operand" "=x")
16534 (if_then_else:MODEF
16535 (match_operand:MODEF 1 "register_operand" "x")
16536 (match_operand:MODEF 2 "register_operand" "x")
16537 (match_operand:MODEF 3 "register_operand" "x")))]
16538 "TARGET_XOP"
16539 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16540 [(set_attr "type" "sse4arg")])
16541
16542 ;; These versions of the min/max patterns are intentionally ignorant of
16543 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16544 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16545 ;; are undefined in this condition, we're certain this is correct.
16546
16547 (define_insn "<code><mode>3"
16548 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16549 (smaxmin:MODEF
16550 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16551 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16552 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16553 "@
16554 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16555 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16556 [(set_attr "isa" "noavx,avx")
16557 (set_attr "prefix" "orig,vex")
16558 (set_attr "type" "sseadd")
16559 (set_attr "mode" "<MODE>")])
16560
16561 ;; These versions of the min/max patterns implement exactly the operations
16562 ;; min = (op1 < op2 ? op1 : op2)
16563 ;; max = (!(op1 < op2) ? op1 : op2)
16564 ;; Their operands are not commutative, and thus they may be used in the
16565 ;; presence of -0.0 and NaN.
16566
16567 (define_insn "*ieee_smin<mode>3"
16568 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16569 (unspec:MODEF
16570 [(match_operand:MODEF 1 "register_operand" "0,x")
16571 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16572 UNSPEC_IEEE_MIN))]
16573 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16574 "@
16575 min<ssemodesuffix>\t{%2, %0|%0, %2}
16576 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16577 [(set_attr "isa" "noavx,avx")
16578 (set_attr "prefix" "orig,vex")
16579 (set_attr "type" "sseadd")
16580 (set_attr "mode" "<MODE>")])
16581
16582 (define_insn "*ieee_smax<mode>3"
16583 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16584 (unspec:MODEF
16585 [(match_operand:MODEF 1 "register_operand" "0,x")
16586 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16587 UNSPEC_IEEE_MAX))]
16588 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16589 "@
16590 max<ssemodesuffix>\t{%2, %0|%0, %2}
16591 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16592 [(set_attr "isa" "noavx,avx")
16593 (set_attr "prefix" "orig,vex")
16594 (set_attr "type" "sseadd")
16595 (set_attr "mode" "<MODE>")])
16596
16597 ;; Make two stack loads independent:
16598 ;; fld aa fld aa
16599 ;; fld %st(0) -> fld bb
16600 ;; fmul bb fmul %st(1), %st
16601 ;;
16602 ;; Actually we only match the last two instructions for simplicity.
16603 (define_peephole2
16604 [(set (match_operand 0 "fp_register_operand" "")
16605 (match_operand 1 "fp_register_operand" ""))
16606 (set (match_dup 0)
16607 (match_operator 2 "binary_fp_operator"
16608 [(match_dup 0)
16609 (match_operand 3 "memory_operand" "")]))]
16610 "REGNO (operands[0]) != REGNO (operands[1])"
16611 [(set (match_dup 0) (match_dup 3))
16612 (set (match_dup 0) (match_dup 4))]
16613
16614 ;; The % modifier is not operational anymore in peephole2's, so we have to
16615 ;; swap the operands manually in the case of addition and multiplication.
16616 "if (COMMUTATIVE_ARITH_P (operands[2]))
16617 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16618 GET_MODE (operands[2]),
16619 operands[0], operands[1]);
16620 else
16621 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16622 GET_MODE (operands[2]),
16623 operands[1], operands[0]);")
16624
16625 ;; Conditional addition patterns
16626 (define_expand "add<mode>cc"
16627 [(match_operand:SWI 0 "register_operand" "")
16628 (match_operand 1 "ordered_comparison_operator" "")
16629 (match_operand:SWI 2 "register_operand" "")
16630 (match_operand:SWI 3 "const_int_operand" "")]
16631 ""
16632 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16633 \f
16634 ;; Misc patterns (?)
16635
16636 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16637 ;; Otherwise there will be nothing to keep
16638 ;;
16639 ;; [(set (reg ebp) (reg esp))]
16640 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16641 ;; (clobber (eflags)]
16642 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16643 ;;
16644 ;; in proper program order.
16645
16646 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16647 [(set (match_operand:P 0 "register_operand" "=r,r")
16648 (plus:P (match_operand:P 1 "register_operand" "0,r")
16649 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16650 (clobber (reg:CC FLAGS_REG))
16651 (clobber (mem:BLK (scratch)))]
16652 ""
16653 {
16654 switch (get_attr_type (insn))
16655 {
16656 case TYPE_IMOV:
16657 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16658
16659 case TYPE_ALU:
16660 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16661 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16662 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16663
16664 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16665
16666 default:
16667 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16668 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16669 }
16670 }
16671 [(set (attr "type")
16672 (cond [(and (eq_attr "alternative" "0")
16673 (not (match_test "TARGET_OPT_AGU")))
16674 (const_string "alu")
16675 (match_operand:<MODE> 2 "const0_operand" "")
16676 (const_string "imov")
16677 ]
16678 (const_string "lea")))
16679 (set (attr "length_immediate")
16680 (cond [(eq_attr "type" "imov")
16681 (const_string "0")
16682 (and (eq_attr "type" "alu")
16683 (match_operand 2 "const128_operand" ""))
16684 (const_string "1")
16685 ]
16686 (const_string "*")))
16687 (set_attr "mode" "<MODE>")])
16688
16689 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16690 [(set (match_operand:P 0 "register_operand" "=r")
16691 (minus:P (match_operand:P 1 "register_operand" "0")
16692 (match_operand:P 2 "register_operand" "r")))
16693 (clobber (reg:CC FLAGS_REG))
16694 (clobber (mem:BLK (scratch)))]
16695 ""
16696 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16697 [(set_attr "type" "alu")
16698 (set_attr "mode" "<MODE>")])
16699
16700 (define_insn "allocate_stack_worker_probe_<mode>"
16701 [(set (match_operand:P 0 "register_operand" "=a")
16702 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16703 UNSPECV_STACK_PROBE))
16704 (clobber (reg:CC FLAGS_REG))]
16705 "ix86_target_stack_probe ()"
16706 "call\t___chkstk_ms"
16707 [(set_attr "type" "multi")
16708 (set_attr "length" "5")])
16709
16710 (define_expand "allocate_stack"
16711 [(match_operand 0 "register_operand" "")
16712 (match_operand 1 "general_operand" "")]
16713 "ix86_target_stack_probe ()"
16714 {
16715 rtx x;
16716
16717 #ifndef CHECK_STACK_LIMIT
16718 #define CHECK_STACK_LIMIT 0
16719 #endif
16720
16721 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16722 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16723 {
16724 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16725 stack_pointer_rtx, 0, OPTAB_DIRECT);
16726 if (x != stack_pointer_rtx)
16727 emit_move_insn (stack_pointer_rtx, x);
16728 }
16729 else
16730 {
16731 x = copy_to_mode_reg (Pmode, operands[1]);
16732 if (TARGET_64BIT)
16733 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16734 else
16735 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16736 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16737 stack_pointer_rtx, 0, OPTAB_DIRECT);
16738 if (x != stack_pointer_rtx)
16739 emit_move_insn (stack_pointer_rtx, x);
16740 }
16741
16742 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16743 DONE;
16744 })
16745
16746 ;; Use IOR for stack probes, this is shorter.
16747 (define_expand "probe_stack"
16748 [(match_operand 0 "memory_operand" "")]
16749 ""
16750 {
16751 rtx (*gen_ior3) (rtx, rtx, rtx);
16752
16753 gen_ior3 = (GET_MODE (operands[0]) == DImode
16754 ? gen_iordi3 : gen_iorsi3);
16755
16756 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16757 DONE;
16758 })
16759
16760 (define_insn "adjust_stack_and_probe<mode>"
16761 [(set (match_operand:P 0 "register_operand" "=r")
16762 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16763 UNSPECV_PROBE_STACK_RANGE))
16764 (set (reg:P SP_REG)
16765 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16766 (clobber (reg:CC FLAGS_REG))
16767 (clobber (mem:BLK (scratch)))]
16768 ""
16769 "* return output_adjust_stack_and_probe (operands[0]);"
16770 [(set_attr "type" "multi")])
16771
16772 (define_insn "probe_stack_range<mode>"
16773 [(set (match_operand:P 0 "register_operand" "=r")
16774 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16775 (match_operand:P 2 "const_int_operand" "n")]
16776 UNSPECV_PROBE_STACK_RANGE))
16777 (clobber (reg:CC FLAGS_REG))]
16778 ""
16779 "* return output_probe_stack_range (operands[0], operands[2]);"
16780 [(set_attr "type" "multi")])
16781
16782 (define_expand "builtin_setjmp_receiver"
16783 [(label_ref (match_operand 0 "" ""))]
16784 "!TARGET_64BIT && flag_pic"
16785 {
16786 #if TARGET_MACHO
16787 if (TARGET_MACHO)
16788 {
16789 rtx xops[3];
16790 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16791 rtx label_rtx = gen_label_rtx ();
16792 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16793 xops[0] = xops[1] = picreg;
16794 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16795 ix86_expand_binary_operator (MINUS, SImode, xops);
16796 }
16797 else
16798 #endif
16799 emit_insn (gen_set_got (pic_offset_table_rtx));
16800 DONE;
16801 })
16802 \f
16803 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16804
16805 (define_split
16806 [(set (match_operand 0 "register_operand" "")
16807 (match_operator 3 "promotable_binary_operator"
16808 [(match_operand 1 "register_operand" "")
16809 (match_operand 2 "aligned_operand" "")]))
16810 (clobber (reg:CC FLAGS_REG))]
16811 "! TARGET_PARTIAL_REG_STALL && reload_completed
16812 && ((GET_MODE (operands[0]) == HImode
16813 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16814 /* ??? next two lines just !satisfies_constraint_K (...) */
16815 || !CONST_INT_P (operands[2])
16816 || satisfies_constraint_K (operands[2])))
16817 || (GET_MODE (operands[0]) == QImode
16818 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16819 [(parallel [(set (match_dup 0)
16820 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16821 (clobber (reg:CC FLAGS_REG))])]
16822 "operands[0] = gen_lowpart (SImode, operands[0]);
16823 operands[1] = gen_lowpart (SImode, operands[1]);
16824 if (GET_CODE (operands[3]) != ASHIFT)
16825 operands[2] = gen_lowpart (SImode, operands[2]);
16826 PUT_MODE (operands[3], SImode);")
16827
16828 ; Promote the QImode tests, as i386 has encoding of the AND
16829 ; instruction with 32-bit sign-extended immediate and thus the
16830 ; instruction size is unchanged, except in the %eax case for
16831 ; which it is increased by one byte, hence the ! optimize_size.
16832 (define_split
16833 [(set (match_operand 0 "flags_reg_operand" "")
16834 (match_operator 2 "compare_operator"
16835 [(and (match_operand 3 "aligned_operand" "")
16836 (match_operand 4 "const_int_operand" ""))
16837 (const_int 0)]))
16838 (set (match_operand 1 "register_operand" "")
16839 (and (match_dup 3) (match_dup 4)))]
16840 "! TARGET_PARTIAL_REG_STALL && reload_completed
16841 && optimize_insn_for_speed_p ()
16842 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16843 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16844 /* Ensure that the operand will remain sign-extended immediate. */
16845 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16846 [(parallel [(set (match_dup 0)
16847 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16848 (const_int 0)]))
16849 (set (match_dup 1)
16850 (and:SI (match_dup 3) (match_dup 4)))])]
16851 {
16852 operands[4]
16853 = gen_int_mode (INTVAL (operands[4])
16854 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16855 operands[1] = gen_lowpart (SImode, operands[1]);
16856 operands[3] = gen_lowpart (SImode, operands[3]);
16857 })
16858
16859 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16860 ; the TEST instruction with 32-bit sign-extended immediate and thus
16861 ; the instruction size would at least double, which is not what we
16862 ; want even with ! optimize_size.
16863 (define_split
16864 [(set (match_operand 0 "flags_reg_operand" "")
16865 (match_operator 1 "compare_operator"
16866 [(and (match_operand:HI 2 "aligned_operand" "")
16867 (match_operand:HI 3 "const_int_operand" ""))
16868 (const_int 0)]))]
16869 "! TARGET_PARTIAL_REG_STALL && reload_completed
16870 && ! TARGET_FAST_PREFIX
16871 && optimize_insn_for_speed_p ()
16872 /* Ensure that the operand will remain sign-extended immediate. */
16873 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16874 [(set (match_dup 0)
16875 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16876 (const_int 0)]))]
16877 {
16878 operands[3]
16879 = gen_int_mode (INTVAL (operands[3])
16880 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16881 operands[2] = gen_lowpart (SImode, operands[2]);
16882 })
16883
16884 (define_split
16885 [(set (match_operand 0 "register_operand" "")
16886 (neg (match_operand 1 "register_operand" "")))
16887 (clobber (reg:CC FLAGS_REG))]
16888 "! TARGET_PARTIAL_REG_STALL && reload_completed
16889 && (GET_MODE (operands[0]) == HImode
16890 || (GET_MODE (operands[0]) == QImode
16891 && (TARGET_PROMOTE_QImode
16892 || optimize_insn_for_size_p ())))"
16893 [(parallel [(set (match_dup 0)
16894 (neg:SI (match_dup 1)))
16895 (clobber (reg:CC FLAGS_REG))])]
16896 "operands[0] = gen_lowpart (SImode, operands[0]);
16897 operands[1] = gen_lowpart (SImode, operands[1]);")
16898
16899 (define_split
16900 [(set (match_operand 0 "register_operand" "")
16901 (not (match_operand 1 "register_operand" "")))]
16902 "! TARGET_PARTIAL_REG_STALL && reload_completed
16903 && (GET_MODE (operands[0]) == HImode
16904 || (GET_MODE (operands[0]) == QImode
16905 && (TARGET_PROMOTE_QImode
16906 || optimize_insn_for_size_p ())))"
16907 [(set (match_dup 0)
16908 (not:SI (match_dup 1)))]
16909 "operands[0] = gen_lowpart (SImode, operands[0]);
16910 operands[1] = gen_lowpart (SImode, operands[1]);")
16911
16912 (define_split
16913 [(set (match_operand 0 "register_operand" "")
16914 (if_then_else (match_operator 1 "ordered_comparison_operator"
16915 [(reg FLAGS_REG) (const_int 0)])
16916 (match_operand 2 "register_operand" "")
16917 (match_operand 3 "register_operand" "")))]
16918 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16919 && (GET_MODE (operands[0]) == HImode
16920 || (GET_MODE (operands[0]) == QImode
16921 && (TARGET_PROMOTE_QImode
16922 || optimize_insn_for_size_p ())))"
16923 [(set (match_dup 0)
16924 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16925 "operands[0] = gen_lowpart (SImode, operands[0]);
16926 operands[2] = gen_lowpart (SImode, operands[2]);
16927 operands[3] = gen_lowpart (SImode, operands[3]);")
16928 \f
16929 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16930 ;; transform a complex memory operation into two memory to register operations.
16931
16932 ;; Don't push memory operands
16933 (define_peephole2
16934 [(set (match_operand:SWI 0 "push_operand" "")
16935 (match_operand:SWI 1 "memory_operand" ""))
16936 (match_scratch:SWI 2 "<r>")]
16937 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16938 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16939 [(set (match_dup 2) (match_dup 1))
16940 (set (match_dup 0) (match_dup 2))])
16941
16942 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16943 ;; SImode pushes.
16944 (define_peephole2
16945 [(set (match_operand:SF 0 "push_operand" "")
16946 (match_operand:SF 1 "memory_operand" ""))
16947 (match_scratch:SF 2 "r")]
16948 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16949 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16950 [(set (match_dup 2) (match_dup 1))
16951 (set (match_dup 0) (match_dup 2))])
16952
16953 ;; Don't move an immediate directly to memory when the instruction
16954 ;; gets too big.
16955 (define_peephole2
16956 [(match_scratch:SWI124 1 "<r>")
16957 (set (match_operand:SWI124 0 "memory_operand" "")
16958 (const_int 0))]
16959 "optimize_insn_for_speed_p ()
16960 && !TARGET_USE_MOV0
16961 && TARGET_SPLIT_LONG_MOVES
16962 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16963 && peep2_regno_dead_p (0, FLAGS_REG)"
16964 [(parallel [(set (match_dup 2) (const_int 0))
16965 (clobber (reg:CC FLAGS_REG))])
16966 (set (match_dup 0) (match_dup 1))]
16967 "operands[2] = gen_lowpart (SImode, operands[1]);")
16968
16969 (define_peephole2
16970 [(match_scratch:SWI124 2 "<r>")
16971 (set (match_operand:SWI124 0 "memory_operand" "")
16972 (match_operand:SWI124 1 "immediate_operand" ""))]
16973 "optimize_insn_for_speed_p ()
16974 && TARGET_SPLIT_LONG_MOVES
16975 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16976 [(set (match_dup 2) (match_dup 1))
16977 (set (match_dup 0) (match_dup 2))])
16978
16979 ;; Don't compare memory with zero, load and use a test instead.
16980 (define_peephole2
16981 [(set (match_operand 0 "flags_reg_operand" "")
16982 (match_operator 1 "compare_operator"
16983 [(match_operand:SI 2 "memory_operand" "")
16984 (const_int 0)]))
16985 (match_scratch:SI 3 "r")]
16986 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16987 [(set (match_dup 3) (match_dup 2))
16988 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16989
16990 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16991 ;; Don't split NOTs with a displacement operand, because resulting XOR
16992 ;; will not be pairable anyway.
16993 ;;
16994 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16995 ;; represented using a modRM byte. The XOR replacement is long decoded,
16996 ;; so this split helps here as well.
16997 ;;
16998 ;; Note: Can't do this as a regular split because we can't get proper
16999 ;; lifetime information then.
17000
17001 (define_peephole2
17002 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17003 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17004 "optimize_insn_for_speed_p ()
17005 && ((TARGET_NOT_UNPAIRABLE
17006 && (!MEM_P (operands[0])
17007 || !memory_displacement_operand (operands[0], <MODE>mode)))
17008 || (TARGET_NOT_VECTORMODE
17009 && long_memory_operand (operands[0], <MODE>mode)))
17010 && peep2_regno_dead_p (0, FLAGS_REG)"
17011 [(parallel [(set (match_dup 0)
17012 (xor:SWI124 (match_dup 1) (const_int -1)))
17013 (clobber (reg:CC FLAGS_REG))])])
17014
17015 ;; Non pairable "test imm, reg" instructions can be translated to
17016 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17017 ;; byte opcode instead of two, have a short form for byte operands),
17018 ;; so do it for other CPUs as well. Given that the value was dead,
17019 ;; this should not create any new dependencies. Pass on the sub-word
17020 ;; versions if we're concerned about partial register stalls.
17021
17022 (define_peephole2
17023 [(set (match_operand 0 "flags_reg_operand" "")
17024 (match_operator 1 "compare_operator"
17025 [(and:SI (match_operand:SI 2 "register_operand" "")
17026 (match_operand:SI 3 "immediate_operand" ""))
17027 (const_int 0)]))]
17028 "ix86_match_ccmode (insn, CCNOmode)
17029 && (true_regnum (operands[2]) != AX_REG
17030 || satisfies_constraint_K (operands[3]))
17031 && peep2_reg_dead_p (1, operands[2])"
17032 [(parallel
17033 [(set (match_dup 0)
17034 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17035 (const_int 0)]))
17036 (set (match_dup 2)
17037 (and:SI (match_dup 2) (match_dup 3)))])])
17038
17039 ;; We don't need to handle HImode case, because it will be promoted to SImode
17040 ;; on ! TARGET_PARTIAL_REG_STALL
17041
17042 (define_peephole2
17043 [(set (match_operand 0 "flags_reg_operand" "")
17044 (match_operator 1 "compare_operator"
17045 [(and:QI (match_operand:QI 2 "register_operand" "")
17046 (match_operand:QI 3 "immediate_operand" ""))
17047 (const_int 0)]))]
17048 "! TARGET_PARTIAL_REG_STALL
17049 && ix86_match_ccmode (insn, CCNOmode)
17050 && true_regnum (operands[2]) != AX_REG
17051 && peep2_reg_dead_p (1, operands[2])"
17052 [(parallel
17053 [(set (match_dup 0)
17054 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17055 (const_int 0)]))
17056 (set (match_dup 2)
17057 (and:QI (match_dup 2) (match_dup 3)))])])
17058
17059 (define_peephole2
17060 [(set (match_operand 0 "flags_reg_operand" "")
17061 (match_operator 1 "compare_operator"
17062 [(and:SI
17063 (zero_extract:SI
17064 (match_operand 2 "ext_register_operand" "")
17065 (const_int 8)
17066 (const_int 8))
17067 (match_operand 3 "const_int_operand" ""))
17068 (const_int 0)]))]
17069 "! TARGET_PARTIAL_REG_STALL
17070 && ix86_match_ccmode (insn, CCNOmode)
17071 && true_regnum (operands[2]) != AX_REG
17072 && peep2_reg_dead_p (1, operands[2])"
17073 [(parallel [(set (match_dup 0)
17074 (match_op_dup 1
17075 [(and:SI
17076 (zero_extract:SI
17077 (match_dup 2)
17078 (const_int 8)
17079 (const_int 8))
17080 (match_dup 3))
17081 (const_int 0)]))
17082 (set (zero_extract:SI (match_dup 2)
17083 (const_int 8)
17084 (const_int 8))
17085 (and:SI
17086 (zero_extract:SI
17087 (match_dup 2)
17088 (const_int 8)
17089 (const_int 8))
17090 (match_dup 3)))])])
17091
17092 ;; Don't do logical operations with memory inputs.
17093 (define_peephole2
17094 [(match_scratch:SI 2 "r")
17095 (parallel [(set (match_operand:SI 0 "register_operand" "")
17096 (match_operator:SI 3 "arith_or_logical_operator"
17097 [(match_dup 0)
17098 (match_operand:SI 1 "memory_operand" "")]))
17099 (clobber (reg:CC FLAGS_REG))])]
17100 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17101 [(set (match_dup 2) (match_dup 1))
17102 (parallel [(set (match_dup 0)
17103 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17104 (clobber (reg:CC FLAGS_REG))])])
17105
17106 (define_peephole2
17107 [(match_scratch:SI 2 "r")
17108 (parallel [(set (match_operand:SI 0 "register_operand" "")
17109 (match_operator:SI 3 "arith_or_logical_operator"
17110 [(match_operand:SI 1 "memory_operand" "")
17111 (match_dup 0)]))
17112 (clobber (reg:CC FLAGS_REG))])]
17113 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17114 [(set (match_dup 2) (match_dup 1))
17115 (parallel [(set (match_dup 0)
17116 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17117 (clobber (reg:CC FLAGS_REG))])])
17118
17119 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17120 ;; refers to the destination of the load!
17121
17122 (define_peephole2
17123 [(set (match_operand:SI 0 "register_operand" "")
17124 (match_operand:SI 1 "register_operand" ""))
17125 (parallel [(set (match_dup 0)
17126 (match_operator:SI 3 "commutative_operator"
17127 [(match_dup 0)
17128 (match_operand:SI 2 "memory_operand" "")]))
17129 (clobber (reg:CC FLAGS_REG))])]
17130 "REGNO (operands[0]) != REGNO (operands[1])
17131 && GENERAL_REGNO_P (REGNO (operands[0]))
17132 && GENERAL_REGNO_P (REGNO (operands[1]))"
17133 [(set (match_dup 0) (match_dup 4))
17134 (parallel [(set (match_dup 0)
17135 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17136 (clobber (reg:CC FLAGS_REG))])]
17137 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17138
17139 (define_peephole2
17140 [(set (match_operand 0 "register_operand" "")
17141 (match_operand 1 "register_operand" ""))
17142 (set (match_dup 0)
17143 (match_operator 3 "commutative_operator"
17144 [(match_dup 0)
17145 (match_operand 2 "memory_operand" "")]))]
17146 "REGNO (operands[0]) != REGNO (operands[1])
17147 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17148 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17149 [(set (match_dup 0) (match_dup 2))
17150 (set (match_dup 0)
17151 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17152
17153 ; Don't do logical operations with memory outputs
17154 ;
17155 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17156 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17157 ; the same decoder scheduling characteristics as the original.
17158
17159 (define_peephole2
17160 [(match_scratch:SI 2 "r")
17161 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17162 (match_operator:SI 3 "arith_or_logical_operator"
17163 [(match_dup 0)
17164 (match_operand:SI 1 "nonmemory_operand" "")]))
17165 (clobber (reg:CC FLAGS_REG))])]
17166 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17167 /* Do not split stack checking probes. */
17168 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17169 [(set (match_dup 2) (match_dup 0))
17170 (parallel [(set (match_dup 2)
17171 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17172 (clobber (reg:CC FLAGS_REG))])
17173 (set (match_dup 0) (match_dup 2))])
17174
17175 (define_peephole2
17176 [(match_scratch:SI 2 "r")
17177 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17178 (match_operator:SI 3 "arith_or_logical_operator"
17179 [(match_operand:SI 1 "nonmemory_operand" "")
17180 (match_dup 0)]))
17181 (clobber (reg:CC FLAGS_REG))])]
17182 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17183 /* Do not split stack checking probes. */
17184 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17185 [(set (match_dup 2) (match_dup 0))
17186 (parallel [(set (match_dup 2)
17187 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17188 (clobber (reg:CC FLAGS_REG))])
17189 (set (match_dup 0) (match_dup 2))])
17190
17191 ;; Attempt to use arith or logical operations with memory outputs with
17192 ;; setting of flags.
17193 (define_peephole2
17194 [(set (match_operand:SWI 0 "register_operand" "")
17195 (match_operand:SWI 1 "memory_operand" ""))
17196 (parallel [(set (match_dup 0)
17197 (match_operator:SWI 3 "plusminuslogic_operator"
17198 [(match_dup 0)
17199 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17200 (clobber (reg:CC FLAGS_REG))])
17201 (set (match_dup 1) (match_dup 0))
17202 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17203 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17204 && peep2_reg_dead_p (4, operands[0])
17205 && !reg_overlap_mentioned_p (operands[0], operands[1])
17206 && ix86_match_ccmode (peep2_next_insn (3),
17207 (GET_CODE (operands[3]) == PLUS
17208 || GET_CODE (operands[3]) == MINUS)
17209 ? CCGOCmode : CCNOmode)"
17210 [(parallel [(set (match_dup 4) (match_dup 5))
17211 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17212 (match_dup 2)]))])]
17213 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17214 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17215 copy_rtx (operands[1]),
17216 copy_rtx (operands[2]));
17217 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17218 operands[5], const0_rtx);")
17219
17220 (define_peephole2
17221 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17222 (match_operator:SWI 2 "plusminuslogic_operator"
17223 [(match_dup 0)
17224 (match_operand:SWI 1 "memory_operand" "")]))
17225 (clobber (reg:CC FLAGS_REG))])
17226 (set (match_dup 1) (match_dup 0))
17227 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17228 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17229 && GET_CODE (operands[2]) != MINUS
17230 && peep2_reg_dead_p (3, operands[0])
17231 && !reg_overlap_mentioned_p (operands[0], operands[1])
17232 && ix86_match_ccmode (peep2_next_insn (2),
17233 GET_CODE (operands[2]) == PLUS
17234 ? CCGOCmode : CCNOmode)"
17235 [(parallel [(set (match_dup 3) (match_dup 4))
17236 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17237 (match_dup 0)]))])]
17238 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17239 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17240 copy_rtx (operands[1]),
17241 copy_rtx (operands[0]));
17242 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17243 operands[4], const0_rtx);")
17244
17245 (define_peephole2
17246 [(set (match_operand:SWI12 0 "register_operand" "")
17247 (match_operand:SWI12 1 "memory_operand" ""))
17248 (parallel [(set (match_operand:SI 4 "register_operand" "")
17249 (match_operator:SI 3 "plusminuslogic_operator"
17250 [(match_dup 4)
17251 (match_operand:SI 2 "nonmemory_operand" "")]))
17252 (clobber (reg:CC FLAGS_REG))])
17253 (set (match_dup 1) (match_dup 0))
17254 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17255 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17256 && REG_P (operands[0]) && REG_P (operands[4])
17257 && REGNO (operands[0]) == REGNO (operands[4])
17258 && peep2_reg_dead_p (4, operands[0])
17259 && !reg_overlap_mentioned_p (operands[0], operands[1])
17260 && ix86_match_ccmode (peep2_next_insn (3),
17261 (GET_CODE (operands[3]) == PLUS
17262 || GET_CODE (operands[3]) == MINUS)
17263 ? CCGOCmode : CCNOmode)"
17264 [(parallel [(set (match_dup 4) (match_dup 5))
17265 (set (match_dup 1) (match_dup 6))])]
17266 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17267 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17268 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17269 copy_rtx (operands[1]), operands[2]);
17270 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17271 operands[5], const0_rtx);
17272 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17273 copy_rtx (operands[1]),
17274 copy_rtx (operands[2]));")
17275
17276 ;; Attempt to always use XOR for zeroing registers.
17277 (define_peephole2
17278 [(set (match_operand 0 "register_operand" "")
17279 (match_operand 1 "const0_operand" ""))]
17280 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17281 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17282 && GENERAL_REG_P (operands[0])
17283 && peep2_regno_dead_p (0, FLAGS_REG)"
17284 [(parallel [(set (match_dup 0) (const_int 0))
17285 (clobber (reg:CC FLAGS_REG))])]
17286 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17287
17288 (define_peephole2
17289 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17290 (const_int 0))]
17291 "(GET_MODE (operands[0]) == QImode
17292 || GET_MODE (operands[0]) == HImode)
17293 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17294 && peep2_regno_dead_p (0, FLAGS_REG)"
17295 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17296 (clobber (reg:CC FLAGS_REG))])])
17297
17298 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17299 (define_peephole2
17300 [(set (match_operand:SWI248 0 "register_operand" "")
17301 (const_int -1))]
17302 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17303 && peep2_regno_dead_p (0, FLAGS_REG)"
17304 [(parallel [(set (match_dup 0) (const_int -1))
17305 (clobber (reg:CC FLAGS_REG))])]
17306 {
17307 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17308 operands[0] = gen_lowpart (SImode, operands[0]);
17309 })
17310
17311 ;; Attempt to convert simple lea to add/shift.
17312 ;; These can be created by move expanders.
17313
17314 (define_peephole2
17315 [(set (match_operand:SWI48 0 "register_operand" "")
17316 (plus:SWI48 (match_dup 0)
17317 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17318 "peep2_regno_dead_p (0, FLAGS_REG)"
17319 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17320 (clobber (reg:CC FLAGS_REG))])])
17321
17322 (define_peephole2
17323 [(set (match_operand:SI 0 "register_operand" "")
17324 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17325 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17326 "TARGET_64BIT
17327 && peep2_regno_dead_p (0, FLAGS_REG)
17328 && REGNO (operands[0]) == REGNO (operands[1])"
17329 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17330 (clobber (reg:CC FLAGS_REG))])]
17331 "operands[2] = gen_lowpart (SImode, operands[2]);")
17332
17333 (define_peephole2
17334 [(set (match_operand:SWI48 0 "register_operand" "")
17335 (mult:SWI48 (match_dup 0)
17336 (match_operand:SWI48 1 "const_int_operand" "")))]
17337 "exact_log2 (INTVAL (operands[1])) >= 0
17338 && peep2_regno_dead_p (0, FLAGS_REG)"
17339 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17340 (clobber (reg:CC FLAGS_REG))])]
17341 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17342
17343 (define_peephole2
17344 [(set (match_operand:SI 0 "register_operand" "")
17345 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17346 (match_operand:DI 2 "const_int_operand" "")) 0))]
17347 "TARGET_64BIT
17348 && exact_log2 (INTVAL (operands[2])) >= 0
17349 && REGNO (operands[0]) == REGNO (operands[1])
17350 && peep2_regno_dead_p (0, FLAGS_REG)"
17351 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17352 (clobber (reg:CC FLAGS_REG))])]
17353 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17354
17355 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17356 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17357 ;; On many CPUs it is also faster, since special hardware to avoid esp
17358 ;; dependencies is present.
17359
17360 ;; While some of these conversions may be done using splitters, we use
17361 ;; peepholes in order to allow combine_stack_adjustments pass to see
17362 ;; nonobfuscated RTL.
17363
17364 ;; Convert prologue esp subtractions to push.
17365 ;; We need register to push. In order to keep verify_flow_info happy we have
17366 ;; two choices
17367 ;; - use scratch and clobber it in order to avoid dependencies
17368 ;; - use already live register
17369 ;; We can't use the second way right now, since there is no reliable way how to
17370 ;; verify that given register is live. First choice will also most likely in
17371 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17372 ;; call clobbered registers are dead. We may want to use base pointer as an
17373 ;; alternative when no register is available later.
17374
17375 (define_peephole2
17376 [(match_scratch:P 1 "r")
17377 (parallel [(set (reg:P SP_REG)
17378 (plus:P (reg:P SP_REG)
17379 (match_operand:P 0 "const_int_operand" "")))
17380 (clobber (reg:CC FLAGS_REG))
17381 (clobber (mem:BLK (scratch)))])]
17382 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17383 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17384 [(clobber (match_dup 1))
17385 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17386 (clobber (mem:BLK (scratch)))])])
17387
17388 (define_peephole2
17389 [(match_scratch:P 1 "r")
17390 (parallel [(set (reg:P SP_REG)
17391 (plus:P (reg:P SP_REG)
17392 (match_operand:P 0 "const_int_operand" "")))
17393 (clobber (reg:CC FLAGS_REG))
17394 (clobber (mem:BLK (scratch)))])]
17395 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17396 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17397 [(clobber (match_dup 1))
17398 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17399 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17400 (clobber (mem:BLK (scratch)))])])
17401
17402 ;; Convert esp subtractions to push.
17403 (define_peephole2
17404 [(match_scratch:P 1 "r")
17405 (parallel [(set (reg:P SP_REG)
17406 (plus:P (reg:P SP_REG)
17407 (match_operand:P 0 "const_int_operand" "")))
17408 (clobber (reg:CC FLAGS_REG))])]
17409 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17410 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17411 [(clobber (match_dup 1))
17412 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17413
17414 (define_peephole2
17415 [(match_scratch:P 1 "r")
17416 (parallel [(set (reg:P SP_REG)
17417 (plus:P (reg:P SP_REG)
17418 (match_operand:P 0 "const_int_operand" "")))
17419 (clobber (reg:CC FLAGS_REG))])]
17420 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17421 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17422 [(clobber (match_dup 1))
17423 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17424 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17425
17426 ;; Convert epilogue deallocator to pop.
17427 (define_peephole2
17428 [(match_scratch:P 1 "r")
17429 (parallel [(set (reg:P SP_REG)
17430 (plus:P (reg:P SP_REG)
17431 (match_operand:P 0 "const_int_operand" "")))
17432 (clobber (reg:CC FLAGS_REG))
17433 (clobber (mem:BLK (scratch)))])]
17434 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17435 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17436 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17437 (clobber (mem:BLK (scratch)))])])
17438
17439 ;; Two pops case is tricky, since pop causes dependency
17440 ;; on destination register. We use two registers if available.
17441 (define_peephole2
17442 [(match_scratch:P 1 "r")
17443 (match_scratch:P 2 "r")
17444 (parallel [(set (reg:P SP_REG)
17445 (plus:P (reg:P SP_REG)
17446 (match_operand:P 0 "const_int_operand" "")))
17447 (clobber (reg:CC FLAGS_REG))
17448 (clobber (mem:BLK (scratch)))])]
17449 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17450 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17451 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17452 (clobber (mem:BLK (scratch)))])
17453 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17454
17455 (define_peephole2
17456 [(match_scratch:P 1 "r")
17457 (parallel [(set (reg:P SP_REG)
17458 (plus:P (reg:P SP_REG)
17459 (match_operand:P 0 "const_int_operand" "")))
17460 (clobber (reg:CC FLAGS_REG))
17461 (clobber (mem:BLK (scratch)))])]
17462 "optimize_insn_for_size_p ()
17463 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17464 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17465 (clobber (mem:BLK (scratch)))])
17466 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17467
17468 ;; Convert esp additions to pop.
17469 (define_peephole2
17470 [(match_scratch:P 1 "r")
17471 (parallel [(set (reg:P SP_REG)
17472 (plus:P (reg:P SP_REG)
17473 (match_operand:P 0 "const_int_operand" "")))
17474 (clobber (reg:CC FLAGS_REG))])]
17475 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17476 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17477
17478 ;; Two pops case is tricky, since pop causes dependency
17479 ;; on destination register. We use two registers if available.
17480 (define_peephole2
17481 [(match_scratch:P 1 "r")
17482 (match_scratch:P 2 "r")
17483 (parallel [(set (reg:P SP_REG)
17484 (plus:P (reg:P SP_REG)
17485 (match_operand:P 0 "const_int_operand" "")))
17486 (clobber (reg:CC FLAGS_REG))])]
17487 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17488 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17489 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17490
17491 (define_peephole2
17492 [(match_scratch:P 1 "r")
17493 (parallel [(set (reg:P SP_REG)
17494 (plus:P (reg:P SP_REG)
17495 (match_operand:P 0 "const_int_operand" "")))
17496 (clobber (reg:CC FLAGS_REG))])]
17497 "optimize_insn_for_size_p ()
17498 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17499 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17500 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17501 \f
17502 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17503 ;; required and register dies. Similarly for 128 to -128.
17504 (define_peephole2
17505 [(set (match_operand 0 "flags_reg_operand" "")
17506 (match_operator 1 "compare_operator"
17507 [(match_operand 2 "register_operand" "")
17508 (match_operand 3 "const_int_operand" "")]))]
17509 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17510 && incdec_operand (operands[3], GET_MODE (operands[3])))
17511 || (!TARGET_FUSE_CMP_AND_BRANCH
17512 && INTVAL (operands[3]) == 128))
17513 && ix86_match_ccmode (insn, CCGCmode)
17514 && peep2_reg_dead_p (1, operands[2])"
17515 [(parallel [(set (match_dup 0)
17516 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17517 (clobber (match_dup 2))])])
17518 \f
17519 ;; Convert imul by three, five and nine into lea
17520 (define_peephole2
17521 [(parallel
17522 [(set (match_operand:SWI48 0 "register_operand" "")
17523 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17524 (match_operand:SWI48 2 "const359_operand" "")))
17525 (clobber (reg:CC FLAGS_REG))])]
17526 "!TARGET_PARTIAL_REG_STALL
17527 || <MODE>mode == SImode
17528 || optimize_function_for_size_p (cfun)"
17529 [(set (match_dup 0)
17530 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17531 (match_dup 1)))]
17532 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17533
17534 (define_peephole2
17535 [(parallel
17536 [(set (match_operand:SWI48 0 "register_operand" "")
17537 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17538 (match_operand:SWI48 2 "const359_operand" "")))
17539 (clobber (reg:CC FLAGS_REG))])]
17540 "optimize_insn_for_speed_p ()
17541 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17542 [(set (match_dup 0) (match_dup 1))
17543 (set (match_dup 0)
17544 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17545 (match_dup 0)))]
17546 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17547
17548 ;; imul $32bit_imm, mem, reg is vector decoded, while
17549 ;; imul $32bit_imm, reg, reg is direct decoded.
17550 (define_peephole2
17551 [(match_scratch:SWI48 3 "r")
17552 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17553 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17554 (match_operand:SWI48 2 "immediate_operand" "")))
17555 (clobber (reg:CC FLAGS_REG))])]
17556 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17557 && !satisfies_constraint_K (operands[2])"
17558 [(set (match_dup 3) (match_dup 1))
17559 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17560 (clobber (reg:CC FLAGS_REG))])])
17561
17562 (define_peephole2
17563 [(match_scratch:SI 3 "r")
17564 (parallel [(set (match_operand:DI 0 "register_operand" "")
17565 (zero_extend:DI
17566 (mult:SI (match_operand:SI 1 "memory_operand" "")
17567 (match_operand:SI 2 "immediate_operand" ""))))
17568 (clobber (reg:CC FLAGS_REG))])]
17569 "TARGET_64BIT
17570 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17571 && !satisfies_constraint_K (operands[2])"
17572 [(set (match_dup 3) (match_dup 1))
17573 (parallel [(set (match_dup 0)
17574 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17575 (clobber (reg:CC FLAGS_REG))])])
17576
17577 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17578 ;; Convert it into imul reg, reg
17579 ;; It would be better to force assembler to encode instruction using long
17580 ;; immediate, but there is apparently no way to do so.
17581 (define_peephole2
17582 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17583 (mult:SWI248
17584 (match_operand:SWI248 1 "nonimmediate_operand" "")
17585 (match_operand:SWI248 2 "const_int_operand" "")))
17586 (clobber (reg:CC FLAGS_REG))])
17587 (match_scratch:SWI248 3 "r")]
17588 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17589 && satisfies_constraint_K (operands[2])"
17590 [(set (match_dup 3) (match_dup 2))
17591 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17592 (clobber (reg:CC FLAGS_REG))])]
17593 {
17594 if (!rtx_equal_p (operands[0], operands[1]))
17595 emit_move_insn (operands[0], operands[1]);
17596 })
17597
17598 ;; After splitting up read-modify operations, array accesses with memory
17599 ;; operands might end up in form:
17600 ;; sall $2, %eax
17601 ;; movl 4(%esp), %edx
17602 ;; addl %edx, %eax
17603 ;; instead of pre-splitting:
17604 ;; sall $2, %eax
17605 ;; addl 4(%esp), %eax
17606 ;; Turn it into:
17607 ;; movl 4(%esp), %edx
17608 ;; leal (%edx,%eax,4), %eax
17609
17610 (define_peephole2
17611 [(match_scratch:P 5 "r")
17612 (parallel [(set (match_operand 0 "register_operand" "")
17613 (ashift (match_operand 1 "register_operand" "")
17614 (match_operand 2 "const_int_operand" "")))
17615 (clobber (reg:CC FLAGS_REG))])
17616 (parallel [(set (match_operand 3 "register_operand" "")
17617 (plus (match_dup 0)
17618 (match_operand 4 "x86_64_general_operand" "")))
17619 (clobber (reg:CC FLAGS_REG))])]
17620 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17621 /* Validate MODE for lea. */
17622 && ((!TARGET_PARTIAL_REG_STALL
17623 && (GET_MODE (operands[0]) == QImode
17624 || GET_MODE (operands[0]) == HImode))
17625 || GET_MODE (operands[0]) == SImode
17626 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17627 && (rtx_equal_p (operands[0], operands[3])
17628 || peep2_reg_dead_p (2, operands[0]))
17629 /* We reorder load and the shift. */
17630 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17631 [(set (match_dup 5) (match_dup 4))
17632 (set (match_dup 0) (match_dup 1))]
17633 {
17634 enum machine_mode op1mode = GET_MODE (operands[1]);
17635 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17636 int scale = 1 << INTVAL (operands[2]);
17637 rtx index = gen_lowpart (Pmode, operands[1]);
17638 rtx base = gen_lowpart (Pmode, operands[5]);
17639 rtx dest = gen_lowpart (mode, operands[3]);
17640
17641 operands[1] = gen_rtx_PLUS (Pmode, base,
17642 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17643 operands[5] = base;
17644 if (mode != Pmode)
17645 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17646 if (op1mode != Pmode)
17647 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17648 operands[0] = dest;
17649 })
17650 \f
17651 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17652 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17653 ;; caught for use by garbage collectors and the like. Using an insn that
17654 ;; maps to SIGILL makes it more likely the program will rightfully die.
17655 ;; Keeping with tradition, "6" is in honor of #UD.
17656 (define_insn "trap"
17657 [(trap_if (const_int 1) (const_int 6))]
17658 ""
17659 { return ASM_SHORT "0x0b0f"; }
17660 [(set_attr "length" "2")])
17661
17662 (define_expand "prefetch"
17663 [(prefetch (match_operand 0 "address_operand" "")
17664 (match_operand:SI 1 "const_int_operand" "")
17665 (match_operand:SI 2 "const_int_operand" ""))]
17666 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17667 {
17668 int rw = INTVAL (operands[1]);
17669 int locality = INTVAL (operands[2]);
17670
17671 gcc_assert (rw == 0 || rw == 1);
17672 gcc_assert (locality >= 0 && locality <= 3);
17673 gcc_assert (GET_MODE (operands[0]) == Pmode
17674 || GET_MODE (operands[0]) == VOIDmode);
17675
17676 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17677 supported by SSE counterpart or the SSE prefetch is not available
17678 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17679 of locality. */
17680 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17681 operands[2] = GEN_INT (3);
17682 else
17683 operands[1] = const0_rtx;
17684 })
17685
17686 (define_insn "*prefetch_sse_<mode>"
17687 [(prefetch (match_operand:P 0 "address_operand" "p")
17688 (const_int 0)
17689 (match_operand:SI 1 "const_int_operand" ""))]
17690 "TARGET_PREFETCH_SSE"
17691 {
17692 static const char * const patterns[4] = {
17693 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17694 };
17695
17696 int locality = INTVAL (operands[1]);
17697 gcc_assert (locality >= 0 && locality <= 3);
17698
17699 return patterns[locality];
17700 }
17701 [(set_attr "type" "sse")
17702 (set_attr "atom_sse_attr" "prefetch")
17703 (set (attr "length_address")
17704 (symbol_ref "memory_address_length (operands[0])"))
17705 (set_attr "memory" "none")])
17706
17707 (define_insn "*prefetch_3dnow_<mode>"
17708 [(prefetch (match_operand:P 0 "address_operand" "p")
17709 (match_operand:SI 1 "const_int_operand" "n")
17710 (const_int 3))]
17711 "TARGET_3DNOW"
17712 {
17713 if (INTVAL (operands[1]) == 0)
17714 return "prefetch\t%a0";
17715 else
17716 return "prefetchw\t%a0";
17717 }
17718 [(set_attr "type" "mmx")
17719 (set (attr "length_address")
17720 (symbol_ref "memory_address_length (operands[0])"))
17721 (set_attr "memory" "none")])
17722
17723 (define_expand "stack_protect_set"
17724 [(match_operand 0 "memory_operand" "")
17725 (match_operand 1 "memory_operand" "")]
17726 ""
17727 {
17728 rtx (*insn)(rtx, rtx);
17729
17730 #ifdef TARGET_THREAD_SSP_OFFSET
17731 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17732 insn = (TARGET_LP64
17733 ? gen_stack_tls_protect_set_di
17734 : gen_stack_tls_protect_set_si);
17735 #else
17736 insn = (TARGET_LP64
17737 ? gen_stack_protect_set_di
17738 : gen_stack_protect_set_si);
17739 #endif
17740
17741 emit_insn (insn (operands[0], operands[1]));
17742 DONE;
17743 })
17744
17745 (define_insn "stack_protect_set_<mode>"
17746 [(set (match_operand:PTR 0 "memory_operand" "=m")
17747 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17748 UNSPEC_SP_SET))
17749 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17750 (clobber (reg:CC FLAGS_REG))]
17751 ""
17752 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17753 [(set_attr "type" "multi")])
17754
17755 (define_insn "stack_tls_protect_set_<mode>"
17756 [(set (match_operand:PTR 0 "memory_operand" "=m")
17757 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17758 UNSPEC_SP_TLS_SET))
17759 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17760 (clobber (reg:CC FLAGS_REG))]
17761 ""
17762 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17763 [(set_attr "type" "multi")])
17764
17765 (define_expand "stack_protect_test"
17766 [(match_operand 0 "memory_operand" "")
17767 (match_operand 1 "memory_operand" "")
17768 (match_operand 2 "" "")]
17769 ""
17770 {
17771 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17772
17773 rtx (*insn)(rtx, rtx, rtx);
17774
17775 #ifdef TARGET_THREAD_SSP_OFFSET
17776 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17777 insn = (TARGET_LP64
17778 ? gen_stack_tls_protect_test_di
17779 : gen_stack_tls_protect_test_si);
17780 #else
17781 insn = (TARGET_LP64
17782 ? gen_stack_protect_test_di
17783 : gen_stack_protect_test_si);
17784 #endif
17785
17786 emit_insn (insn (flags, operands[0], operands[1]));
17787
17788 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17789 flags, const0_rtx, operands[2]));
17790 DONE;
17791 })
17792
17793 (define_insn "stack_protect_test_<mode>"
17794 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17795 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17796 (match_operand:PTR 2 "memory_operand" "m")]
17797 UNSPEC_SP_TEST))
17798 (clobber (match_scratch:PTR 3 "=&r"))]
17799 ""
17800 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17801 [(set_attr "type" "multi")])
17802
17803 (define_insn "stack_tls_protect_test_<mode>"
17804 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17805 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17806 (match_operand:PTR 2 "const_int_operand" "i")]
17807 UNSPEC_SP_TLS_TEST))
17808 (clobber (match_scratch:PTR 3 "=r"))]
17809 ""
17810 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17811 [(set_attr "type" "multi")])
17812
17813 (define_insn "sse4_2_crc32<mode>"
17814 [(set (match_operand:SI 0 "register_operand" "=r")
17815 (unspec:SI
17816 [(match_operand:SI 1 "register_operand" "0")
17817 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17818 UNSPEC_CRC32))]
17819 "TARGET_SSE4_2 || TARGET_CRC32"
17820 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17821 [(set_attr "type" "sselog1")
17822 (set_attr "prefix_rep" "1")
17823 (set_attr "prefix_extra" "1")
17824 (set (attr "prefix_data16")
17825 (if_then_else (match_operand:HI 2 "" "")
17826 (const_string "1")
17827 (const_string "*")))
17828 (set (attr "prefix_rex")
17829 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17830 (const_string "1")
17831 (const_string "*")))
17832 (set_attr "mode" "SI")])
17833
17834 (define_insn "sse4_2_crc32di"
17835 [(set (match_operand:DI 0 "register_operand" "=r")
17836 (unspec:DI
17837 [(match_operand:DI 1 "register_operand" "0")
17838 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17839 UNSPEC_CRC32))]
17840 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17841 "crc32{q}\t{%2, %0|%0, %2}"
17842 [(set_attr "type" "sselog1")
17843 (set_attr "prefix_rep" "1")
17844 (set_attr "prefix_extra" "1")
17845 (set_attr "mode" "DI")])
17846
17847 (define_expand "rdpmc"
17848 [(match_operand:DI 0 "register_operand" "")
17849 (match_operand:SI 1 "register_operand" "")]
17850 ""
17851 {
17852 rtx reg = gen_reg_rtx (DImode);
17853 rtx si;
17854
17855 /* Force operand 1 into ECX. */
17856 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17857 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17858 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17859 UNSPECV_RDPMC);
17860
17861 if (TARGET_64BIT)
17862 {
17863 rtvec vec = rtvec_alloc (2);
17864 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17865 rtx upper = gen_reg_rtx (DImode);
17866 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17867 gen_rtvec (1, const0_rtx),
17868 UNSPECV_RDPMC);
17869 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17870 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17871 emit_insn (load);
17872 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17873 NULL, 1, OPTAB_DIRECT);
17874 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17875 OPTAB_DIRECT);
17876 }
17877 else
17878 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17879 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17880 DONE;
17881 })
17882
17883 (define_insn "*rdpmc"
17884 [(set (match_operand:DI 0 "register_operand" "=A")
17885 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17886 UNSPECV_RDPMC))]
17887 "!TARGET_64BIT"
17888 "rdpmc"
17889 [(set_attr "type" "other")
17890 (set_attr "length" "2")])
17891
17892 (define_insn "*rdpmc_rex64"
17893 [(set (match_operand:DI 0 "register_operand" "=a")
17894 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17895 UNSPECV_RDPMC))
17896 (set (match_operand:DI 1 "register_operand" "=d")
17897 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17898 "TARGET_64BIT"
17899 "rdpmc"
17900 [(set_attr "type" "other")
17901 (set_attr "length" "2")])
17902
17903 (define_expand "rdtsc"
17904 [(set (match_operand:DI 0 "register_operand" "")
17905 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17906 ""
17907 {
17908 if (TARGET_64BIT)
17909 {
17910 rtvec vec = rtvec_alloc (2);
17911 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17912 rtx upper = gen_reg_rtx (DImode);
17913 rtx lower = gen_reg_rtx (DImode);
17914 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17915 gen_rtvec (1, const0_rtx),
17916 UNSPECV_RDTSC);
17917 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17918 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17919 emit_insn (load);
17920 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17921 NULL, 1, OPTAB_DIRECT);
17922 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17923 OPTAB_DIRECT);
17924 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17925 DONE;
17926 }
17927 })
17928
17929 (define_insn "*rdtsc"
17930 [(set (match_operand:DI 0 "register_operand" "=A")
17931 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17932 "!TARGET_64BIT"
17933 "rdtsc"
17934 [(set_attr "type" "other")
17935 (set_attr "length" "2")])
17936
17937 (define_insn "*rdtsc_rex64"
17938 [(set (match_operand:DI 0 "register_operand" "=a")
17939 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17940 (set (match_operand:DI 1 "register_operand" "=d")
17941 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17942 "TARGET_64BIT"
17943 "rdtsc"
17944 [(set_attr "type" "other")
17945 (set_attr "length" "2")])
17946
17947 (define_expand "rdtscp"
17948 [(match_operand:DI 0 "register_operand" "")
17949 (match_operand:SI 1 "memory_operand" "")]
17950 ""
17951 {
17952 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17953 gen_rtvec (1, const0_rtx),
17954 UNSPECV_RDTSCP);
17955 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17956 gen_rtvec (1, const0_rtx),
17957 UNSPECV_RDTSCP);
17958 rtx reg = gen_reg_rtx (DImode);
17959 rtx tmp = gen_reg_rtx (SImode);
17960
17961 if (TARGET_64BIT)
17962 {
17963 rtvec vec = rtvec_alloc (3);
17964 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17965 rtx upper = gen_reg_rtx (DImode);
17966 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17967 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17968 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17969 emit_insn (load);
17970 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17971 NULL, 1, OPTAB_DIRECT);
17972 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17973 OPTAB_DIRECT);
17974 }
17975 else
17976 {
17977 rtvec vec = rtvec_alloc (2);
17978 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17979 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17980 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17981 emit_insn (load);
17982 }
17983 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17984 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17985 DONE;
17986 })
17987
17988 (define_insn "*rdtscp"
17989 [(set (match_operand:DI 0 "register_operand" "=A")
17990 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17991 (set (match_operand:SI 1 "register_operand" "=c")
17992 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17993 "!TARGET_64BIT"
17994 "rdtscp"
17995 [(set_attr "type" "other")
17996 (set_attr "length" "3")])
17997
17998 (define_insn "*rdtscp_rex64"
17999 [(set (match_operand:DI 0 "register_operand" "=a")
18000 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18001 (set (match_operand:DI 1 "register_operand" "=d")
18002 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18003 (set (match_operand:SI 2 "register_operand" "=c")
18004 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18005 "TARGET_64BIT"
18006 "rdtscp"
18007 [(set_attr "type" "other")
18008 (set_attr "length" "3")])
18009
18010 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18011 ;;
18012 ;; LWP instructions
18013 ;;
18014 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18015
18016 (define_expand "lwp_llwpcb"
18017 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18018 UNSPECV_LLWP_INTRINSIC)]
18019 "TARGET_LWP")
18020
18021 (define_insn "*lwp_llwpcb<mode>1"
18022 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18023 UNSPECV_LLWP_INTRINSIC)]
18024 "TARGET_LWP"
18025 "llwpcb\t%0"
18026 [(set_attr "type" "lwp")
18027 (set_attr "mode" "<MODE>")
18028 (set_attr "length" "5")])
18029
18030 (define_expand "lwp_slwpcb"
18031 [(set (match_operand 0 "register_operand" "=r")
18032 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18033 "TARGET_LWP"
18034 {
18035 rtx (*insn)(rtx);
18036
18037 insn = (TARGET_64BIT
18038 ? gen_lwp_slwpcbdi
18039 : gen_lwp_slwpcbsi);
18040
18041 emit_insn (insn (operands[0]));
18042 DONE;
18043 })
18044
18045 (define_insn "lwp_slwpcb<mode>"
18046 [(set (match_operand:P 0 "register_operand" "=r")
18047 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18048 "TARGET_LWP"
18049 "slwpcb\t%0"
18050 [(set_attr "type" "lwp")
18051 (set_attr "mode" "<MODE>")
18052 (set_attr "length" "5")])
18053
18054 (define_expand "lwp_lwpval<mode>3"
18055 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18056 (match_operand:SI 2 "nonimmediate_operand" "rm")
18057 (match_operand:SI 3 "const_int_operand" "i")]
18058 UNSPECV_LWPVAL_INTRINSIC)]
18059 "TARGET_LWP"
18060 "/* Avoid unused variable warning. */
18061 (void) operand0;")
18062
18063 (define_insn "*lwp_lwpval<mode>3_1"
18064 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18065 (match_operand:SI 1 "nonimmediate_operand" "rm")
18066 (match_operand:SI 2 "const_int_operand" "i")]
18067 UNSPECV_LWPVAL_INTRINSIC)]
18068 "TARGET_LWP"
18069 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18070 [(set_attr "type" "lwp")
18071 (set_attr "mode" "<MODE>")
18072 (set (attr "length")
18073 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18074
18075 (define_expand "lwp_lwpins<mode>3"
18076 [(set (reg:CCC FLAGS_REG)
18077 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18078 (match_operand:SI 2 "nonimmediate_operand" "rm")
18079 (match_operand:SI 3 "const_int_operand" "i")]
18080 UNSPECV_LWPINS_INTRINSIC))
18081 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18082 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18083 "TARGET_LWP")
18084
18085 (define_insn "*lwp_lwpins<mode>3_1"
18086 [(set (reg:CCC FLAGS_REG)
18087 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18088 (match_operand:SI 1 "nonimmediate_operand" "rm")
18089 (match_operand:SI 2 "const_int_operand" "i")]
18090 UNSPECV_LWPINS_INTRINSIC))]
18091 "TARGET_LWP"
18092 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18093 [(set_attr "type" "lwp")
18094 (set_attr "mode" "<MODE>")
18095 (set (attr "length")
18096 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18097
18098 (define_insn "rdfsbase<mode>"
18099 [(set (match_operand:SWI48 0 "register_operand" "=r")
18100 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18101 "TARGET_64BIT && TARGET_FSGSBASE"
18102 "rdfsbase %0"
18103 [(set_attr "type" "other")
18104 (set_attr "prefix_extra" "2")])
18105
18106 (define_insn "rdgsbase<mode>"
18107 [(set (match_operand:SWI48 0 "register_operand" "=r")
18108 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18109 "TARGET_64BIT && TARGET_FSGSBASE"
18110 "rdgsbase %0"
18111 [(set_attr "type" "other")
18112 (set_attr "prefix_extra" "2")])
18113
18114 (define_insn "wrfsbase<mode>"
18115 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18116 UNSPECV_WRFSBASE)]
18117 "TARGET_64BIT && TARGET_FSGSBASE"
18118 "wrfsbase %0"
18119 [(set_attr "type" "other")
18120 (set_attr "prefix_extra" "2")])
18121
18122 (define_insn "wrgsbase<mode>"
18123 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18124 UNSPECV_WRGSBASE)]
18125 "TARGET_64BIT && TARGET_FSGSBASE"
18126 "wrgsbase %0"
18127 [(set_attr "type" "other")
18128 (set_attr "prefix_extra" "2")])
18129
18130 (define_insn "rdrand<mode>_1"
18131 [(set (match_operand:SWI248 0 "register_operand" "=r")
18132 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18133 (set (reg:CCC FLAGS_REG)
18134 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18135 "TARGET_RDRND"
18136 "rdrand\t%0"
18137 [(set_attr "type" "other")
18138 (set_attr "prefix_extra" "1")])
18139
18140 (define_expand "pause"
18141 [(set (match_dup 0)
18142 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18143 ""
18144 {
18145 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18146 MEM_VOLATILE_P (operands[0]) = 1;
18147 })
18148
18149 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18150 ;; They have the same encoding.
18151 (define_insn "*pause"
18152 [(set (match_operand:BLK 0 "" "")
18153 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18154 ""
18155 "rep; nop"
18156 [(set_attr "length" "2")
18157 (set_attr "memory" "unknown")])
18158
18159 (include "mmx.md")
18160 (include "sse.md")
18161 (include "sync.md")