91a830104a4d1eec8c39b0c8625bc17ff91fda75
[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 shift-right operators
776 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
777
778 ;; Base name for define_insn
779 (define_code_attr shift_insn
780 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
781
782 ;; Base name for insn mnemonic.
783 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
784
785 ;; Mapping of rotate operators
786 (define_code_iterator any_rotate [rotate rotatert])
787
788 ;; Base name for define_insn
789 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
790
791 ;; Base name for insn mnemonic.
792 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
793
794 ;; Mapping of abs neg operators
795 (define_code_iterator absneg [abs neg])
796
797 ;; Base name for x87 insn mnemonic.
798 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
799
800 ;; Used in signed and unsigned widening multiplications.
801 (define_code_iterator any_extend [sign_extend zero_extend])
802
803 ;; Prefix for insn menmonic.
804 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
805
806 ;; Prefix for define_insn
807 (define_code_attr u [(sign_extend "") (zero_extend "u")])
808 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
809
810 ;; All integer modes.
811 (define_mode_iterator SWI1248x [QI HI SI DI])
812
813 ;; All integer modes without QImode.
814 (define_mode_iterator SWI248x [HI SI DI])
815
816 ;; All integer modes without QImode and HImode.
817 (define_mode_iterator SWI48x [SI DI])
818
819 ;; All integer modes without SImode and DImode.
820 (define_mode_iterator SWI12 [QI HI])
821
822 ;; All integer modes without DImode.
823 (define_mode_iterator SWI124 [QI HI SI])
824
825 ;; All integer modes without QImode and DImode.
826 (define_mode_iterator SWI24 [HI SI])
827
828 ;; Single word integer modes.
829 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
830
831 ;; Single word integer modes without QImode.
832 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
833
834 ;; Single word integer modes without QImode and HImode.
835 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
836
837 ;; All math-dependant single and double word integer modes.
838 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
839 (HI "TARGET_HIMODE_MATH")
840 SI DI (TI "TARGET_64BIT")])
841
842 ;; Math-dependant single word integer modes.
843 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
844 (HI "TARGET_HIMODE_MATH")
845 SI (DI "TARGET_64BIT")])
846
847 ;; Math-dependant integer modes without DImode.
848 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
849 (HI "TARGET_HIMODE_MATH")
850 SI])
851
852 ;; Math-dependant single word integer modes without QImode.
853 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
854 SI (DI "TARGET_64BIT")])
855
856 ;; Double word integer modes.
857 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
858 (TI "TARGET_64BIT")])
859
860 ;; Double word integer modes as mode attribute.
861 (define_mode_attr DWI [(SI "DI") (DI "TI")])
862 (define_mode_attr dwi [(SI "di") (DI "ti")])
863
864 ;; Half mode for double word integer modes.
865 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
866 (DI "TARGET_64BIT")])
867
868 ;; Instruction suffix for integer modes.
869 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
870
871 ;; Pointer size prefix for integer modes (Intel asm dialect)
872 (define_mode_attr iptrsize [(QI "BYTE")
873 (HI "WORD")
874 (SI "DWORD")
875 (DI "QWORD")])
876
877 ;; Register class for integer modes.
878 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
879
880 ;; Immediate operand constraint for integer modes.
881 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
882
883 ;; General operand constraint for word modes.
884 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
885
886 ;; Immediate operand constraint for double integer modes.
887 (define_mode_attr di [(SI "nF") (DI "e")])
888
889 ;; Immediate operand constraint for shifts.
890 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
891
892 ;; General operand predicate for integer modes.
893 (define_mode_attr general_operand
894 [(QI "general_operand")
895 (HI "general_operand")
896 (SI "x86_64_general_operand")
897 (DI "x86_64_general_operand")
898 (TI "x86_64_general_operand")])
899
900 ;; General sign/zero extend operand predicate for integer modes.
901 (define_mode_attr general_szext_operand
902 [(QI "general_operand")
903 (HI "general_operand")
904 (SI "x86_64_szext_general_operand")
905 (DI "x86_64_szext_general_operand")])
906
907 ;; Immediate operand predicate for integer modes.
908 (define_mode_attr immediate_operand
909 [(QI "immediate_operand")
910 (HI "immediate_operand")
911 (SI "x86_64_immediate_operand")
912 (DI "x86_64_immediate_operand")])
913
914 ;; Nonmemory operand predicate for integer modes.
915 (define_mode_attr nonmemory_operand
916 [(QI "nonmemory_operand")
917 (HI "nonmemory_operand")
918 (SI "x86_64_nonmemory_operand")
919 (DI "x86_64_nonmemory_operand")])
920
921 ;; Operand predicate for shifts.
922 (define_mode_attr shift_operand
923 [(QI "nonimmediate_operand")
924 (HI "nonimmediate_operand")
925 (SI "nonimmediate_operand")
926 (DI "shiftdi_operand")
927 (TI "register_operand")])
928
929 ;; Operand predicate for shift argument.
930 (define_mode_attr shift_immediate_operand
931 [(QI "const_1_to_31_operand")
932 (HI "const_1_to_31_operand")
933 (SI "const_1_to_31_operand")
934 (DI "const_1_to_63_operand")])
935
936 ;; Input operand predicate for arithmetic left shifts.
937 (define_mode_attr ashl_input_operand
938 [(QI "nonimmediate_operand")
939 (HI "nonimmediate_operand")
940 (SI "nonimmediate_operand")
941 (DI "ashldi_input_operand")
942 (TI "reg_or_pm1_operand")])
943
944 ;; SSE and x87 SFmode and DFmode floating point modes
945 (define_mode_iterator MODEF [SF DF])
946
947 ;; All x87 floating point modes
948 (define_mode_iterator X87MODEF [SF DF XF])
949
950 ;; SSE instruction suffix for various modes
951 (define_mode_attr ssemodesuffix
952 [(SF "ss") (DF "sd")
953 (V8SF "ps") (V4DF "pd")
954 (V4SF "ps") (V2DF "pd")
955 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
956 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
957
958 ;; SSE vector suffix for floating point modes
959 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
960
961 ;; SSE vector mode corresponding to a scalar mode
962 (define_mode_attr ssevecmode
963 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
964
965 ;; Instruction suffix for REX 64bit operators.
966 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
967
968 ;; This mode iterator allows :P to be used for patterns that operate on
969 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
970 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
971
972 ;; This mode iterator allows :PTR to be used for patterns that operate on
973 ;; ptr_mode sized quantities.
974 (define_mode_iterator PTR
975 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
976 \f
977 ;; Scheduling descriptions
978
979 (include "pentium.md")
980 (include "ppro.md")
981 (include "k6.md")
982 (include "athlon.md")
983 (include "bdver1.md")
984 (include "geode.md")
985 (include "atom.md")
986 (include "core2.md")
987
988 \f
989 ;; Operand and operator predicates and constraints
990
991 (include "predicates.md")
992 (include "constraints.md")
993
994 \f
995 ;; Compare and branch/compare and store instructions.
996
997 (define_expand "cbranch<mode>4"
998 [(set (reg:CC FLAGS_REG)
999 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
1000 (match_operand:SDWIM 2 "<general_operand>" "")))
1001 (set (pc) (if_then_else
1002 (match_operator 0 "ordered_comparison_operator"
1003 [(reg:CC FLAGS_REG) (const_int 0)])
1004 (label_ref (match_operand 3 "" ""))
1005 (pc)))]
1006 ""
1007 {
1008 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1009 operands[1] = force_reg (<MODE>mode, operands[1]);
1010 ix86_expand_branch (GET_CODE (operands[0]),
1011 operands[1], operands[2], operands[3]);
1012 DONE;
1013 })
1014
1015 (define_expand "cstore<mode>4"
1016 [(set (reg:CC FLAGS_REG)
1017 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1018 (match_operand:SWIM 3 "<general_operand>" "")))
1019 (set (match_operand:QI 0 "register_operand" "")
1020 (match_operator 1 "ordered_comparison_operator"
1021 [(reg:CC FLAGS_REG) (const_int 0)]))]
1022 ""
1023 {
1024 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1025 operands[2] = force_reg (<MODE>mode, operands[2]);
1026 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1027 operands[2], operands[3]);
1028 DONE;
1029 })
1030
1031 (define_expand "cmp<mode>_1"
1032 [(set (reg:CC FLAGS_REG)
1033 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1034 (match_operand:SWI48 1 "<general_operand>" "")))])
1035
1036 (define_insn "*cmp<mode>_ccno_1"
1037 [(set (reg FLAGS_REG)
1038 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1039 (match_operand:SWI 1 "const0_operand" "")))]
1040 "ix86_match_ccmode (insn, CCNOmode)"
1041 "@
1042 test{<imodesuffix>}\t%0, %0
1043 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1044 [(set_attr "type" "test,icmp")
1045 (set_attr "length_immediate" "0,1")
1046 (set_attr "mode" "<MODE>")])
1047
1048 (define_insn "*cmp<mode>_1"
1049 [(set (reg FLAGS_REG)
1050 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1051 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1052 "ix86_match_ccmode (insn, CCmode)"
1053 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1054 [(set_attr "type" "icmp")
1055 (set_attr "mode" "<MODE>")])
1056
1057 (define_insn "*cmp<mode>_minus_1"
1058 [(set (reg FLAGS_REG)
1059 (compare
1060 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1061 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1062 (const_int 0)))]
1063 "ix86_match_ccmode (insn, CCGOCmode)"
1064 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1065 [(set_attr "type" "icmp")
1066 (set_attr "mode" "<MODE>")])
1067
1068 (define_insn "*cmpqi_ext_1"
1069 [(set (reg FLAGS_REG)
1070 (compare
1071 (match_operand:QI 0 "general_operand" "Qm")
1072 (subreg:QI
1073 (zero_extract:SI
1074 (match_operand 1 "ext_register_operand" "Q")
1075 (const_int 8)
1076 (const_int 8)) 0)))]
1077 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1078 "cmp{b}\t{%h1, %0|%0, %h1}"
1079 [(set_attr "type" "icmp")
1080 (set_attr "mode" "QI")])
1081
1082 (define_insn "*cmpqi_ext_1_rex64"
1083 [(set (reg FLAGS_REG)
1084 (compare
1085 (match_operand:QI 0 "register_operand" "Q")
1086 (subreg:QI
1087 (zero_extract:SI
1088 (match_operand 1 "ext_register_operand" "Q")
1089 (const_int 8)
1090 (const_int 8)) 0)))]
1091 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1092 "cmp{b}\t{%h1, %0|%0, %h1}"
1093 [(set_attr "type" "icmp")
1094 (set_attr "mode" "QI")])
1095
1096 (define_insn "*cmpqi_ext_2"
1097 [(set (reg FLAGS_REG)
1098 (compare
1099 (subreg:QI
1100 (zero_extract:SI
1101 (match_operand 0 "ext_register_operand" "Q")
1102 (const_int 8)
1103 (const_int 8)) 0)
1104 (match_operand:QI 1 "const0_operand" "")))]
1105 "ix86_match_ccmode (insn, CCNOmode)"
1106 "test{b}\t%h0, %h0"
1107 [(set_attr "type" "test")
1108 (set_attr "length_immediate" "0")
1109 (set_attr "mode" "QI")])
1110
1111 (define_expand "cmpqi_ext_3"
1112 [(set (reg:CC FLAGS_REG)
1113 (compare:CC
1114 (subreg:QI
1115 (zero_extract:SI
1116 (match_operand 0 "ext_register_operand" "")
1117 (const_int 8)
1118 (const_int 8)) 0)
1119 (match_operand:QI 1 "immediate_operand" "")))])
1120
1121 (define_insn "*cmpqi_ext_3_insn"
1122 [(set (reg FLAGS_REG)
1123 (compare
1124 (subreg:QI
1125 (zero_extract:SI
1126 (match_operand 0 "ext_register_operand" "Q")
1127 (const_int 8)
1128 (const_int 8)) 0)
1129 (match_operand:QI 1 "general_operand" "Qmn")))]
1130 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1131 "cmp{b}\t{%1, %h0|%h0, %1}"
1132 [(set_attr "type" "icmp")
1133 (set_attr "modrm" "1")
1134 (set_attr "mode" "QI")])
1135
1136 (define_insn "*cmpqi_ext_3_insn_rex64"
1137 [(set (reg FLAGS_REG)
1138 (compare
1139 (subreg:QI
1140 (zero_extract:SI
1141 (match_operand 0 "ext_register_operand" "Q")
1142 (const_int 8)
1143 (const_int 8)) 0)
1144 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1145 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1146 "cmp{b}\t{%1, %h0|%h0, %1}"
1147 [(set_attr "type" "icmp")
1148 (set_attr "modrm" "1")
1149 (set_attr "mode" "QI")])
1150
1151 (define_insn "*cmpqi_ext_4"
1152 [(set (reg FLAGS_REG)
1153 (compare
1154 (subreg:QI
1155 (zero_extract:SI
1156 (match_operand 0 "ext_register_operand" "Q")
1157 (const_int 8)
1158 (const_int 8)) 0)
1159 (subreg:QI
1160 (zero_extract:SI
1161 (match_operand 1 "ext_register_operand" "Q")
1162 (const_int 8)
1163 (const_int 8)) 0)))]
1164 "ix86_match_ccmode (insn, CCmode)"
1165 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1166 [(set_attr "type" "icmp")
1167 (set_attr "mode" "QI")])
1168
1169 ;; These implement float point compares.
1170 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1171 ;; which would allow mix and match FP modes on the compares. Which is what
1172 ;; the old patterns did, but with many more of them.
1173
1174 (define_expand "cbranchxf4"
1175 [(set (reg:CC FLAGS_REG)
1176 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1177 (match_operand:XF 2 "nonmemory_operand" "")))
1178 (set (pc) (if_then_else
1179 (match_operator 0 "ix86_fp_comparison_operator"
1180 [(reg:CC FLAGS_REG)
1181 (const_int 0)])
1182 (label_ref (match_operand 3 "" ""))
1183 (pc)))]
1184 "TARGET_80387"
1185 {
1186 ix86_expand_branch (GET_CODE (operands[0]),
1187 operands[1], operands[2], operands[3]);
1188 DONE;
1189 })
1190
1191 (define_expand "cstorexf4"
1192 [(set (reg:CC FLAGS_REG)
1193 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1194 (match_operand:XF 3 "nonmemory_operand" "")))
1195 (set (match_operand:QI 0 "register_operand" "")
1196 (match_operator 1 "ix86_fp_comparison_operator"
1197 [(reg:CC FLAGS_REG)
1198 (const_int 0)]))]
1199 "TARGET_80387"
1200 {
1201 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1202 operands[2], operands[3]);
1203 DONE;
1204 })
1205
1206 (define_expand "cbranch<mode>4"
1207 [(set (reg:CC FLAGS_REG)
1208 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1209 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1210 (set (pc) (if_then_else
1211 (match_operator 0 "ix86_fp_comparison_operator"
1212 [(reg:CC FLAGS_REG)
1213 (const_int 0)])
1214 (label_ref (match_operand 3 "" ""))
1215 (pc)))]
1216 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1217 {
1218 ix86_expand_branch (GET_CODE (operands[0]),
1219 operands[1], operands[2], operands[3]);
1220 DONE;
1221 })
1222
1223 (define_expand "cstore<mode>4"
1224 [(set (reg:CC FLAGS_REG)
1225 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1226 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1227 (set (match_operand:QI 0 "register_operand" "")
1228 (match_operator 1 "ix86_fp_comparison_operator"
1229 [(reg:CC FLAGS_REG)
1230 (const_int 0)]))]
1231 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1232 {
1233 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1234 operands[2], operands[3]);
1235 DONE;
1236 })
1237
1238 (define_expand "cbranchcc4"
1239 [(set (pc) (if_then_else
1240 (match_operator 0 "comparison_operator"
1241 [(match_operand 1 "flags_reg_operand" "")
1242 (match_operand 2 "const0_operand" "")])
1243 (label_ref (match_operand 3 "" ""))
1244 (pc)))]
1245 ""
1246 {
1247 ix86_expand_branch (GET_CODE (operands[0]),
1248 operands[1], operands[2], operands[3]);
1249 DONE;
1250 })
1251
1252 (define_expand "cstorecc4"
1253 [(set (match_operand:QI 0 "register_operand" "")
1254 (match_operator 1 "comparison_operator"
1255 [(match_operand 2 "flags_reg_operand" "")
1256 (match_operand 3 "const0_operand" "")]))]
1257 ""
1258 {
1259 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1260 operands[2], operands[3]);
1261 DONE;
1262 })
1263
1264
1265 ;; FP compares, step 1:
1266 ;; Set the FP condition codes.
1267 ;;
1268 ;; CCFPmode compare with exceptions
1269 ;; CCFPUmode compare with no exceptions
1270
1271 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1272 ;; used to manage the reg stack popping would not be preserved.
1273
1274 (define_insn "*cmpfp_0"
1275 [(set (match_operand:HI 0 "register_operand" "=a")
1276 (unspec:HI
1277 [(compare:CCFP
1278 (match_operand 1 "register_operand" "f")
1279 (match_operand 2 "const0_operand" ""))]
1280 UNSPEC_FNSTSW))]
1281 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1282 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1283 "* return output_fp_compare (insn, operands, false, false);"
1284 [(set_attr "type" "multi")
1285 (set_attr "unit" "i387")
1286 (set (attr "mode")
1287 (cond [(match_operand:SF 1 "" "")
1288 (const_string "SF")
1289 (match_operand:DF 1 "" "")
1290 (const_string "DF")
1291 ]
1292 (const_string "XF")))])
1293
1294 (define_insn_and_split "*cmpfp_0_cc"
1295 [(set (reg:CCFP FLAGS_REG)
1296 (compare:CCFP
1297 (match_operand 1 "register_operand" "f")
1298 (match_operand 2 "const0_operand" "")))
1299 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1300 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1301 && TARGET_SAHF && !TARGET_CMOVE
1302 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1303 "#"
1304 "&& reload_completed"
1305 [(set (match_dup 0)
1306 (unspec:HI
1307 [(compare:CCFP (match_dup 1)(match_dup 2))]
1308 UNSPEC_FNSTSW))
1309 (set (reg:CC FLAGS_REG)
1310 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1311 ""
1312 [(set_attr "type" "multi")
1313 (set_attr "unit" "i387")
1314 (set (attr "mode")
1315 (cond [(match_operand:SF 1 "" "")
1316 (const_string "SF")
1317 (match_operand:DF 1 "" "")
1318 (const_string "DF")
1319 ]
1320 (const_string "XF")))])
1321
1322 (define_insn "*cmpfp_xf"
1323 [(set (match_operand:HI 0 "register_operand" "=a")
1324 (unspec:HI
1325 [(compare:CCFP
1326 (match_operand:XF 1 "register_operand" "f")
1327 (match_operand:XF 2 "register_operand" "f"))]
1328 UNSPEC_FNSTSW))]
1329 "TARGET_80387"
1330 "* return output_fp_compare (insn, operands, false, false);"
1331 [(set_attr "type" "multi")
1332 (set_attr "unit" "i387")
1333 (set_attr "mode" "XF")])
1334
1335 (define_insn_and_split "*cmpfp_xf_cc"
1336 [(set (reg:CCFP FLAGS_REG)
1337 (compare:CCFP
1338 (match_operand:XF 1 "register_operand" "f")
1339 (match_operand:XF 2 "register_operand" "f")))
1340 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1341 "TARGET_80387
1342 && TARGET_SAHF && !TARGET_CMOVE"
1343 "#"
1344 "&& reload_completed"
1345 [(set (match_dup 0)
1346 (unspec:HI
1347 [(compare:CCFP (match_dup 1)(match_dup 2))]
1348 UNSPEC_FNSTSW))
1349 (set (reg:CC FLAGS_REG)
1350 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1351 ""
1352 [(set_attr "type" "multi")
1353 (set_attr "unit" "i387")
1354 (set_attr "mode" "XF")])
1355
1356 (define_insn "*cmpfp_<mode>"
1357 [(set (match_operand:HI 0 "register_operand" "=a")
1358 (unspec:HI
1359 [(compare:CCFP
1360 (match_operand:MODEF 1 "register_operand" "f")
1361 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1362 UNSPEC_FNSTSW))]
1363 "TARGET_80387"
1364 "* return output_fp_compare (insn, operands, false, false);"
1365 [(set_attr "type" "multi")
1366 (set_attr "unit" "i387")
1367 (set_attr "mode" "<MODE>")])
1368
1369 (define_insn_and_split "*cmpfp_<mode>_cc"
1370 [(set (reg:CCFP FLAGS_REG)
1371 (compare:CCFP
1372 (match_operand:MODEF 1 "register_operand" "f")
1373 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1374 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1375 "TARGET_80387
1376 && TARGET_SAHF && !TARGET_CMOVE"
1377 "#"
1378 "&& reload_completed"
1379 [(set (match_dup 0)
1380 (unspec:HI
1381 [(compare:CCFP (match_dup 1)(match_dup 2))]
1382 UNSPEC_FNSTSW))
1383 (set (reg:CC FLAGS_REG)
1384 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1385 ""
1386 [(set_attr "type" "multi")
1387 (set_attr "unit" "i387")
1388 (set_attr "mode" "<MODE>")])
1389
1390 (define_insn "*cmpfp_u"
1391 [(set (match_operand:HI 0 "register_operand" "=a")
1392 (unspec:HI
1393 [(compare:CCFPU
1394 (match_operand 1 "register_operand" "f")
1395 (match_operand 2 "register_operand" "f"))]
1396 UNSPEC_FNSTSW))]
1397 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1398 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1399 "* return output_fp_compare (insn, operands, false, true);"
1400 [(set_attr "type" "multi")
1401 (set_attr "unit" "i387")
1402 (set (attr "mode")
1403 (cond [(match_operand:SF 1 "" "")
1404 (const_string "SF")
1405 (match_operand:DF 1 "" "")
1406 (const_string "DF")
1407 ]
1408 (const_string "XF")))])
1409
1410 (define_insn_and_split "*cmpfp_u_cc"
1411 [(set (reg:CCFPU FLAGS_REG)
1412 (compare:CCFPU
1413 (match_operand 1 "register_operand" "f")
1414 (match_operand 2 "register_operand" "f")))
1415 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1416 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1417 && TARGET_SAHF && !TARGET_CMOVE
1418 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1419 "#"
1420 "&& reload_completed"
1421 [(set (match_dup 0)
1422 (unspec:HI
1423 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1424 UNSPEC_FNSTSW))
1425 (set (reg:CC FLAGS_REG)
1426 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1427 ""
1428 [(set_attr "type" "multi")
1429 (set_attr "unit" "i387")
1430 (set (attr "mode")
1431 (cond [(match_operand:SF 1 "" "")
1432 (const_string "SF")
1433 (match_operand:DF 1 "" "")
1434 (const_string "DF")
1435 ]
1436 (const_string "XF")))])
1437
1438 (define_insn "*cmpfp_<mode>"
1439 [(set (match_operand:HI 0 "register_operand" "=a")
1440 (unspec:HI
1441 [(compare:CCFP
1442 (match_operand 1 "register_operand" "f")
1443 (match_operator 3 "float_operator"
1444 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1445 UNSPEC_FNSTSW))]
1446 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1447 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1448 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1449 "* return output_fp_compare (insn, operands, false, false);"
1450 [(set_attr "type" "multi")
1451 (set_attr "unit" "i387")
1452 (set_attr "fp_int_src" "true")
1453 (set_attr "mode" "<MODE>")])
1454
1455 (define_insn_and_split "*cmpfp_<mode>_cc"
1456 [(set (reg:CCFP FLAGS_REG)
1457 (compare:CCFP
1458 (match_operand 1 "register_operand" "f")
1459 (match_operator 3 "float_operator"
1460 [(match_operand:SWI24 2 "memory_operand" "m")])))
1461 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1462 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1463 && TARGET_SAHF && !TARGET_CMOVE
1464 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1465 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1466 "#"
1467 "&& reload_completed"
1468 [(set (match_dup 0)
1469 (unspec:HI
1470 [(compare:CCFP
1471 (match_dup 1)
1472 (match_op_dup 3 [(match_dup 2)]))]
1473 UNSPEC_FNSTSW))
1474 (set (reg:CC FLAGS_REG)
1475 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1476 ""
1477 [(set_attr "type" "multi")
1478 (set_attr "unit" "i387")
1479 (set_attr "fp_int_src" "true")
1480 (set_attr "mode" "<MODE>")])
1481
1482 ;; FP compares, step 2
1483 ;; Move the fpsw to ax.
1484
1485 (define_insn "x86_fnstsw_1"
1486 [(set (match_operand:HI 0 "register_operand" "=a")
1487 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1488 "TARGET_80387"
1489 "fnstsw\t%0"
1490 [(set (attr "length")
1491 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1492 (set_attr "mode" "SI")
1493 (set_attr "unit" "i387")])
1494
1495 ;; FP compares, step 3
1496 ;; Get ax into flags, general case.
1497
1498 (define_insn "x86_sahf_1"
1499 [(set (reg:CC FLAGS_REG)
1500 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1501 UNSPEC_SAHF))]
1502 "TARGET_SAHF"
1503 {
1504 #ifndef HAVE_AS_IX86_SAHF
1505 if (TARGET_64BIT)
1506 return ASM_BYTE "0x9e";
1507 else
1508 #endif
1509 return "sahf";
1510 }
1511 [(set_attr "length" "1")
1512 (set_attr "athlon_decode" "vector")
1513 (set_attr "amdfam10_decode" "direct")
1514 (set_attr "bdver1_decode" "direct")
1515 (set_attr "mode" "SI")])
1516
1517 ;; Pentium Pro can do steps 1 through 3 in one go.
1518 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1519 ;; (these i387 instructions set flags directly)
1520 (define_insn "*cmpfp_i_mixed"
1521 [(set (reg:CCFP FLAGS_REG)
1522 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1523 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1524 "TARGET_MIX_SSE_I387
1525 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1526 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1527 "* return output_fp_compare (insn, operands, true, false);"
1528 [(set_attr "type" "fcmp,ssecomi")
1529 (set_attr "prefix" "orig,maybe_vex")
1530 (set (attr "mode")
1531 (if_then_else (match_operand:SF 1 "" "")
1532 (const_string "SF")
1533 (const_string "DF")))
1534 (set (attr "prefix_rep")
1535 (if_then_else (eq_attr "type" "ssecomi")
1536 (const_string "0")
1537 (const_string "*")))
1538 (set (attr "prefix_data16")
1539 (cond [(eq_attr "type" "fcmp")
1540 (const_string "*")
1541 (eq_attr "mode" "DF")
1542 (const_string "1")
1543 ]
1544 (const_string "0")))
1545 (set_attr "athlon_decode" "vector")
1546 (set_attr "amdfam10_decode" "direct")
1547 (set_attr "bdver1_decode" "double")])
1548
1549 (define_insn "*cmpfp_i_sse"
1550 [(set (reg:CCFP FLAGS_REG)
1551 (compare:CCFP (match_operand 0 "register_operand" "x")
1552 (match_operand 1 "nonimmediate_operand" "xm")))]
1553 "TARGET_SSE_MATH
1554 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1555 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556 "* return output_fp_compare (insn, operands, true, false);"
1557 [(set_attr "type" "ssecomi")
1558 (set_attr "prefix" "maybe_vex")
1559 (set (attr "mode")
1560 (if_then_else (match_operand:SF 1 "" "")
1561 (const_string "SF")
1562 (const_string "DF")))
1563 (set_attr "prefix_rep" "0")
1564 (set (attr "prefix_data16")
1565 (if_then_else (eq_attr "mode" "DF")
1566 (const_string "1")
1567 (const_string "0")))
1568 (set_attr "athlon_decode" "vector")
1569 (set_attr "amdfam10_decode" "direct")
1570 (set_attr "bdver1_decode" "double")])
1571
1572 (define_insn "*cmpfp_i_i387"
1573 [(set (reg:CCFP FLAGS_REG)
1574 (compare:CCFP (match_operand 0 "register_operand" "f")
1575 (match_operand 1 "register_operand" "f")))]
1576 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1577 && TARGET_CMOVE
1578 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1579 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1580 "* return output_fp_compare (insn, operands, true, false);"
1581 [(set_attr "type" "fcmp")
1582 (set (attr "mode")
1583 (cond [(match_operand:SF 1 "" "")
1584 (const_string "SF")
1585 (match_operand:DF 1 "" "")
1586 (const_string "DF")
1587 ]
1588 (const_string "XF")))
1589 (set_attr "athlon_decode" "vector")
1590 (set_attr "amdfam10_decode" "direct")
1591 (set_attr "bdver1_decode" "double")])
1592
1593 (define_insn "*cmpfp_iu_mixed"
1594 [(set (reg:CCFPU FLAGS_REG)
1595 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1596 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1597 "TARGET_MIX_SSE_I387
1598 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1599 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1600 "* return output_fp_compare (insn, operands, true, true);"
1601 [(set_attr "type" "fcmp,ssecomi")
1602 (set_attr "prefix" "orig,maybe_vex")
1603 (set (attr "mode")
1604 (if_then_else (match_operand:SF 1 "" "")
1605 (const_string "SF")
1606 (const_string "DF")))
1607 (set (attr "prefix_rep")
1608 (if_then_else (eq_attr "type" "ssecomi")
1609 (const_string "0")
1610 (const_string "*")))
1611 (set (attr "prefix_data16")
1612 (cond [(eq_attr "type" "fcmp")
1613 (const_string "*")
1614 (eq_attr "mode" "DF")
1615 (const_string "1")
1616 ]
1617 (const_string "0")))
1618 (set_attr "athlon_decode" "vector")
1619 (set_attr "amdfam10_decode" "direct")
1620 (set_attr "bdver1_decode" "double")])
1621
1622 (define_insn "*cmpfp_iu_sse"
1623 [(set (reg:CCFPU FLAGS_REG)
1624 (compare:CCFPU (match_operand 0 "register_operand" "x")
1625 (match_operand 1 "nonimmediate_operand" "xm")))]
1626 "TARGET_SSE_MATH
1627 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1628 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1629 "* return output_fp_compare (insn, operands, true, true);"
1630 [(set_attr "type" "ssecomi")
1631 (set_attr "prefix" "maybe_vex")
1632 (set (attr "mode")
1633 (if_then_else (match_operand:SF 1 "" "")
1634 (const_string "SF")
1635 (const_string "DF")))
1636 (set_attr "prefix_rep" "0")
1637 (set (attr "prefix_data16")
1638 (if_then_else (eq_attr "mode" "DF")
1639 (const_string "1")
1640 (const_string "0")))
1641 (set_attr "athlon_decode" "vector")
1642 (set_attr "amdfam10_decode" "direct")
1643 (set_attr "bdver1_decode" "double")])
1644
1645 (define_insn "*cmpfp_iu_387"
1646 [(set (reg:CCFPU FLAGS_REG)
1647 (compare:CCFPU (match_operand 0 "register_operand" "f")
1648 (match_operand 1 "register_operand" "f")))]
1649 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1650 && TARGET_CMOVE
1651 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1652 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1653 "* return output_fp_compare (insn, operands, true, true);"
1654 [(set_attr "type" "fcmp")
1655 (set (attr "mode")
1656 (cond [(match_operand:SF 1 "" "")
1657 (const_string "SF")
1658 (match_operand:DF 1 "" "")
1659 (const_string "DF")
1660 ]
1661 (const_string "XF")))
1662 (set_attr "athlon_decode" "vector")
1663 (set_attr "amdfam10_decode" "direct")
1664 (set_attr "bdver1_decode" "direct")])
1665 \f
1666 ;; Push/pop instructions.
1667
1668 (define_insn "*push<mode>2"
1669 [(set (match_operand:DWI 0 "push_operand" "=<")
1670 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1671 ""
1672 "#"
1673 [(set_attr "type" "multi")
1674 (set_attr "mode" "<MODE>")])
1675
1676 (define_split
1677 [(set (match_operand:TI 0 "push_operand" "")
1678 (match_operand:TI 1 "general_operand" ""))]
1679 "TARGET_64BIT && reload_completed
1680 && !SSE_REG_P (operands[1])"
1681 [(const_int 0)]
1682 "ix86_split_long_move (operands); DONE;")
1683
1684 (define_insn "*pushdi2_rex64"
1685 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1686 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1687 "TARGET_64BIT"
1688 "@
1689 push{q}\t%1
1690 #"
1691 [(set_attr "type" "push,multi")
1692 (set_attr "mode" "DI")])
1693
1694 ;; Convert impossible pushes of immediate to existing instructions.
1695 ;; First try to get scratch register and go through it. In case this
1696 ;; fails, push sign extended lower part first and then overwrite
1697 ;; upper part by 32bit move.
1698 (define_peephole2
1699 [(match_scratch:DI 2 "r")
1700 (set (match_operand:DI 0 "push_operand" "")
1701 (match_operand:DI 1 "immediate_operand" ""))]
1702 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1703 && !x86_64_immediate_operand (operands[1], DImode)"
1704 [(set (match_dup 2) (match_dup 1))
1705 (set (match_dup 0) (match_dup 2))])
1706
1707 ;; We need to define this as both peepholer and splitter for case
1708 ;; peephole2 pass is not run.
1709 ;; "&& 1" is needed to keep it from matching the previous pattern.
1710 (define_peephole2
1711 [(set (match_operand:DI 0 "push_operand" "")
1712 (match_operand:DI 1 "immediate_operand" ""))]
1713 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1714 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1715 [(set (match_dup 0) (match_dup 1))
1716 (set (match_dup 2) (match_dup 3))]
1717 {
1718 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1719
1720 operands[1] = gen_lowpart (DImode, operands[2]);
1721 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1722 GEN_INT (4)));
1723 })
1724
1725 (define_split
1726 [(set (match_operand:DI 0 "push_operand" "")
1727 (match_operand:DI 1 "immediate_operand" ""))]
1728 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1729 ? epilogue_completed : reload_completed)
1730 && !symbolic_operand (operands[1], DImode)
1731 && !x86_64_immediate_operand (operands[1], DImode)"
1732 [(set (match_dup 0) (match_dup 1))
1733 (set (match_dup 2) (match_dup 3))]
1734 {
1735 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1736
1737 operands[1] = gen_lowpart (DImode, operands[2]);
1738 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1739 GEN_INT (4)));
1740 })
1741
1742 (define_split
1743 [(set (match_operand:DI 0 "push_operand" "")
1744 (match_operand:DI 1 "general_operand" ""))]
1745 "!TARGET_64BIT && reload_completed
1746 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1747 [(const_int 0)]
1748 "ix86_split_long_move (operands); DONE;")
1749
1750 (define_insn "*pushsi2"
1751 [(set (match_operand:SI 0 "push_operand" "=<")
1752 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1753 "!TARGET_64BIT"
1754 "push{l}\t%1"
1755 [(set_attr "type" "push")
1756 (set_attr "mode" "SI")])
1757
1758 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1759 ;; "push a byte/word". But actually we use pushl, which has the effect
1760 ;; of rounding the amount pushed up to a word.
1761
1762 ;; For TARGET_64BIT we always round up to 8 bytes.
1763 (define_insn "*push<mode>2_rex64"
1764 [(set (match_operand:SWI124 0 "push_operand" "=X")
1765 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1766 "TARGET_64BIT"
1767 "push{q}\t%q1"
1768 [(set_attr "type" "push")
1769 (set_attr "mode" "DI")])
1770
1771 (define_insn "*push<mode>2"
1772 [(set (match_operand:SWI12 0 "push_operand" "=X")
1773 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1774 "!TARGET_64BIT"
1775 "push{l}\t%k1"
1776 [(set_attr "type" "push")
1777 (set_attr "mode" "SI")])
1778
1779 (define_insn "*push<mode>2_prologue"
1780 [(set (match_operand:P 0 "push_operand" "=<")
1781 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1782 (clobber (mem:BLK (scratch)))]
1783 ""
1784 "push{<imodesuffix>}\t%1"
1785 [(set_attr "type" "push")
1786 (set_attr "mode" "<MODE>")])
1787
1788 (define_insn "*pop<mode>1"
1789 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1790 (match_operand:P 1 "pop_operand" ">"))]
1791 ""
1792 "pop{<imodesuffix>}\t%0"
1793 [(set_attr "type" "pop")
1794 (set_attr "mode" "<MODE>")])
1795
1796 (define_insn "*pop<mode>1_epilogue"
1797 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1798 (match_operand:P 1 "pop_operand" ">"))
1799 (clobber (mem:BLK (scratch)))]
1800 ""
1801 "pop{<imodesuffix>}\t%0"
1802 [(set_attr "type" "pop")
1803 (set_attr "mode" "<MODE>")])
1804 \f
1805 ;; Move instructions.
1806
1807 (define_expand "movoi"
1808 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1809 (match_operand:OI 1 "general_operand" ""))]
1810 "TARGET_AVX"
1811 "ix86_expand_move (OImode, operands); DONE;")
1812
1813 (define_expand "movti"
1814 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1815 (match_operand:TI 1 "nonimmediate_operand" ""))]
1816 "TARGET_64BIT || TARGET_SSE"
1817 {
1818 if (TARGET_64BIT)
1819 ix86_expand_move (TImode, operands);
1820 else if (push_operand (operands[0], TImode))
1821 ix86_expand_push (TImode, operands[1]);
1822 else
1823 ix86_expand_vector_move (TImode, operands);
1824 DONE;
1825 })
1826
1827 ;; This expands to what emit_move_complex would generate if we didn't
1828 ;; have a movti pattern. Having this avoids problems with reload on
1829 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1830 ;; to have around all the time.
1831 (define_expand "movcdi"
1832 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1833 (match_operand:CDI 1 "general_operand" ""))]
1834 ""
1835 {
1836 if (push_operand (operands[0], CDImode))
1837 emit_move_complex_push (CDImode, operands[0], operands[1]);
1838 else
1839 emit_move_complex_parts (operands[0], operands[1]);
1840 DONE;
1841 })
1842
1843 (define_expand "mov<mode>"
1844 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1845 (match_operand:SWI1248x 1 "general_operand" ""))]
1846 ""
1847 "ix86_expand_move (<MODE>mode, operands); DONE;")
1848
1849 (define_insn "*mov<mode>_xor"
1850 [(set (match_operand:SWI48 0 "register_operand" "=r")
1851 (match_operand:SWI48 1 "const0_operand" ""))
1852 (clobber (reg:CC FLAGS_REG))]
1853 "reload_completed"
1854 "xor{l}\t%k0, %k0"
1855 [(set_attr "type" "alu1")
1856 (set_attr "mode" "SI")
1857 (set_attr "length_immediate" "0")])
1858
1859 (define_insn "*mov<mode>_or"
1860 [(set (match_operand:SWI48 0 "register_operand" "=r")
1861 (match_operand:SWI48 1 "const_int_operand" ""))
1862 (clobber (reg:CC FLAGS_REG))]
1863 "reload_completed
1864 && operands[1] == constm1_rtx"
1865 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1866 [(set_attr "type" "alu1")
1867 (set_attr "mode" "<MODE>")
1868 (set_attr "length_immediate" "1")])
1869
1870 (define_insn "*movoi_internal_avx"
1871 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1872 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1873 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1874 {
1875 switch (which_alternative)
1876 {
1877 case 0:
1878 return standard_sse_constant_opcode (insn, operands[1]);
1879 case 1:
1880 case 2:
1881 if (misaligned_operand (operands[0], OImode)
1882 || misaligned_operand (operands[1], OImode))
1883 return "vmovdqu\t{%1, %0|%0, %1}";
1884 else
1885 return "vmovdqa\t{%1, %0|%0, %1}";
1886 default:
1887 gcc_unreachable ();
1888 }
1889 }
1890 [(set_attr "type" "sselog1,ssemov,ssemov")
1891 (set_attr "prefix" "vex")
1892 (set_attr "mode" "OI")])
1893
1894 (define_insn "*movti_internal_rex64"
1895 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1896 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1897 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1898 {
1899 switch (which_alternative)
1900 {
1901 case 0:
1902 case 1:
1903 return "#";
1904 case 2:
1905 return standard_sse_constant_opcode (insn, operands[1]);
1906 case 3:
1907 case 4:
1908 /* TDmode values are passed as TImode on the stack. Moving them
1909 to stack may result in unaligned memory access. */
1910 if (misaligned_operand (operands[0], TImode)
1911 || misaligned_operand (operands[1], TImode))
1912 {
1913 if (get_attr_mode (insn) == MODE_V4SF)
1914 return "%vmovups\t{%1, %0|%0, %1}";
1915 else
1916 return "%vmovdqu\t{%1, %0|%0, %1}";
1917 }
1918 else
1919 {
1920 if (get_attr_mode (insn) == MODE_V4SF)
1921 return "%vmovaps\t{%1, %0|%0, %1}";
1922 else
1923 return "%vmovdqa\t{%1, %0|%0, %1}";
1924 }
1925 default:
1926 gcc_unreachable ();
1927 }
1928 }
1929 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1930 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1931 (set (attr "mode")
1932 (cond [(eq_attr "alternative" "2,3")
1933 (if_then_else
1934 (match_test "optimize_function_for_size_p (cfun)")
1935 (const_string "V4SF")
1936 (const_string "TI"))
1937 (eq_attr "alternative" "4")
1938 (if_then_else
1939 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1940 (match_test "optimize_function_for_size_p (cfun)"))
1941 (const_string "V4SF")
1942 (const_string "TI"))]
1943 (const_string "DI")))])
1944
1945 (define_split
1946 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1947 (match_operand:TI 1 "general_operand" ""))]
1948 "reload_completed
1949 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1950 [(const_int 0)]
1951 "ix86_split_long_move (operands); DONE;")
1952
1953 (define_insn "*movti_internal_sse"
1954 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1955 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1956 "TARGET_SSE && !TARGET_64BIT
1957 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1958 {
1959 switch (which_alternative)
1960 {
1961 case 0:
1962 return standard_sse_constant_opcode (insn, operands[1]);
1963 case 1:
1964 case 2:
1965 /* TDmode values are passed as TImode on the stack. Moving them
1966 to stack may result in unaligned memory access. */
1967 if (misaligned_operand (operands[0], TImode)
1968 || misaligned_operand (operands[1], TImode))
1969 {
1970 if (get_attr_mode (insn) == MODE_V4SF)
1971 return "%vmovups\t{%1, %0|%0, %1}";
1972 else
1973 return "%vmovdqu\t{%1, %0|%0, %1}";
1974 }
1975 else
1976 {
1977 if (get_attr_mode (insn) == MODE_V4SF)
1978 return "%vmovaps\t{%1, %0|%0, %1}";
1979 else
1980 return "%vmovdqa\t{%1, %0|%0, %1}";
1981 }
1982 default:
1983 gcc_unreachable ();
1984 }
1985 }
1986 [(set_attr "type" "sselog1,ssemov,ssemov")
1987 (set_attr "prefix" "maybe_vex")
1988 (set (attr "mode")
1989 (cond [(ior (not (match_test "TARGET_SSE2"))
1990 (match_test "optimize_function_for_size_p (cfun)"))
1991 (const_string "V4SF")
1992 (and (eq_attr "alternative" "2")
1993 (match_test "TARGET_SSE_TYPELESS_STORES"))
1994 (const_string "V4SF")]
1995 (const_string "TI")))])
1996
1997 (define_insn "*movdi_internal_rex64"
1998 [(set (match_operand:DI 0 "nonimmediate_operand"
1999 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
2000 (match_operand:DI 1 "general_operand"
2001 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
2002 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2003 {
2004 switch (get_attr_type (insn))
2005 {
2006 case TYPE_SSECVT:
2007 if (SSE_REG_P (operands[0]))
2008 return "movq2dq\t{%1, %0|%0, %1}";
2009 else
2010 return "movdq2q\t{%1, %0|%0, %1}";
2011
2012 case TYPE_SSEMOV:
2013 if (get_attr_mode (insn) == MODE_TI)
2014 return "%vmovdqa\t{%1, %0|%0, %1}";
2015 /* Handle broken assemblers that require movd instead of movq. */
2016 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2017 return "%vmovd\t{%1, %0|%0, %1}";
2018 else
2019 return "%vmovq\t{%1, %0|%0, %1}";
2020
2021 case TYPE_MMXMOV:
2022 /* Handle broken assemblers that require movd instead of movq. */
2023 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2024 return "movd\t{%1, %0|%0, %1}";
2025 else
2026 return "movq\t{%1, %0|%0, %1}";
2027
2028 case TYPE_SSELOG1:
2029 return standard_sse_constant_opcode (insn, operands[1]);
2030
2031 case TYPE_MMX:
2032 return "pxor\t%0, %0";
2033
2034 case TYPE_MULTI:
2035 return "#";
2036
2037 case TYPE_LEA:
2038 return "lea{q}\t{%a1, %0|%0, %a1}";
2039
2040 default:
2041 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2042 if (get_attr_mode (insn) == MODE_SI)
2043 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2044 else if (which_alternative == 2)
2045 return "movabs{q}\t{%1, %0|%0, %1}";
2046 else
2047 return "mov{q}\t{%1, %0|%0, %1}";
2048 }
2049 }
2050 [(set (attr "type")
2051 (cond [(eq_attr "alternative" "4")
2052 (const_string "multi")
2053 (eq_attr "alternative" "5")
2054 (const_string "mmx")
2055 (eq_attr "alternative" "6,7,8,9")
2056 (const_string "mmxmov")
2057 (eq_attr "alternative" "10")
2058 (const_string "sselog1")
2059 (eq_attr "alternative" "11,12,13,14,15")
2060 (const_string "ssemov")
2061 (eq_attr "alternative" "16,17")
2062 (const_string "ssecvt")
2063 (match_operand 1 "pic_32bit_operand" "")
2064 (const_string "lea")
2065 ]
2066 (const_string "imov")))
2067 (set (attr "modrm")
2068 (if_then_else
2069 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2070 (const_string "0")
2071 (const_string "*")))
2072 (set (attr "length_immediate")
2073 (if_then_else
2074 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2075 (const_string "8")
2076 (const_string "*")))
2077 (set (attr "prefix_rex")
2078 (if_then_else (eq_attr "alternative" "8,9")
2079 (const_string "1")
2080 (const_string "*")))
2081 (set (attr "prefix_data16")
2082 (if_then_else (eq_attr "alternative" "11")
2083 (const_string "1")
2084 (const_string "*")))
2085 (set (attr "prefix")
2086 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2087 (const_string "maybe_vex")
2088 (const_string "orig")))
2089 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2090
2091 ;; Reload patterns to support multi-word load/store
2092 ;; with non-offsetable address.
2093 (define_expand "reload_noff_store"
2094 [(parallel [(match_operand 0 "memory_operand" "=m")
2095 (match_operand 1 "register_operand" "r")
2096 (match_operand:DI 2 "register_operand" "=&r")])]
2097 "TARGET_64BIT"
2098 {
2099 rtx mem = operands[0];
2100 rtx addr = XEXP (mem, 0);
2101
2102 emit_move_insn (operands[2], addr);
2103 mem = replace_equiv_address_nv (mem, operands[2]);
2104
2105 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2106 DONE;
2107 })
2108
2109 (define_expand "reload_noff_load"
2110 [(parallel [(match_operand 0 "register_operand" "=r")
2111 (match_operand 1 "memory_operand" "m")
2112 (match_operand:DI 2 "register_operand" "=r")])]
2113 "TARGET_64BIT"
2114 {
2115 rtx mem = operands[1];
2116 rtx addr = XEXP (mem, 0);
2117
2118 emit_move_insn (operands[2], addr);
2119 mem = replace_equiv_address_nv (mem, operands[2]);
2120
2121 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2122 DONE;
2123 })
2124
2125 ;; Convert impossible stores of immediate to existing instructions.
2126 ;; First try to get scratch register and go through it. In case this
2127 ;; fails, move by 32bit parts.
2128 (define_peephole2
2129 [(match_scratch:DI 2 "r")
2130 (set (match_operand:DI 0 "memory_operand" "")
2131 (match_operand:DI 1 "immediate_operand" ""))]
2132 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2133 && !x86_64_immediate_operand (operands[1], DImode)"
2134 [(set (match_dup 2) (match_dup 1))
2135 (set (match_dup 0) (match_dup 2))])
2136
2137 ;; We need to define this as both peepholer and splitter for case
2138 ;; peephole2 pass is not run.
2139 ;; "&& 1" is needed to keep it from matching the previous pattern.
2140 (define_peephole2
2141 [(set (match_operand:DI 0 "memory_operand" "")
2142 (match_operand:DI 1 "immediate_operand" ""))]
2143 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2144 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2145 [(set (match_dup 2) (match_dup 3))
2146 (set (match_dup 4) (match_dup 5))]
2147 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2148
2149 (define_split
2150 [(set (match_operand:DI 0 "memory_operand" "")
2151 (match_operand:DI 1 "immediate_operand" ""))]
2152 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2153 ? epilogue_completed : reload_completed)
2154 && !symbolic_operand (operands[1], DImode)
2155 && !x86_64_immediate_operand (operands[1], DImode)"
2156 [(set (match_dup 2) (match_dup 3))
2157 (set (match_dup 4) (match_dup 5))]
2158 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2159
2160 (define_insn "*movdi_internal"
2161 [(set (match_operand:DI 0 "nonimmediate_operand"
2162 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2163 (match_operand:DI 1 "general_operand"
2164 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2165 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2166 {
2167 switch (get_attr_type (insn))
2168 {
2169 case TYPE_SSECVT:
2170 if (SSE_REG_P (operands[0]))
2171 return "movq2dq\t{%1, %0|%0, %1}";
2172 else
2173 return "movdq2q\t{%1, %0|%0, %1}";
2174
2175 case TYPE_SSEMOV:
2176 switch (get_attr_mode (insn))
2177 {
2178 case MODE_TI:
2179 return "%vmovdqa\t{%1, %0|%0, %1}";
2180 case MODE_DI:
2181 return "%vmovq\t{%1, %0|%0, %1}";
2182 case MODE_V4SF:
2183 return "movaps\t{%1, %0|%0, %1}";
2184 case MODE_V2SF:
2185 return "movlps\t{%1, %0|%0, %1}";
2186 default:
2187 gcc_unreachable ();
2188 }
2189
2190 case TYPE_MMXMOV:
2191 return "movq\t{%1, %0|%0, %1}";
2192
2193 case TYPE_SSELOG1:
2194 return standard_sse_constant_opcode (insn, operands[1]);
2195
2196 case TYPE_MMX:
2197 return "pxor\t%0, %0";
2198
2199 case TYPE_MULTI:
2200 return "#";
2201
2202 default:
2203 gcc_unreachable ();
2204 }
2205 }
2206 [(set (attr "isa")
2207 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2208 (const_string "sse2")
2209 (eq_attr "alternative" "9,10,11,12")
2210 (const_string "noavx")
2211 ]
2212 (const_string "*")))
2213 (set (attr "type")
2214 (cond [(eq_attr "alternative" "0,1")
2215 (const_string "multi")
2216 (eq_attr "alternative" "2")
2217 (const_string "mmx")
2218 (eq_attr "alternative" "3,4")
2219 (const_string "mmxmov")
2220 (eq_attr "alternative" "5,9")
2221 (const_string "sselog1")
2222 (eq_attr "alternative" "13,14")
2223 (const_string "ssecvt")
2224 ]
2225 (const_string "ssemov")))
2226 (set (attr "prefix")
2227 (if_then_else (eq_attr "alternative" "5,6,7,8")
2228 (const_string "maybe_vex")
2229 (const_string "orig")))
2230 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2231
2232 (define_split
2233 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2234 (match_operand:DI 1 "general_operand" ""))]
2235 "!TARGET_64BIT && reload_completed
2236 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2237 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2238 [(const_int 0)]
2239 "ix86_split_long_move (operands); DONE;")
2240
2241 (define_insn "*movsi_internal"
2242 [(set (match_operand:SI 0 "nonimmediate_operand"
2243 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2244 (match_operand:SI 1 "general_operand"
2245 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2246 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2247 {
2248 switch (get_attr_type (insn))
2249 {
2250 case TYPE_SSELOG1:
2251 return standard_sse_constant_opcode (insn, operands[1]);
2252
2253 case TYPE_SSEMOV:
2254 switch (get_attr_mode (insn))
2255 {
2256 case MODE_TI:
2257 return "%vmovdqa\t{%1, %0|%0, %1}";
2258 case MODE_V4SF:
2259 return "%vmovaps\t{%1, %0|%0, %1}";
2260 case MODE_SI:
2261 return "%vmovd\t{%1, %0|%0, %1}";
2262 case MODE_SF:
2263 return "%vmovss\t{%1, %0|%0, %1}";
2264 default:
2265 gcc_unreachable ();
2266 }
2267
2268 case TYPE_MMX:
2269 return "pxor\t%0, %0";
2270
2271 case TYPE_MMXMOV:
2272 if (get_attr_mode (insn) == MODE_DI)
2273 return "movq\t{%1, %0|%0, %1}";
2274 return "movd\t{%1, %0|%0, %1}";
2275
2276 case TYPE_LEA:
2277 return "lea{l}\t{%a1, %0|%0, %a1}";
2278
2279 default:
2280 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2281 return "mov{l}\t{%1, %0|%0, %1}";
2282 }
2283 }
2284 [(set (attr "type")
2285 (cond [(eq_attr "alternative" "2")
2286 (const_string "mmx")
2287 (eq_attr "alternative" "3,4,5")
2288 (const_string "mmxmov")
2289 (eq_attr "alternative" "6")
2290 (const_string "sselog1")
2291 (eq_attr "alternative" "7,8,9,10,11")
2292 (const_string "ssemov")
2293 (match_operand 1 "pic_32bit_operand" "")
2294 (const_string "lea")
2295 ]
2296 (const_string "imov")))
2297 (set (attr "prefix")
2298 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2299 (const_string "orig")
2300 (const_string "maybe_vex")))
2301 (set (attr "prefix_data16")
2302 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2303 (const_string "1")
2304 (const_string "*")))
2305 (set (attr "mode")
2306 (cond [(eq_attr "alternative" "2,3")
2307 (const_string "DI")
2308 (eq_attr "alternative" "6,7")
2309 (if_then_else
2310 (not (match_test "TARGET_SSE2"))
2311 (const_string "V4SF")
2312 (const_string "TI"))
2313 (and (eq_attr "alternative" "8,9,10,11")
2314 (not (match_test "TARGET_SSE2")))
2315 (const_string "SF")
2316 ]
2317 (const_string "SI")))])
2318
2319 (define_insn "*movhi_internal"
2320 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2321 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2322 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2323 {
2324 switch (get_attr_type (insn))
2325 {
2326 case TYPE_IMOVX:
2327 /* movzwl is faster than movw on p2 due to partial word stalls,
2328 though not as fast as an aligned movl. */
2329 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2330 default:
2331 if (get_attr_mode (insn) == MODE_SI)
2332 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2333 else
2334 return "mov{w}\t{%1, %0|%0, %1}";
2335 }
2336 }
2337 [(set (attr "type")
2338 (cond [(match_test "optimize_function_for_size_p (cfun)")
2339 (const_string "imov")
2340 (and (eq_attr "alternative" "0")
2341 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2342 (not (match_test "TARGET_HIMODE_MATH"))))
2343 (const_string "imov")
2344 (and (eq_attr "alternative" "1,2")
2345 (match_operand:HI 1 "aligned_operand" ""))
2346 (const_string "imov")
2347 (and (match_test "TARGET_MOVX")
2348 (eq_attr "alternative" "0,2"))
2349 (const_string "imovx")
2350 ]
2351 (const_string "imov")))
2352 (set (attr "mode")
2353 (cond [(eq_attr "type" "imovx")
2354 (const_string "SI")
2355 (and (eq_attr "alternative" "1,2")
2356 (match_operand:HI 1 "aligned_operand" ""))
2357 (const_string "SI")
2358 (and (eq_attr "alternative" "0")
2359 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2360 (not (match_test "TARGET_HIMODE_MATH"))))
2361 (const_string "SI")
2362 ]
2363 (const_string "HI")))])
2364
2365 ;; Situation is quite tricky about when to choose full sized (SImode) move
2366 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2367 ;; partial register dependency machines (such as AMD Athlon), where QImode
2368 ;; moves issue extra dependency and for partial register stalls machines
2369 ;; that don't use QImode patterns (and QImode move cause stall on the next
2370 ;; instruction).
2371 ;;
2372 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2373 ;; register stall machines with, where we use QImode instructions, since
2374 ;; partial register stall can be caused there. Then we use movzx.
2375 (define_insn "*movqi_internal"
2376 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2377 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2378 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2379 {
2380 switch (get_attr_type (insn))
2381 {
2382 case TYPE_IMOVX:
2383 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2384 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2385 default:
2386 if (get_attr_mode (insn) == MODE_SI)
2387 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2388 else
2389 return "mov{b}\t{%1, %0|%0, %1}";
2390 }
2391 }
2392 [(set (attr "type")
2393 (cond [(and (eq_attr "alternative" "5")
2394 (not (match_operand:QI 1 "aligned_operand" "")))
2395 (const_string "imovx")
2396 (match_test "optimize_function_for_size_p (cfun)")
2397 (const_string "imov")
2398 (and (eq_attr "alternative" "3")
2399 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2400 (not (match_test "TARGET_QIMODE_MATH"))))
2401 (const_string "imov")
2402 (eq_attr "alternative" "3,5")
2403 (const_string "imovx")
2404 (and (match_test "TARGET_MOVX")
2405 (eq_attr "alternative" "2"))
2406 (const_string "imovx")
2407 ]
2408 (const_string "imov")))
2409 (set (attr "mode")
2410 (cond [(eq_attr "alternative" "3,4,5")
2411 (const_string "SI")
2412 (eq_attr "alternative" "6")
2413 (const_string "QI")
2414 (eq_attr "type" "imovx")
2415 (const_string "SI")
2416 (and (eq_attr "type" "imov")
2417 (and (eq_attr "alternative" "0,1")
2418 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2419 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2420 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2421 (const_string "SI")
2422 ;; Avoid partial register stalls when not using QImode arithmetic
2423 (and (eq_attr "type" "imov")
2424 (and (eq_attr "alternative" "0,1")
2425 (and (match_test "TARGET_PARTIAL_REG_STALL")
2426 (not (match_test "TARGET_QIMODE_MATH")))))
2427 (const_string "SI")
2428 ]
2429 (const_string "QI")))])
2430
2431 ;; Stores and loads of ax to arbitrary constant address.
2432 ;; We fake an second form of instruction to force reload to load address
2433 ;; into register when rax is not available
2434 (define_insn "*movabs<mode>_1"
2435 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2436 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2437 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2438 "@
2439 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2440 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2441 [(set_attr "type" "imov")
2442 (set_attr "modrm" "0,*")
2443 (set_attr "length_address" "8,0")
2444 (set_attr "length_immediate" "0,*")
2445 (set_attr "memory" "store")
2446 (set_attr "mode" "<MODE>")])
2447
2448 (define_insn "*movabs<mode>_2"
2449 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2450 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2451 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2452 "@
2453 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2454 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2455 [(set_attr "type" "imov")
2456 (set_attr "modrm" "0,*")
2457 (set_attr "length_address" "8,0")
2458 (set_attr "length_immediate" "0")
2459 (set_attr "memory" "load")
2460 (set_attr "mode" "<MODE>")])
2461
2462 (define_insn "*swap<mode>"
2463 [(set (match_operand:SWI48 0 "register_operand" "+r")
2464 (match_operand:SWI48 1 "register_operand" "+r"))
2465 (set (match_dup 1)
2466 (match_dup 0))]
2467 ""
2468 "xchg{<imodesuffix>}\t%1, %0"
2469 [(set_attr "type" "imov")
2470 (set_attr "mode" "<MODE>")
2471 (set_attr "pent_pair" "np")
2472 (set_attr "athlon_decode" "vector")
2473 (set_attr "amdfam10_decode" "double")
2474 (set_attr "bdver1_decode" "double")])
2475
2476 (define_insn "*swap<mode>_1"
2477 [(set (match_operand:SWI12 0 "register_operand" "+r")
2478 (match_operand:SWI12 1 "register_operand" "+r"))
2479 (set (match_dup 1)
2480 (match_dup 0))]
2481 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2482 "xchg{l}\t%k1, %k0"
2483 [(set_attr "type" "imov")
2484 (set_attr "mode" "SI")
2485 (set_attr "pent_pair" "np")
2486 (set_attr "athlon_decode" "vector")
2487 (set_attr "amdfam10_decode" "double")
2488 (set_attr "bdver1_decode" "double")])
2489
2490 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2491 ;; is disabled for AMDFAM10
2492 (define_insn "*swap<mode>_2"
2493 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2494 (match_operand:SWI12 1 "register_operand" "+<r>"))
2495 (set (match_dup 1)
2496 (match_dup 0))]
2497 "TARGET_PARTIAL_REG_STALL"
2498 "xchg{<imodesuffix>}\t%1, %0"
2499 [(set_attr "type" "imov")
2500 (set_attr "mode" "<MODE>")
2501 (set_attr "pent_pair" "np")
2502 (set_attr "athlon_decode" "vector")])
2503
2504 (define_expand "movstrict<mode>"
2505 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2506 (match_operand:SWI12 1 "general_operand" ""))]
2507 ""
2508 {
2509 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2510 FAIL;
2511 if (GET_CODE (operands[0]) == SUBREG
2512 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2513 FAIL;
2514 /* Don't generate memory->memory moves, go through a register */
2515 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2516 operands[1] = force_reg (<MODE>mode, operands[1]);
2517 })
2518
2519 (define_insn "*movstrict<mode>_1"
2520 [(set (strict_low_part
2521 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2522 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2523 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2524 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2525 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2526 [(set_attr "type" "imov")
2527 (set_attr "mode" "<MODE>")])
2528
2529 (define_insn "*movstrict<mode>_xor"
2530 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2531 (match_operand:SWI12 1 "const0_operand" ""))
2532 (clobber (reg:CC FLAGS_REG))]
2533 "reload_completed"
2534 "xor{<imodesuffix>}\t%0, %0"
2535 [(set_attr "type" "alu1")
2536 (set_attr "mode" "<MODE>")
2537 (set_attr "length_immediate" "0")])
2538
2539 (define_insn "*mov<mode>_extv_1"
2540 [(set (match_operand:SWI24 0 "register_operand" "=R")
2541 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2542 (const_int 8)
2543 (const_int 8)))]
2544 ""
2545 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2546 [(set_attr "type" "imovx")
2547 (set_attr "mode" "SI")])
2548
2549 (define_insn "*movqi_extv_1_rex64"
2550 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2551 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2552 (const_int 8)
2553 (const_int 8)))]
2554 "TARGET_64BIT"
2555 {
2556 switch (get_attr_type (insn))
2557 {
2558 case TYPE_IMOVX:
2559 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2560 default:
2561 return "mov{b}\t{%h1, %0|%0, %h1}";
2562 }
2563 }
2564 [(set (attr "type")
2565 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2566 (match_test "TARGET_MOVX"))
2567 (const_string "imovx")
2568 (const_string "imov")))
2569 (set (attr "mode")
2570 (if_then_else (eq_attr "type" "imovx")
2571 (const_string "SI")
2572 (const_string "QI")))])
2573
2574 (define_insn "*movqi_extv_1"
2575 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2576 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2577 (const_int 8)
2578 (const_int 8)))]
2579 "!TARGET_64BIT"
2580 {
2581 switch (get_attr_type (insn))
2582 {
2583 case TYPE_IMOVX:
2584 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2585 default:
2586 return "mov{b}\t{%h1, %0|%0, %h1}";
2587 }
2588 }
2589 [(set (attr "type")
2590 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2591 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2592 (match_test "TARGET_MOVX")))
2593 (const_string "imovx")
2594 (const_string "imov")))
2595 (set (attr "mode")
2596 (if_then_else (eq_attr "type" "imovx")
2597 (const_string "SI")
2598 (const_string "QI")))])
2599
2600 (define_insn "*mov<mode>_extzv_1"
2601 [(set (match_operand:SWI48 0 "register_operand" "=R")
2602 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2603 (const_int 8)
2604 (const_int 8)))]
2605 ""
2606 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2607 [(set_attr "type" "imovx")
2608 (set_attr "mode" "SI")])
2609
2610 (define_insn "*movqi_extzv_2_rex64"
2611 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2612 (subreg:QI
2613 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2614 (const_int 8)
2615 (const_int 8)) 0))]
2616 "TARGET_64BIT"
2617 {
2618 switch (get_attr_type (insn))
2619 {
2620 case TYPE_IMOVX:
2621 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2622 default:
2623 return "mov{b}\t{%h1, %0|%0, %h1}";
2624 }
2625 }
2626 [(set (attr "type")
2627 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2628 (match_test "TARGET_MOVX"))
2629 (const_string "imovx")
2630 (const_string "imov")))
2631 (set (attr "mode")
2632 (if_then_else (eq_attr "type" "imovx")
2633 (const_string "SI")
2634 (const_string "QI")))])
2635
2636 (define_insn "*movqi_extzv_2"
2637 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2638 (subreg:QI
2639 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2640 (const_int 8)
2641 (const_int 8)) 0))]
2642 "!TARGET_64BIT"
2643 {
2644 switch (get_attr_type (insn))
2645 {
2646 case TYPE_IMOVX:
2647 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2648 default:
2649 return "mov{b}\t{%h1, %0|%0, %h1}";
2650 }
2651 }
2652 [(set (attr "type")
2653 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2654 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2655 (match_test "TARGET_MOVX")))
2656 (const_string "imovx")
2657 (const_string "imov")))
2658 (set (attr "mode")
2659 (if_then_else (eq_attr "type" "imovx")
2660 (const_string "SI")
2661 (const_string "QI")))])
2662
2663 (define_expand "mov<mode>_insv_1"
2664 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2665 (const_int 8)
2666 (const_int 8))
2667 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2668
2669 (define_insn "*mov<mode>_insv_1_rex64"
2670 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2671 (const_int 8)
2672 (const_int 8))
2673 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2674 "TARGET_64BIT"
2675 "mov{b}\t{%b1, %h0|%h0, %b1}"
2676 [(set_attr "type" "imov")
2677 (set_attr "mode" "QI")])
2678
2679 (define_insn "*movsi_insv_1"
2680 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2681 (const_int 8)
2682 (const_int 8))
2683 (match_operand:SI 1 "general_operand" "Qmn"))]
2684 "!TARGET_64BIT"
2685 "mov{b}\t{%b1, %h0|%h0, %b1}"
2686 [(set_attr "type" "imov")
2687 (set_attr "mode" "QI")])
2688
2689 (define_insn "*movqi_insv_2"
2690 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2691 (const_int 8)
2692 (const_int 8))
2693 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2694 (const_int 8)))]
2695 ""
2696 "mov{b}\t{%h1, %h0|%h0, %h1}"
2697 [(set_attr "type" "imov")
2698 (set_attr "mode" "QI")])
2699 \f
2700 ;; Floating point push instructions.
2701
2702 (define_insn "*pushtf"
2703 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2704 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2705 "TARGET_SSE2"
2706 {
2707 /* This insn should be already split before reg-stack. */
2708 gcc_unreachable ();
2709 }
2710 [(set_attr "type" "multi")
2711 (set_attr "unit" "sse,*,*")
2712 (set_attr "mode" "TF,SI,SI")])
2713
2714 ;; %%% Kill this when call knows how to work this out.
2715 (define_split
2716 [(set (match_operand:TF 0 "push_operand" "")
2717 (match_operand:TF 1 "sse_reg_operand" ""))]
2718 "TARGET_SSE2 && reload_completed"
2719 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2720 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2721
2722 (define_insn "*pushxf"
2723 [(set (match_operand:XF 0 "push_operand" "=<,<")
2724 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2725 "optimize_function_for_speed_p (cfun)"
2726 {
2727 /* This insn should be already split before reg-stack. */
2728 gcc_unreachable ();
2729 }
2730 [(set_attr "type" "multi")
2731 (set_attr "unit" "i387,*")
2732 (set_attr "mode" "XF,SI")])
2733
2734 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2735 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2736 ;; Pushing using integer instructions is longer except for constants
2737 ;; and direct memory references (assuming that any given constant is pushed
2738 ;; only once, but this ought to be handled elsewhere).
2739
2740 (define_insn "*pushxf_nointeger"
2741 [(set (match_operand:XF 0 "push_operand" "=<,<")
2742 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2743 "optimize_function_for_size_p (cfun)"
2744 {
2745 /* This insn should be already split before reg-stack. */
2746 gcc_unreachable ();
2747 }
2748 [(set_attr "type" "multi")
2749 (set_attr "unit" "i387,*")
2750 (set_attr "mode" "XF,SI")])
2751
2752 ;; %%% Kill this when call knows how to work this out.
2753 (define_split
2754 [(set (match_operand:XF 0 "push_operand" "")
2755 (match_operand:XF 1 "fp_register_operand" ""))]
2756 "reload_completed"
2757 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2758 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2759 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2760
2761 (define_insn "*pushdf_rex64"
2762 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2763 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2764 "TARGET_64BIT"
2765 {
2766 /* This insn should be already split before reg-stack. */
2767 gcc_unreachable ();
2768 }
2769 [(set_attr "type" "multi")
2770 (set_attr "unit" "i387,*,*")
2771 (set_attr "mode" "DF,DI,DF")])
2772
2773 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2774 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2775 ;; On the average, pushdf using integers can be still shorter.
2776
2777 (define_insn "*pushdf"
2778 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2779 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2780 "!TARGET_64BIT"
2781 {
2782 /* This insn should be already split before reg-stack. */
2783 gcc_unreachable ();
2784 }
2785 [(set_attr "isa" "*,*,sse2")
2786 (set_attr "type" "multi")
2787 (set_attr "unit" "i387,*,*")
2788 (set_attr "mode" "DF,DI,DF")])
2789
2790 ;; %%% Kill this when call knows how to work this out.
2791 (define_split
2792 [(set (match_operand:DF 0 "push_operand" "")
2793 (match_operand:DF 1 "any_fp_register_operand" ""))]
2794 "reload_completed"
2795 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2796 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2797
2798 (define_insn "*pushsf_rex64"
2799 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2800 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2801 "TARGET_64BIT"
2802 {
2803 /* Anything else should be already split before reg-stack. */
2804 gcc_assert (which_alternative == 1);
2805 return "push{q}\t%q1";
2806 }
2807 [(set_attr "type" "multi,push,multi")
2808 (set_attr "unit" "i387,*,*")
2809 (set_attr "mode" "SF,DI,SF")])
2810
2811 (define_insn "*pushsf"
2812 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2813 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2814 "!TARGET_64BIT"
2815 {
2816 /* Anything else should be already split before reg-stack. */
2817 gcc_assert (which_alternative == 1);
2818 return "push{l}\t%1";
2819 }
2820 [(set_attr "type" "multi,push,multi")
2821 (set_attr "unit" "i387,*,*")
2822 (set_attr "mode" "SF,SI,SF")])
2823
2824 ;; %%% Kill this when call knows how to work this out.
2825 (define_split
2826 [(set (match_operand:SF 0 "push_operand" "")
2827 (match_operand:SF 1 "any_fp_register_operand" ""))]
2828 "reload_completed"
2829 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2830 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2831 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2832
2833 (define_split
2834 [(set (match_operand:SF 0 "push_operand" "")
2835 (match_operand:SF 1 "memory_operand" ""))]
2836 "reload_completed
2837 && (operands[2] = find_constant_src (insn))"
2838 [(set (match_dup 0) (match_dup 2))])
2839
2840 (define_split
2841 [(set (match_operand 0 "push_operand" "")
2842 (match_operand 1 "general_operand" ""))]
2843 "reload_completed
2844 && (GET_MODE (operands[0]) == TFmode
2845 || GET_MODE (operands[0]) == XFmode
2846 || GET_MODE (operands[0]) == DFmode)
2847 && !ANY_FP_REG_P (operands[1])"
2848 [(const_int 0)]
2849 "ix86_split_long_move (operands); DONE;")
2850 \f
2851 ;; Floating point move instructions.
2852
2853 (define_expand "movtf"
2854 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2855 (match_operand:TF 1 "nonimmediate_operand" ""))]
2856 "TARGET_SSE2"
2857 {
2858 ix86_expand_move (TFmode, operands);
2859 DONE;
2860 })
2861
2862 (define_expand "mov<mode>"
2863 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2864 (match_operand:X87MODEF 1 "general_operand" ""))]
2865 ""
2866 "ix86_expand_move (<MODE>mode, operands); DONE;")
2867
2868 (define_insn "*movtf_internal"
2869 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2870 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2871 "TARGET_SSE2
2872 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2873 && (!can_create_pseudo_p ()
2874 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2875 || GET_CODE (operands[1]) != CONST_DOUBLE
2876 || (optimize_function_for_size_p (cfun)
2877 && standard_sse_constant_p (operands[1])
2878 && !memory_operand (operands[0], TFmode))
2879 || (!TARGET_MEMORY_MISMATCH_STALL
2880 && memory_operand (operands[0], TFmode)))"
2881 {
2882 switch (which_alternative)
2883 {
2884 case 0:
2885 case 1:
2886 /* Handle misaligned load/store since we
2887 don't have movmisaligntf pattern. */
2888 if (misaligned_operand (operands[0], TFmode)
2889 || misaligned_operand (operands[1], TFmode))
2890 {
2891 if (get_attr_mode (insn) == MODE_V4SF)
2892 return "%vmovups\t{%1, %0|%0, %1}";
2893 else
2894 return "%vmovdqu\t{%1, %0|%0, %1}";
2895 }
2896 else
2897 {
2898 if (get_attr_mode (insn) == MODE_V4SF)
2899 return "%vmovaps\t{%1, %0|%0, %1}";
2900 else
2901 return "%vmovdqa\t{%1, %0|%0, %1}";
2902 }
2903
2904 case 2:
2905 return standard_sse_constant_opcode (insn, operands[1]);
2906
2907 case 3:
2908 case 4:
2909 return "#";
2910
2911 default:
2912 gcc_unreachable ();
2913 }
2914 }
2915 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2916 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2917 (set (attr "mode")
2918 (cond [(eq_attr "alternative" "0,2")
2919 (if_then_else
2920 (match_test "optimize_function_for_size_p (cfun)")
2921 (const_string "V4SF")
2922 (const_string "TI"))
2923 (eq_attr "alternative" "1")
2924 (if_then_else
2925 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2926 (match_test "optimize_function_for_size_p (cfun)"))
2927 (const_string "V4SF")
2928 (const_string "TI"))]
2929 (const_string "DI")))])
2930
2931 ;; Possible store forwarding (partial memory) stall in alternative 4.
2932 (define_insn "*movxf_internal"
2933 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2934 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2935 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2936 && (!can_create_pseudo_p ()
2937 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2938 || GET_CODE (operands[1]) != CONST_DOUBLE
2939 || (optimize_function_for_size_p (cfun)
2940 && standard_80387_constant_p (operands[1]) > 0
2941 && !memory_operand (operands[0], XFmode))
2942 || (!TARGET_MEMORY_MISMATCH_STALL
2943 && memory_operand (operands[0], XFmode)))"
2944 {
2945 switch (which_alternative)
2946 {
2947 case 0:
2948 case 1:
2949 return output_387_reg_move (insn, operands);
2950
2951 case 2:
2952 return standard_80387_constant_opcode (operands[1]);
2953
2954 case 3:
2955 case 4:
2956 return "#";
2957
2958 default:
2959 gcc_unreachable ();
2960 }
2961 }
2962 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2963 (set_attr "mode" "XF,XF,XF,SI,SI")])
2964
2965 (define_insn "*movdf_internal_rex64"
2966 [(set (match_operand:DF 0 "nonimmediate_operand"
2967 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2968 (match_operand:DF 1 "general_operand"
2969 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2970 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2971 && (!can_create_pseudo_p ()
2972 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2973 || GET_CODE (operands[1]) != CONST_DOUBLE
2974 || (optimize_function_for_size_p (cfun)
2975 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2976 && standard_80387_constant_p (operands[1]) > 0)
2977 || (TARGET_SSE2 && TARGET_SSE_MATH
2978 && standard_sse_constant_p (operands[1]))))
2979 || memory_operand (operands[0], DFmode))"
2980 {
2981 switch (which_alternative)
2982 {
2983 case 0:
2984 case 1:
2985 return output_387_reg_move (insn, operands);
2986
2987 case 2:
2988 return standard_80387_constant_opcode (operands[1]);
2989
2990 case 3:
2991 case 4:
2992 return "mov{q}\t{%1, %0|%0, %1}";
2993
2994 case 5:
2995 return "movabs{q}\t{%1, %0|%0, %1}";
2996
2997 case 6:
2998 return "#";
2999
3000 case 7:
3001 return standard_sse_constant_opcode (insn, operands[1]);
3002
3003 case 8:
3004 case 9:
3005 case 10:
3006 switch (get_attr_mode (insn))
3007 {
3008 case MODE_V2DF:
3009 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3010 return "%vmovapd\t{%1, %0|%0, %1}";
3011 case MODE_V4SF:
3012 return "%vmovaps\t{%1, %0|%0, %1}";
3013
3014 case MODE_DI:
3015 return "%vmovq\t{%1, %0|%0, %1}";
3016 case MODE_DF:
3017 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3018 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3019 return "%vmovsd\t{%1, %0|%0, %1}";
3020 case MODE_V1DF:
3021 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3022 case MODE_V2SF:
3023 return "%vmovlps\t{%1, %d0|%d0, %1}";
3024 default:
3025 gcc_unreachable ();
3026 }
3027
3028 case 11:
3029 case 12:
3030 /* Handle broken assemblers that require movd instead of movq. */
3031 return "%vmovd\t{%1, %0|%0, %1}";
3032
3033 default:
3034 gcc_unreachable();
3035 }
3036 }
3037 [(set (attr "type")
3038 (cond [(eq_attr "alternative" "0,1,2")
3039 (const_string "fmov")
3040 (eq_attr "alternative" "3,4,5")
3041 (const_string "imov")
3042 (eq_attr "alternative" "6")
3043 (const_string "multi")
3044 (eq_attr "alternative" "7")
3045 (const_string "sselog1")
3046 ]
3047 (const_string "ssemov")))
3048 (set (attr "modrm")
3049 (if_then_else
3050 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3051 (const_string "0")
3052 (const_string "*")))
3053 (set (attr "length_immediate")
3054 (if_then_else
3055 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3056 (const_string "8")
3057 (const_string "*")))
3058 (set (attr "prefix")
3059 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3060 (const_string "orig")
3061 (const_string "maybe_vex")))
3062 (set (attr "prefix_data16")
3063 (if_then_else (eq_attr "mode" "V1DF")
3064 (const_string "1")
3065 (const_string "*")))
3066 (set (attr "mode")
3067 (cond [(eq_attr "alternative" "0,1,2")
3068 (const_string "DF")
3069 (eq_attr "alternative" "3,4,5,6,11,12")
3070 (const_string "DI")
3071
3072 /* xorps is one byte shorter. */
3073 (eq_attr "alternative" "7")
3074 (cond [(match_test "optimize_function_for_size_p (cfun)")
3075 (const_string "V4SF")
3076 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3077 (const_string "TI")
3078 ]
3079 (const_string "V2DF"))
3080
3081 /* For architectures resolving dependencies on
3082 whole SSE registers use APD move to break dependency
3083 chains, otherwise use short move to avoid extra work.
3084
3085 movaps encodes one byte shorter. */
3086 (eq_attr "alternative" "8")
3087 (cond
3088 [(match_test "optimize_function_for_size_p (cfun)")
3089 (const_string "V4SF")
3090 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3091 (const_string "V2DF")
3092 ]
3093 (const_string "DF"))
3094 /* For architectures resolving dependencies on register
3095 parts we may avoid extra work to zero out upper part
3096 of register. */
3097 (eq_attr "alternative" "9")
3098 (if_then_else
3099 (match_test "TARGET_SSE_SPLIT_REGS")
3100 (const_string "V1DF")
3101 (const_string "DF"))
3102 ]
3103 (const_string "DF")))])
3104
3105 ;; Possible store forwarding (partial memory) stall in alternative 4.
3106 (define_insn "*movdf_internal"
3107 [(set (match_operand:DF 0 "nonimmediate_operand"
3108 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3109 (match_operand:DF 1 "general_operand"
3110 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3111 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3112 && (!can_create_pseudo_p ()
3113 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3114 || GET_CODE (operands[1]) != CONST_DOUBLE
3115 || (optimize_function_for_size_p (cfun)
3116 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3117 && standard_80387_constant_p (operands[1]) > 0)
3118 || (TARGET_SSE2 && TARGET_SSE_MATH
3119 && standard_sse_constant_p (operands[1])))
3120 && !memory_operand (operands[0], DFmode))
3121 || (!TARGET_MEMORY_MISMATCH_STALL
3122 && memory_operand (operands[0], DFmode)))"
3123 {
3124 switch (which_alternative)
3125 {
3126 case 0:
3127 case 1:
3128 return output_387_reg_move (insn, operands);
3129
3130 case 2:
3131 return standard_80387_constant_opcode (operands[1]);
3132
3133 case 3:
3134 case 4:
3135 return "#";
3136
3137 case 5:
3138 case 9:
3139 return standard_sse_constant_opcode (insn, operands[1]);
3140
3141 case 6:
3142 case 7:
3143 case 8:
3144 case 10:
3145 case 11:
3146 case 12:
3147 switch (get_attr_mode (insn))
3148 {
3149 case MODE_V2DF:
3150 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3151 return "%vmovapd\t{%1, %0|%0, %1}";
3152 case MODE_V4SF:
3153 return "%vmovaps\t{%1, %0|%0, %1}";
3154
3155 case MODE_DI:
3156 return "%vmovq\t{%1, %0|%0, %1}";
3157 case MODE_DF:
3158 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3159 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3160 return "%vmovsd\t{%1, %0|%0, %1}";
3161 case MODE_V1DF:
3162 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3163 case MODE_V2SF:
3164 return "%vmovlps\t{%1, %d0|%d0, %1}";
3165 default:
3166 gcc_unreachable ();
3167 }
3168
3169 default:
3170 gcc_unreachable ();
3171 }
3172 }
3173 [(set (attr "isa")
3174 (if_then_else (eq_attr "alternative" "5,6,7,8")
3175 (const_string "sse2")
3176 (const_string "*")))
3177 (set (attr "type")
3178 (cond [(eq_attr "alternative" "0,1,2")
3179 (const_string "fmov")
3180 (eq_attr "alternative" "3,4")
3181 (const_string "multi")
3182 (eq_attr "alternative" "5,9")
3183 (const_string "sselog1")
3184 ]
3185 (const_string "ssemov")))
3186 (set (attr "prefix")
3187 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3188 (const_string "orig")
3189 (const_string "maybe_vex")))
3190 (set (attr "prefix_data16")
3191 (if_then_else (eq_attr "mode" "V1DF")
3192 (const_string "1")
3193 (const_string "*")))
3194 (set (attr "mode")
3195 (cond [(eq_attr "alternative" "0,1,2")
3196 (const_string "DF")
3197 (eq_attr "alternative" "3,4")
3198 (const_string "SI")
3199
3200 /* For SSE1, we have many fewer alternatives. */
3201 (not (match_test "TARGET_SSE2"))
3202 (if_then_else
3203 (eq_attr "alternative" "5,6,9,10")
3204 (const_string "V4SF")
3205 (const_string "V2SF"))
3206
3207 /* xorps is one byte shorter. */
3208 (eq_attr "alternative" "5,9")
3209 (cond [(match_test "optimize_function_for_size_p (cfun)")
3210 (const_string "V4SF")
3211 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3212 (const_string "TI")
3213 ]
3214 (const_string "V2DF"))
3215
3216 /* For architectures resolving dependencies on
3217 whole SSE registers use APD move to break dependency
3218 chains, otherwise use short move to avoid extra work.
3219
3220 movaps encodes one byte shorter. */
3221 (eq_attr "alternative" "6,10")
3222 (cond
3223 [(match_test "optimize_function_for_size_p (cfun)")
3224 (const_string "V4SF")
3225 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3226 (const_string "V2DF")
3227 ]
3228 (const_string "DF"))
3229 /* For architectures resolving dependencies on register
3230 parts we may avoid extra work to zero out upper part
3231 of register. */
3232 (eq_attr "alternative" "7,11")
3233 (if_then_else
3234 (match_test "TARGET_SSE_SPLIT_REGS")
3235 (const_string "V1DF")
3236 (const_string "DF"))
3237 ]
3238 (const_string "DF")))])
3239
3240 (define_insn "*movsf_internal"
3241 [(set (match_operand:SF 0 "nonimmediate_operand"
3242 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3243 (match_operand:SF 1 "general_operand"
3244 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3245 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3246 && (!can_create_pseudo_p ()
3247 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3248 || GET_CODE (operands[1]) != CONST_DOUBLE
3249 || (optimize_function_for_size_p (cfun)
3250 && ((!TARGET_SSE_MATH
3251 && standard_80387_constant_p (operands[1]) > 0)
3252 || (TARGET_SSE_MATH
3253 && standard_sse_constant_p (operands[1]))))
3254 || memory_operand (operands[0], SFmode))"
3255 {
3256 switch (which_alternative)
3257 {
3258 case 0:
3259 case 1:
3260 return output_387_reg_move (insn, operands);
3261
3262 case 2:
3263 return standard_80387_constant_opcode (operands[1]);
3264
3265 case 3:
3266 case 4:
3267 return "mov{l}\t{%1, %0|%0, %1}";
3268
3269 case 5:
3270 return standard_sse_constant_opcode (insn, operands[1]);
3271
3272 case 6:
3273 if (get_attr_mode (insn) == MODE_V4SF)
3274 return "%vmovaps\t{%1, %0|%0, %1}";
3275 if (TARGET_AVX)
3276 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3277
3278 case 7:
3279 case 8:
3280 return "%vmovss\t{%1, %0|%0, %1}";
3281
3282 case 9:
3283 case 10:
3284 case 14:
3285 case 15:
3286 return "movd\t{%1, %0|%0, %1}";
3287
3288 case 11:
3289 return "movq\t{%1, %0|%0, %1}";
3290
3291 case 12:
3292 case 13:
3293 return "%vmovd\t{%1, %0|%0, %1}";
3294
3295 default:
3296 gcc_unreachable ();
3297 }
3298 }
3299 [(set (attr "type")
3300 (cond [(eq_attr "alternative" "0,1,2")
3301 (const_string "fmov")
3302 (eq_attr "alternative" "3,4")
3303 (const_string "multi")
3304 (eq_attr "alternative" "5")
3305 (const_string "sselog1")
3306 (eq_attr "alternative" "9,10,11,14,15")
3307 (const_string "mmxmov")
3308 ]
3309 (const_string "ssemov")))
3310 (set (attr "prefix")
3311 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3312 (const_string "maybe_vex")
3313 (const_string "orig")))
3314 (set (attr "mode")
3315 (cond [(eq_attr "alternative" "3,4,9,10")
3316 (const_string "SI")
3317 (eq_attr "alternative" "5")
3318 (if_then_else
3319 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3320 (match_test "TARGET_SSE2"))
3321 (not (match_test "optimize_function_for_size_p (cfun)")))
3322 (const_string "TI")
3323 (const_string "V4SF"))
3324 /* For architectures resolving dependencies on
3325 whole SSE registers use APS move to break dependency
3326 chains, otherwise use short move to avoid extra work.
3327
3328 Do the same for architectures resolving dependencies on
3329 the parts. While in DF mode it is better to always handle
3330 just register parts, the SF mode is different due to lack
3331 of instructions to load just part of the register. It is
3332 better to maintain the whole registers in single format
3333 to avoid problems on using packed logical operations. */
3334 (eq_attr "alternative" "6")
3335 (if_then_else
3336 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3337 (match_test "TARGET_SSE_SPLIT_REGS"))
3338 (const_string "V4SF")
3339 (const_string "SF"))
3340 (eq_attr "alternative" "11")
3341 (const_string "DI")]
3342 (const_string "SF")))])
3343
3344 (define_split
3345 [(set (match_operand 0 "any_fp_register_operand" "")
3346 (match_operand 1 "memory_operand" ""))]
3347 "reload_completed
3348 && (GET_MODE (operands[0]) == TFmode
3349 || GET_MODE (operands[0]) == XFmode
3350 || GET_MODE (operands[0]) == DFmode
3351 || GET_MODE (operands[0]) == SFmode)
3352 && (operands[2] = find_constant_src (insn))"
3353 [(set (match_dup 0) (match_dup 2))]
3354 {
3355 rtx c = operands[2];
3356 int r = REGNO (operands[0]);
3357
3358 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3359 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3360 FAIL;
3361 })
3362
3363 (define_split
3364 [(set (match_operand 0 "any_fp_register_operand" "")
3365 (float_extend (match_operand 1 "memory_operand" "")))]
3366 "reload_completed
3367 && (GET_MODE (operands[0]) == TFmode
3368 || GET_MODE (operands[0]) == XFmode
3369 || GET_MODE (operands[0]) == DFmode)
3370 && (operands[2] = find_constant_src (insn))"
3371 [(set (match_dup 0) (match_dup 2))]
3372 {
3373 rtx c = operands[2];
3374 int r = REGNO (operands[0]);
3375
3376 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3377 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3378 FAIL;
3379 })
3380
3381 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3382 (define_split
3383 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3384 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3385 "reload_completed
3386 && (standard_80387_constant_p (operands[1]) == 8
3387 || standard_80387_constant_p (operands[1]) == 9)"
3388 [(set (match_dup 0)(match_dup 1))
3389 (set (match_dup 0)
3390 (neg:X87MODEF (match_dup 0)))]
3391 {
3392 REAL_VALUE_TYPE r;
3393
3394 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3395 if (real_isnegzero (&r))
3396 operands[1] = CONST0_RTX (<MODE>mode);
3397 else
3398 operands[1] = CONST1_RTX (<MODE>mode);
3399 })
3400
3401 (define_split
3402 [(set (match_operand 0 "nonimmediate_operand" "")
3403 (match_operand 1 "general_operand" ""))]
3404 "reload_completed
3405 && (GET_MODE (operands[0]) == TFmode
3406 || GET_MODE (operands[0]) == XFmode
3407 || GET_MODE (operands[0]) == DFmode)
3408 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3409 [(const_int 0)]
3410 "ix86_split_long_move (operands); DONE;")
3411
3412 (define_insn "swapxf"
3413 [(set (match_operand:XF 0 "register_operand" "+f")
3414 (match_operand:XF 1 "register_operand" "+f"))
3415 (set (match_dup 1)
3416 (match_dup 0))]
3417 "TARGET_80387"
3418 {
3419 if (STACK_TOP_P (operands[0]))
3420 return "fxch\t%1";
3421 else
3422 return "fxch\t%0";
3423 }
3424 [(set_attr "type" "fxch")
3425 (set_attr "mode" "XF")])
3426
3427 (define_insn "*swap<mode>"
3428 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3429 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3430 (set (match_dup 1)
3431 (match_dup 0))]
3432 "TARGET_80387 || reload_completed"
3433 {
3434 if (STACK_TOP_P (operands[0]))
3435 return "fxch\t%1";
3436 else
3437 return "fxch\t%0";
3438 }
3439 [(set_attr "type" "fxch")
3440 (set_attr "mode" "<MODE>")])
3441 \f
3442 ;; Zero extension instructions
3443
3444 (define_expand "zero_extendsidi2"
3445 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3446 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3447 ""
3448 {
3449 if (!TARGET_64BIT)
3450 {
3451 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3452 DONE;
3453 }
3454 })
3455
3456 (define_insn "*zero_extendsidi2_rex64"
3457 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3458 (zero_extend:DI
3459 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3460 "TARGET_64BIT"
3461 "@
3462 mov\t{%k1, %k0|%k0, %k1}
3463 #
3464 movd\t{%1, %0|%0, %1}
3465 movd\t{%1, %0|%0, %1}
3466 %vmovd\t{%1, %0|%0, %1}
3467 %vmovd\t{%1, %0|%0, %1}"
3468 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3469 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3470 (set_attr "prefix_0f" "0,*,*,*,*,*")
3471 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3472
3473 (define_split
3474 [(set (match_operand:DI 0 "memory_operand" "")
3475 (zero_extend:DI (match_dup 0)))]
3476 "TARGET_64BIT"
3477 [(set (match_dup 4) (const_int 0))]
3478 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3479
3480 ;; %%% Kill me once multi-word ops are sane.
3481 (define_insn "zero_extendsidi2_1"
3482 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3483 (zero_extend:DI
3484 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3485 (clobber (reg:CC FLAGS_REG))]
3486 "!TARGET_64BIT"
3487 "@
3488 #
3489 #
3490 #
3491 movd\t{%1, %0|%0, %1}
3492 movd\t{%1, %0|%0, %1}
3493 %vmovd\t{%1, %0|%0, %1}
3494 %vmovd\t{%1, %0|%0, %1}"
3495 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3496 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3497 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3498 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3499
3500 (define_split
3501 [(set (match_operand:DI 0 "register_operand" "")
3502 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3503 (clobber (reg:CC FLAGS_REG))]
3504 "!TARGET_64BIT && reload_completed
3505 && true_regnum (operands[0]) == true_regnum (operands[1])"
3506 [(set (match_dup 4) (const_int 0))]
3507 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3508
3509 (define_split
3510 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3511 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3512 (clobber (reg:CC FLAGS_REG))]
3513 "!TARGET_64BIT && reload_completed
3514 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3515 [(set (match_dup 3) (match_dup 1))
3516 (set (match_dup 4) (const_int 0))]
3517 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3518
3519 (define_insn "zero_extend<mode>di2"
3520 [(set (match_operand:DI 0 "register_operand" "=r")
3521 (zero_extend:DI
3522 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3523 "TARGET_64BIT"
3524 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3525 [(set_attr "type" "imovx")
3526 (set_attr "mode" "SI")])
3527
3528 (define_expand "zero_extendhisi2"
3529 [(set (match_operand:SI 0 "register_operand" "")
3530 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3531 ""
3532 {
3533 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3534 {
3535 operands[1] = force_reg (HImode, operands[1]);
3536 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3537 DONE;
3538 }
3539 })
3540
3541 (define_insn_and_split "zero_extendhisi2_and"
3542 [(set (match_operand:SI 0 "register_operand" "=r")
3543 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3544 (clobber (reg:CC FLAGS_REG))]
3545 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3546 "#"
3547 "&& reload_completed"
3548 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3549 (clobber (reg:CC FLAGS_REG))])]
3550 ""
3551 [(set_attr "type" "alu1")
3552 (set_attr "mode" "SI")])
3553
3554 (define_insn "*zero_extendhisi2_movzwl"
3555 [(set (match_operand:SI 0 "register_operand" "=r")
3556 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3557 "!TARGET_ZERO_EXTEND_WITH_AND
3558 || optimize_function_for_size_p (cfun)"
3559 "movz{wl|x}\t{%1, %0|%0, %1}"
3560 [(set_attr "type" "imovx")
3561 (set_attr "mode" "SI")])
3562
3563 (define_expand "zero_extendqi<mode>2"
3564 [(parallel
3565 [(set (match_operand:SWI24 0 "register_operand" "")
3566 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3567 (clobber (reg:CC FLAGS_REG))])])
3568
3569 (define_insn "*zero_extendqi<mode>2_and"
3570 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3571 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3572 (clobber (reg:CC FLAGS_REG))]
3573 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3574 "#"
3575 [(set_attr "type" "alu1")
3576 (set_attr "mode" "<MODE>")])
3577
3578 ;; When source and destination does not overlap, clear destination
3579 ;; first and then do the movb
3580 (define_split
3581 [(set (match_operand:SWI24 0 "register_operand" "")
3582 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3583 (clobber (reg:CC FLAGS_REG))]
3584 "reload_completed
3585 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3586 && ANY_QI_REG_P (operands[0])
3587 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3588 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3589 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3590 {
3591 operands[2] = gen_lowpart (QImode, operands[0]);
3592 ix86_expand_clear (operands[0]);
3593 })
3594
3595 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3596 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3597 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3598 (clobber (reg:CC FLAGS_REG))]
3599 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3600 "#"
3601 [(set_attr "type" "imovx,alu1")
3602 (set_attr "mode" "<MODE>")])
3603
3604 ;; For the movzbl case strip only the clobber
3605 (define_split
3606 [(set (match_operand:SWI24 0 "register_operand" "")
3607 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3608 (clobber (reg:CC FLAGS_REG))]
3609 "reload_completed
3610 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3611 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3612 [(set (match_dup 0)
3613 (zero_extend:SWI24 (match_dup 1)))])
3614
3615 ; zero extend to SImode to avoid partial register stalls
3616 (define_insn "*zero_extendqi<mode>2_movzbl"
3617 [(set (match_operand:SWI24 0 "register_operand" "=r")
3618 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3619 "reload_completed
3620 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3621 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3622 [(set_attr "type" "imovx")
3623 (set_attr "mode" "SI")])
3624
3625 ;; Rest is handled by single and.
3626 (define_split
3627 [(set (match_operand:SWI24 0 "register_operand" "")
3628 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3629 (clobber (reg:CC FLAGS_REG))]
3630 "reload_completed
3631 && true_regnum (operands[0]) == true_regnum (operands[1])"
3632 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3633 (clobber (reg:CC FLAGS_REG))])])
3634 \f
3635 ;; Sign extension instructions
3636
3637 (define_expand "extendsidi2"
3638 [(set (match_operand:DI 0 "register_operand" "")
3639 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3640 ""
3641 {
3642 if (!TARGET_64BIT)
3643 {
3644 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3645 DONE;
3646 }
3647 })
3648
3649 (define_insn "*extendsidi2_rex64"
3650 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3651 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3652 "TARGET_64BIT"
3653 "@
3654 {cltq|cdqe}
3655 movs{lq|x}\t{%1, %0|%0, %1}"
3656 [(set_attr "type" "imovx")
3657 (set_attr "mode" "DI")
3658 (set_attr "prefix_0f" "0")
3659 (set_attr "modrm" "0,1")])
3660
3661 (define_insn "extendsidi2_1"
3662 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3663 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3664 (clobber (reg:CC FLAGS_REG))
3665 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3666 "!TARGET_64BIT"
3667 "#")
3668
3669 ;; Extend to memory case when source register does die.
3670 (define_split
3671 [(set (match_operand:DI 0 "memory_operand" "")
3672 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3673 (clobber (reg:CC FLAGS_REG))
3674 (clobber (match_operand:SI 2 "register_operand" ""))]
3675 "(reload_completed
3676 && dead_or_set_p (insn, operands[1])
3677 && !reg_mentioned_p (operands[1], operands[0]))"
3678 [(set (match_dup 3) (match_dup 1))
3679 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3680 (clobber (reg:CC FLAGS_REG))])
3681 (set (match_dup 4) (match_dup 1))]
3682 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3683
3684 ;; Extend to memory case when source register does not die.
3685 (define_split
3686 [(set (match_operand:DI 0 "memory_operand" "")
3687 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3688 (clobber (reg:CC FLAGS_REG))
3689 (clobber (match_operand:SI 2 "register_operand" ""))]
3690 "reload_completed"
3691 [(const_int 0)]
3692 {
3693 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3694
3695 emit_move_insn (operands[3], operands[1]);
3696
3697 /* Generate a cltd if possible and doing so it profitable. */
3698 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3699 && true_regnum (operands[1]) == AX_REG
3700 && true_regnum (operands[2]) == DX_REG)
3701 {
3702 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3703 }
3704 else
3705 {
3706 emit_move_insn (operands[2], operands[1]);
3707 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3708 }
3709 emit_move_insn (operands[4], operands[2]);
3710 DONE;
3711 })
3712
3713 ;; Extend to register case. Optimize case where source and destination
3714 ;; registers match and cases where we can use cltd.
3715 (define_split
3716 [(set (match_operand:DI 0 "register_operand" "")
3717 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3718 (clobber (reg:CC FLAGS_REG))
3719 (clobber (match_scratch:SI 2 ""))]
3720 "reload_completed"
3721 [(const_int 0)]
3722 {
3723 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3724
3725 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3726 emit_move_insn (operands[3], operands[1]);
3727
3728 /* Generate a cltd if possible and doing so it profitable. */
3729 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3730 && true_regnum (operands[3]) == AX_REG
3731 && true_regnum (operands[4]) == DX_REG)
3732 {
3733 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3734 DONE;
3735 }
3736
3737 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3738 emit_move_insn (operands[4], operands[1]);
3739
3740 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3741 DONE;
3742 })
3743
3744 (define_insn "extend<mode>di2"
3745 [(set (match_operand:DI 0 "register_operand" "=r")
3746 (sign_extend:DI
3747 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3748 "TARGET_64BIT"
3749 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3750 [(set_attr "type" "imovx")
3751 (set_attr "mode" "DI")])
3752
3753 (define_insn "extendhisi2"
3754 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3755 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3756 ""
3757 {
3758 switch (get_attr_prefix_0f (insn))
3759 {
3760 case 0:
3761 return "{cwtl|cwde}";
3762 default:
3763 return "movs{wl|x}\t{%1, %0|%0, %1}";
3764 }
3765 }
3766 [(set_attr "type" "imovx")
3767 (set_attr "mode" "SI")
3768 (set (attr "prefix_0f")
3769 ;; movsx is short decodable while cwtl is vector decoded.
3770 (if_then_else (and (eq_attr "cpu" "!k6")
3771 (eq_attr "alternative" "0"))
3772 (const_string "0")
3773 (const_string "1")))
3774 (set (attr "modrm")
3775 (if_then_else (eq_attr "prefix_0f" "0")
3776 (const_string "0")
3777 (const_string "1")))])
3778
3779 (define_insn "*extendhisi2_zext"
3780 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3781 (zero_extend:DI
3782 (sign_extend:SI
3783 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3784 "TARGET_64BIT"
3785 {
3786 switch (get_attr_prefix_0f (insn))
3787 {
3788 case 0:
3789 return "{cwtl|cwde}";
3790 default:
3791 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3792 }
3793 }
3794 [(set_attr "type" "imovx")
3795 (set_attr "mode" "SI")
3796 (set (attr "prefix_0f")
3797 ;; movsx is short decodable while cwtl is vector decoded.
3798 (if_then_else (and (eq_attr "cpu" "!k6")
3799 (eq_attr "alternative" "0"))
3800 (const_string "0")
3801 (const_string "1")))
3802 (set (attr "modrm")
3803 (if_then_else (eq_attr "prefix_0f" "0")
3804 (const_string "0")
3805 (const_string "1")))])
3806
3807 (define_insn "extendqisi2"
3808 [(set (match_operand:SI 0 "register_operand" "=r")
3809 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3810 ""
3811 "movs{bl|x}\t{%1, %0|%0, %1}"
3812 [(set_attr "type" "imovx")
3813 (set_attr "mode" "SI")])
3814
3815 (define_insn "*extendqisi2_zext"
3816 [(set (match_operand:DI 0 "register_operand" "=r")
3817 (zero_extend:DI
3818 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3819 "TARGET_64BIT"
3820 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3821 [(set_attr "type" "imovx")
3822 (set_attr "mode" "SI")])
3823
3824 (define_insn "extendqihi2"
3825 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3826 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3827 ""
3828 {
3829 switch (get_attr_prefix_0f (insn))
3830 {
3831 case 0:
3832 return "{cbtw|cbw}";
3833 default:
3834 return "movs{bw|x}\t{%1, %0|%0, %1}";
3835 }
3836 }
3837 [(set_attr "type" "imovx")
3838 (set_attr "mode" "HI")
3839 (set (attr "prefix_0f")
3840 ;; movsx is short decodable while cwtl is vector decoded.
3841 (if_then_else (and (eq_attr "cpu" "!k6")
3842 (eq_attr "alternative" "0"))
3843 (const_string "0")
3844 (const_string "1")))
3845 (set (attr "modrm")
3846 (if_then_else (eq_attr "prefix_0f" "0")
3847 (const_string "0")
3848 (const_string "1")))])
3849 \f
3850 ;; Conversions between float and double.
3851
3852 ;; These are all no-ops in the model used for the 80387.
3853 ;; So just emit moves.
3854
3855 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3856 (define_split
3857 [(set (match_operand:DF 0 "push_operand" "")
3858 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3859 "reload_completed"
3860 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3861 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3862
3863 (define_split
3864 [(set (match_operand:XF 0 "push_operand" "")
3865 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3866 "reload_completed"
3867 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3868 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3869 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3870
3871 (define_expand "extendsfdf2"
3872 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3873 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3874 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3875 {
3876 /* ??? Needed for compress_float_constant since all fp constants
3877 are TARGET_LEGITIMATE_CONSTANT_P. */
3878 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3879 {
3880 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3881 && standard_80387_constant_p (operands[1]) > 0)
3882 {
3883 operands[1] = simplify_const_unary_operation
3884 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3885 emit_move_insn_1 (operands[0], operands[1]);
3886 DONE;
3887 }
3888 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3889 }
3890 })
3891
3892 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3893 cvtss2sd:
3894 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3895 cvtps2pd xmm2,xmm1
3896 We do the conversion post reload to avoid producing of 128bit spills
3897 that might lead to ICE on 32bit target. The sequence unlikely combine
3898 anyway. */
3899 (define_split
3900 [(set (match_operand:DF 0 "register_operand" "")
3901 (float_extend:DF
3902 (match_operand:SF 1 "nonimmediate_operand" "")))]
3903 "TARGET_USE_VECTOR_FP_CONVERTS
3904 && optimize_insn_for_speed_p ()
3905 && reload_completed && SSE_REG_P (operands[0])"
3906 [(set (match_dup 2)
3907 (float_extend:V2DF
3908 (vec_select:V2SF
3909 (match_dup 3)
3910 (parallel [(const_int 0) (const_int 1)]))))]
3911 {
3912 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3913 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3914 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3915 Try to avoid move when unpacking can be done in source. */
3916 if (REG_P (operands[1]))
3917 {
3918 /* If it is unsafe to overwrite upper half of source, we need
3919 to move to destination and unpack there. */
3920 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3921 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3922 && true_regnum (operands[0]) != true_regnum (operands[1]))
3923 {
3924 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3925 emit_move_insn (tmp, operands[1]);
3926 }
3927 else
3928 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3929 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3930 operands[3]));
3931 }
3932 else
3933 emit_insn (gen_vec_setv4sf_0 (operands[3],
3934 CONST0_RTX (V4SFmode), operands[1]));
3935 })
3936
3937 (define_insn "*extendsfdf2_mixed"
3938 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3939 (float_extend:DF
3940 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3941 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3942 {
3943 switch (which_alternative)
3944 {
3945 case 0:
3946 case 1:
3947 return output_387_reg_move (insn, operands);
3948
3949 case 2:
3950 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3951
3952 default:
3953 gcc_unreachable ();
3954 }
3955 }
3956 [(set_attr "type" "fmov,fmov,ssecvt")
3957 (set_attr "prefix" "orig,orig,maybe_vex")
3958 (set_attr "mode" "SF,XF,DF")])
3959
3960 (define_insn "*extendsfdf2_sse"
3961 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3962 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3963 "TARGET_SSE2 && TARGET_SSE_MATH"
3964 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3965 [(set_attr "type" "ssecvt")
3966 (set_attr "prefix" "maybe_vex")
3967 (set_attr "mode" "DF")])
3968
3969 (define_insn "*extendsfdf2_i387"
3970 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3971 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3972 "TARGET_80387"
3973 "* return output_387_reg_move (insn, operands);"
3974 [(set_attr "type" "fmov")
3975 (set_attr "mode" "SF,XF")])
3976
3977 (define_expand "extend<mode>xf2"
3978 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3979 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3980 "TARGET_80387"
3981 {
3982 /* ??? Needed for compress_float_constant since all fp constants
3983 are TARGET_LEGITIMATE_CONSTANT_P. */
3984 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3985 {
3986 if (standard_80387_constant_p (operands[1]) > 0)
3987 {
3988 operands[1] = simplify_const_unary_operation
3989 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3990 emit_move_insn_1 (operands[0], operands[1]);
3991 DONE;
3992 }
3993 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3994 }
3995 })
3996
3997 (define_insn "*extend<mode>xf2_i387"
3998 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3999 (float_extend:XF
4000 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4001 "TARGET_80387"
4002 "* return output_387_reg_move (insn, operands);"
4003 [(set_attr "type" "fmov")
4004 (set_attr "mode" "<MODE>,XF")])
4005
4006 ;; %%% This seems bad bad news.
4007 ;; This cannot output into an f-reg because there is no way to be sure
4008 ;; of truncating in that case. Otherwise this is just like a simple move
4009 ;; insn. So we pretend we can output to a reg in order to get better
4010 ;; register preferencing, but we really use a stack slot.
4011
4012 ;; Conversion from DFmode to SFmode.
4013
4014 (define_expand "truncdfsf2"
4015 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4016 (float_truncate:SF
4017 (match_operand:DF 1 "nonimmediate_operand" "")))]
4018 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4019 {
4020 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4021 ;
4022 else if (flag_unsafe_math_optimizations)
4023 ;
4024 else
4025 {
4026 enum ix86_stack_slot slot = (virtuals_instantiated
4027 ? SLOT_TEMP
4028 : SLOT_VIRTUAL);
4029 rtx temp = assign_386_stack_local (SFmode, slot);
4030 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4031 DONE;
4032 }
4033 })
4034
4035 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4036 cvtsd2ss:
4037 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4038 cvtpd2ps xmm2,xmm1
4039 We do the conversion post reload to avoid producing of 128bit spills
4040 that might lead to ICE on 32bit target. The sequence unlikely combine
4041 anyway. */
4042 (define_split
4043 [(set (match_operand:SF 0 "register_operand" "")
4044 (float_truncate:SF
4045 (match_operand:DF 1 "nonimmediate_operand" "")))]
4046 "TARGET_USE_VECTOR_FP_CONVERTS
4047 && optimize_insn_for_speed_p ()
4048 && reload_completed && SSE_REG_P (operands[0])"
4049 [(set (match_dup 2)
4050 (vec_concat:V4SF
4051 (float_truncate:V2SF
4052 (match_dup 4))
4053 (match_dup 3)))]
4054 {
4055 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4056 operands[3] = CONST0_RTX (V2SFmode);
4057 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4058 /* Use movsd for loading from memory, unpcklpd for registers.
4059 Try to avoid move when unpacking can be done in source, or SSE3
4060 movddup is available. */
4061 if (REG_P (operands[1]))
4062 {
4063 if (!TARGET_SSE3
4064 && true_regnum (operands[0]) != true_regnum (operands[1])
4065 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4066 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4067 {
4068 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4069 emit_move_insn (tmp, operands[1]);
4070 operands[1] = tmp;
4071 }
4072 else if (!TARGET_SSE3)
4073 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4074 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4075 }
4076 else
4077 emit_insn (gen_sse2_loadlpd (operands[4],
4078 CONST0_RTX (V2DFmode), operands[1]));
4079 })
4080
4081 (define_expand "truncdfsf2_with_temp"
4082 [(parallel [(set (match_operand:SF 0 "" "")
4083 (float_truncate:SF (match_operand:DF 1 "" "")))
4084 (clobber (match_operand:SF 2 "" ""))])])
4085
4086 (define_insn "*truncdfsf_fast_mixed"
4087 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4088 (float_truncate:SF
4089 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4090 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4091 {
4092 switch (which_alternative)
4093 {
4094 case 0:
4095 return output_387_reg_move (insn, operands);
4096 case 1:
4097 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4098 default:
4099 gcc_unreachable ();
4100 }
4101 }
4102 [(set_attr "type" "fmov,ssecvt")
4103 (set_attr "prefix" "orig,maybe_vex")
4104 (set_attr "mode" "SF")])
4105
4106 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4107 ;; because nothing we do here is unsafe.
4108 (define_insn "*truncdfsf_fast_sse"
4109 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4110 (float_truncate:SF
4111 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4112 "TARGET_SSE2 && TARGET_SSE_MATH"
4113 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4114 [(set_attr "type" "ssecvt")
4115 (set_attr "prefix" "maybe_vex")
4116 (set_attr "mode" "SF")])
4117
4118 (define_insn "*truncdfsf_fast_i387"
4119 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4120 (float_truncate:SF
4121 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4122 "TARGET_80387 && flag_unsafe_math_optimizations"
4123 "* return output_387_reg_move (insn, operands);"
4124 [(set_attr "type" "fmov")
4125 (set_attr "mode" "SF")])
4126
4127 (define_insn "*truncdfsf_mixed"
4128 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4129 (float_truncate:SF
4130 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4131 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4132 "TARGET_MIX_SSE_I387"
4133 {
4134 switch (which_alternative)
4135 {
4136 case 0:
4137 return output_387_reg_move (insn, operands);
4138 case 1:
4139 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4140
4141 default:
4142 return "#";
4143 }
4144 }
4145 [(set_attr "isa" "*,sse2,*,*,*")
4146 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4147 (set_attr "unit" "*,*,i387,i387,i387")
4148 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4149 (set_attr "mode" "SF")])
4150
4151 (define_insn "*truncdfsf_i387"
4152 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4153 (float_truncate:SF
4154 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4155 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4156 "TARGET_80387"
4157 {
4158 switch (which_alternative)
4159 {
4160 case 0:
4161 return output_387_reg_move (insn, operands);
4162
4163 default:
4164 return "#";
4165 }
4166 }
4167 [(set_attr "type" "fmov,multi,multi,multi")
4168 (set_attr "unit" "*,i387,i387,i387")
4169 (set_attr "mode" "SF")])
4170
4171 (define_insn "*truncdfsf2_i387_1"
4172 [(set (match_operand:SF 0 "memory_operand" "=m")
4173 (float_truncate:SF
4174 (match_operand:DF 1 "register_operand" "f")))]
4175 "TARGET_80387
4176 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4177 && !TARGET_MIX_SSE_I387"
4178 "* return output_387_reg_move (insn, operands);"
4179 [(set_attr "type" "fmov")
4180 (set_attr "mode" "SF")])
4181
4182 (define_split
4183 [(set (match_operand:SF 0 "register_operand" "")
4184 (float_truncate:SF
4185 (match_operand:DF 1 "fp_register_operand" "")))
4186 (clobber (match_operand 2 "" ""))]
4187 "reload_completed"
4188 [(set (match_dup 2) (match_dup 1))
4189 (set (match_dup 0) (match_dup 2))]
4190 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4191
4192 ;; Conversion from XFmode to {SF,DF}mode
4193
4194 (define_expand "truncxf<mode>2"
4195 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4196 (float_truncate:MODEF
4197 (match_operand:XF 1 "register_operand" "")))
4198 (clobber (match_dup 2))])]
4199 "TARGET_80387"
4200 {
4201 if (flag_unsafe_math_optimizations)
4202 {
4203 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4204 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4205 if (reg != operands[0])
4206 emit_move_insn (operands[0], reg);
4207 DONE;
4208 }
4209 else
4210 {
4211 enum ix86_stack_slot slot = (virtuals_instantiated
4212 ? SLOT_TEMP
4213 : SLOT_VIRTUAL);
4214 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4215 }
4216 })
4217
4218 (define_insn "*truncxfsf2_mixed"
4219 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4220 (float_truncate:SF
4221 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4222 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4223 "TARGET_80387"
4224 {
4225 gcc_assert (!which_alternative);
4226 return output_387_reg_move (insn, operands);
4227 }
4228 [(set_attr "type" "fmov,multi,multi,multi")
4229 (set_attr "unit" "*,i387,i387,i387")
4230 (set_attr "mode" "SF")])
4231
4232 (define_insn "*truncxfdf2_mixed"
4233 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4234 (float_truncate:DF
4235 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4236 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4237 "TARGET_80387"
4238 {
4239 gcc_assert (!which_alternative);
4240 return output_387_reg_move (insn, operands);
4241 }
4242 [(set_attr "isa" "*,*,sse2,*")
4243 (set_attr "type" "fmov,multi,multi,multi")
4244 (set_attr "unit" "*,i387,i387,i387")
4245 (set_attr "mode" "DF")])
4246
4247 (define_insn "truncxf<mode>2_i387_noop"
4248 [(set (match_operand:MODEF 0 "register_operand" "=f")
4249 (float_truncate:MODEF
4250 (match_operand:XF 1 "register_operand" "f")))]
4251 "TARGET_80387 && flag_unsafe_math_optimizations"
4252 "* return output_387_reg_move (insn, operands);"
4253 [(set_attr "type" "fmov")
4254 (set_attr "mode" "<MODE>")])
4255
4256 (define_insn "*truncxf<mode>2_i387"
4257 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4258 (float_truncate:MODEF
4259 (match_operand:XF 1 "register_operand" "f")))]
4260 "TARGET_80387"
4261 "* return output_387_reg_move (insn, operands);"
4262 [(set_attr "type" "fmov")
4263 (set_attr "mode" "<MODE>")])
4264
4265 (define_split
4266 [(set (match_operand:MODEF 0 "register_operand" "")
4267 (float_truncate:MODEF
4268 (match_operand:XF 1 "register_operand" "")))
4269 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4270 "TARGET_80387 && reload_completed"
4271 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4272 (set (match_dup 0) (match_dup 2))])
4273
4274 (define_split
4275 [(set (match_operand:MODEF 0 "memory_operand" "")
4276 (float_truncate:MODEF
4277 (match_operand:XF 1 "register_operand" "")))
4278 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4279 "TARGET_80387"
4280 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4281 \f
4282 ;; Signed conversion to DImode.
4283
4284 (define_expand "fix_truncxfdi2"
4285 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4286 (fix:DI (match_operand:XF 1 "register_operand" "")))
4287 (clobber (reg:CC FLAGS_REG))])]
4288 "TARGET_80387"
4289 {
4290 if (TARGET_FISTTP)
4291 {
4292 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4293 DONE;
4294 }
4295 })
4296
4297 (define_expand "fix_trunc<mode>di2"
4298 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4299 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4300 (clobber (reg:CC FLAGS_REG))])]
4301 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4302 {
4303 if (TARGET_FISTTP
4304 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4305 {
4306 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4307 DONE;
4308 }
4309 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4310 {
4311 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4312 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4313 if (out != operands[0])
4314 emit_move_insn (operands[0], out);
4315 DONE;
4316 }
4317 })
4318
4319 ;; Signed conversion to SImode.
4320
4321 (define_expand "fix_truncxfsi2"
4322 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4323 (fix:SI (match_operand:XF 1 "register_operand" "")))
4324 (clobber (reg:CC FLAGS_REG))])]
4325 "TARGET_80387"
4326 {
4327 if (TARGET_FISTTP)
4328 {
4329 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4330 DONE;
4331 }
4332 })
4333
4334 (define_expand "fix_trunc<mode>si2"
4335 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4336 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4337 (clobber (reg:CC FLAGS_REG))])]
4338 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4339 {
4340 if (TARGET_FISTTP
4341 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4342 {
4343 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4344 DONE;
4345 }
4346 if (SSE_FLOAT_MODE_P (<MODE>mode))
4347 {
4348 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4349 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4350 if (out != operands[0])
4351 emit_move_insn (operands[0], out);
4352 DONE;
4353 }
4354 })
4355
4356 ;; Signed conversion to HImode.
4357
4358 (define_expand "fix_trunc<mode>hi2"
4359 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4360 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4361 (clobber (reg:CC FLAGS_REG))])]
4362 "TARGET_80387
4363 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4364 {
4365 if (TARGET_FISTTP)
4366 {
4367 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4368 DONE;
4369 }
4370 })
4371
4372 ;; Unsigned conversion to SImode.
4373
4374 (define_expand "fixuns_trunc<mode>si2"
4375 [(parallel
4376 [(set (match_operand:SI 0 "register_operand" "")
4377 (unsigned_fix:SI
4378 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4379 (use (match_dup 2))
4380 (clobber (match_scratch:<ssevecmode> 3 ""))
4381 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4382 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4383 {
4384 enum machine_mode mode = <MODE>mode;
4385 enum machine_mode vecmode = <ssevecmode>mode;
4386 REAL_VALUE_TYPE TWO31r;
4387 rtx two31;
4388
4389 if (optimize_insn_for_size_p ())
4390 FAIL;
4391
4392 real_ldexp (&TWO31r, &dconst1, 31);
4393 two31 = const_double_from_real_value (TWO31r, mode);
4394 two31 = ix86_build_const_vector (vecmode, true, two31);
4395 operands[2] = force_reg (vecmode, two31);
4396 })
4397
4398 (define_insn_and_split "*fixuns_trunc<mode>_1"
4399 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4400 (unsigned_fix:SI
4401 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4402 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4403 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4404 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4405 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4406 && optimize_function_for_speed_p (cfun)"
4407 "#"
4408 "&& reload_completed"
4409 [(const_int 0)]
4410 {
4411 ix86_split_convert_uns_si_sse (operands);
4412 DONE;
4413 })
4414
4415 ;; Unsigned conversion to HImode.
4416 ;; Without these patterns, we'll try the unsigned SI conversion which
4417 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4418
4419 (define_expand "fixuns_trunc<mode>hi2"
4420 [(set (match_dup 2)
4421 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4422 (set (match_operand:HI 0 "nonimmediate_operand" "")
4423 (subreg:HI (match_dup 2) 0))]
4424 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4425 "operands[2] = gen_reg_rtx (SImode);")
4426
4427 ;; When SSE is available, it is always faster to use it!
4428 (define_insn "fix_trunc<mode>di_sse"
4429 [(set (match_operand:DI 0 "register_operand" "=r,r")
4430 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4431 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4432 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4433 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4434 [(set_attr "type" "sseicvt")
4435 (set_attr "prefix" "maybe_vex")
4436 (set_attr "prefix_rex" "1")
4437 (set_attr "mode" "<MODE>")
4438 (set_attr "athlon_decode" "double,vector")
4439 (set_attr "amdfam10_decode" "double,double")
4440 (set_attr "bdver1_decode" "double,double")])
4441
4442 (define_insn "fix_trunc<mode>si_sse"
4443 [(set (match_operand:SI 0 "register_operand" "=r,r")
4444 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4445 "SSE_FLOAT_MODE_P (<MODE>mode)
4446 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4447 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4448 [(set_attr "type" "sseicvt")
4449 (set_attr "prefix" "maybe_vex")
4450 (set_attr "mode" "<MODE>")
4451 (set_attr "athlon_decode" "double,vector")
4452 (set_attr "amdfam10_decode" "double,double")
4453 (set_attr "bdver1_decode" "double,double")])
4454
4455 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4456 (define_peephole2
4457 [(set (match_operand:MODEF 0 "register_operand" "")
4458 (match_operand:MODEF 1 "memory_operand" ""))
4459 (set (match_operand:SWI48x 2 "register_operand" "")
4460 (fix:SWI48x (match_dup 0)))]
4461 "TARGET_SHORTEN_X87_SSE
4462 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4463 && peep2_reg_dead_p (2, operands[0])"
4464 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4465
4466 ;; Avoid vector decoded forms of the instruction.
4467 (define_peephole2
4468 [(match_scratch:DF 2 "x")
4469 (set (match_operand:SWI48x 0 "register_operand" "")
4470 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4471 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4472 [(set (match_dup 2) (match_dup 1))
4473 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4474
4475 (define_peephole2
4476 [(match_scratch:SF 2 "x")
4477 (set (match_operand:SWI48x 0 "register_operand" "")
4478 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4479 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4480 [(set (match_dup 2) (match_dup 1))
4481 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4482
4483 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4484 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4485 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4486 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4487 && TARGET_FISTTP
4488 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4489 && (TARGET_64BIT || <MODE>mode != DImode))
4490 && TARGET_SSE_MATH)
4491 && can_create_pseudo_p ()"
4492 "#"
4493 "&& 1"
4494 [(const_int 0)]
4495 {
4496 if (memory_operand (operands[0], VOIDmode))
4497 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4498 else
4499 {
4500 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4501 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4502 operands[1],
4503 operands[2]));
4504 }
4505 DONE;
4506 }
4507 [(set_attr "type" "fisttp")
4508 (set_attr "mode" "<MODE>")])
4509
4510 (define_insn "fix_trunc<mode>_i387_fisttp"
4511 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4512 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4513 (clobber (match_scratch:XF 2 "=&1f"))]
4514 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4515 && TARGET_FISTTP
4516 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4517 && (TARGET_64BIT || <MODE>mode != DImode))
4518 && TARGET_SSE_MATH)"
4519 "* return output_fix_trunc (insn, operands, true);"
4520 [(set_attr "type" "fisttp")
4521 (set_attr "mode" "<MODE>")])
4522
4523 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4524 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4525 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4526 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4527 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4528 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && TARGET_FISTTP
4530 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4531 && (TARGET_64BIT || <MODE>mode != DImode))
4532 && TARGET_SSE_MATH)"
4533 "#"
4534 [(set_attr "type" "fisttp")
4535 (set_attr "mode" "<MODE>")])
4536
4537 (define_split
4538 [(set (match_operand:SWI248x 0 "register_operand" "")
4539 (fix:SWI248x (match_operand 1 "register_operand" "")))
4540 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4541 (clobber (match_scratch 3 ""))]
4542 "reload_completed"
4543 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4544 (clobber (match_dup 3))])
4545 (set (match_dup 0) (match_dup 2))])
4546
4547 (define_split
4548 [(set (match_operand:SWI248x 0 "memory_operand" "")
4549 (fix:SWI248x (match_operand 1 "register_operand" "")))
4550 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4551 (clobber (match_scratch 3 ""))]
4552 "reload_completed"
4553 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4554 (clobber (match_dup 3))])])
4555
4556 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4557 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4558 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4559 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4560 ;; function in i386.c.
4561 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4562 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4563 (fix:SWI248x (match_operand 1 "register_operand" "")))
4564 (clobber (reg:CC FLAGS_REG))]
4565 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4566 && !TARGET_FISTTP
4567 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4568 && (TARGET_64BIT || <MODE>mode != DImode))
4569 && can_create_pseudo_p ()"
4570 "#"
4571 "&& 1"
4572 [(const_int 0)]
4573 {
4574 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4575
4576 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4577 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4578 if (memory_operand (operands[0], VOIDmode))
4579 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4580 operands[2], operands[3]));
4581 else
4582 {
4583 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4584 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4585 operands[2], operands[3],
4586 operands[4]));
4587 }
4588 DONE;
4589 }
4590 [(set_attr "type" "fistp")
4591 (set_attr "i387_cw" "trunc")
4592 (set_attr "mode" "<MODE>")])
4593
4594 (define_insn "fix_truncdi_i387"
4595 [(set (match_operand:DI 0 "memory_operand" "=m")
4596 (fix:DI (match_operand 1 "register_operand" "f")))
4597 (use (match_operand:HI 2 "memory_operand" "m"))
4598 (use (match_operand:HI 3 "memory_operand" "m"))
4599 (clobber (match_scratch:XF 4 "=&1f"))]
4600 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4601 && !TARGET_FISTTP
4602 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4603 "* return output_fix_trunc (insn, operands, false);"
4604 [(set_attr "type" "fistp")
4605 (set_attr "i387_cw" "trunc")
4606 (set_attr "mode" "DI")])
4607
4608 (define_insn "fix_truncdi_i387_with_temp"
4609 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4610 (fix:DI (match_operand 1 "register_operand" "f,f")))
4611 (use (match_operand:HI 2 "memory_operand" "m,m"))
4612 (use (match_operand:HI 3 "memory_operand" "m,m"))
4613 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4614 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4615 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4616 && !TARGET_FISTTP
4617 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4618 "#"
4619 [(set_attr "type" "fistp")
4620 (set_attr "i387_cw" "trunc")
4621 (set_attr "mode" "DI")])
4622
4623 (define_split
4624 [(set (match_operand:DI 0 "register_operand" "")
4625 (fix:DI (match_operand 1 "register_operand" "")))
4626 (use (match_operand:HI 2 "memory_operand" ""))
4627 (use (match_operand:HI 3 "memory_operand" ""))
4628 (clobber (match_operand:DI 4 "memory_operand" ""))
4629 (clobber (match_scratch 5 ""))]
4630 "reload_completed"
4631 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4632 (use (match_dup 2))
4633 (use (match_dup 3))
4634 (clobber (match_dup 5))])
4635 (set (match_dup 0) (match_dup 4))])
4636
4637 (define_split
4638 [(set (match_operand:DI 0 "memory_operand" "")
4639 (fix:DI (match_operand 1 "register_operand" "")))
4640 (use (match_operand:HI 2 "memory_operand" ""))
4641 (use (match_operand:HI 3 "memory_operand" ""))
4642 (clobber (match_operand:DI 4 "memory_operand" ""))
4643 (clobber (match_scratch 5 ""))]
4644 "reload_completed"
4645 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4646 (use (match_dup 2))
4647 (use (match_dup 3))
4648 (clobber (match_dup 5))])])
4649
4650 (define_insn "fix_trunc<mode>_i387"
4651 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4652 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4653 (use (match_operand:HI 2 "memory_operand" "m"))
4654 (use (match_operand:HI 3 "memory_operand" "m"))]
4655 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4656 && !TARGET_FISTTP
4657 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4658 "* return output_fix_trunc (insn, operands, false);"
4659 [(set_attr "type" "fistp")
4660 (set_attr "i387_cw" "trunc")
4661 (set_attr "mode" "<MODE>")])
4662
4663 (define_insn "fix_trunc<mode>_i387_with_temp"
4664 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4665 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4666 (use (match_operand:HI 2 "memory_operand" "m,m"))
4667 (use (match_operand:HI 3 "memory_operand" "m,m"))
4668 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4669 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4670 && !TARGET_FISTTP
4671 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4672 "#"
4673 [(set_attr "type" "fistp")
4674 (set_attr "i387_cw" "trunc")
4675 (set_attr "mode" "<MODE>")])
4676
4677 (define_split
4678 [(set (match_operand:SWI24 0 "register_operand" "")
4679 (fix:SWI24 (match_operand 1 "register_operand" "")))
4680 (use (match_operand:HI 2 "memory_operand" ""))
4681 (use (match_operand:HI 3 "memory_operand" ""))
4682 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4683 "reload_completed"
4684 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4685 (use (match_dup 2))
4686 (use (match_dup 3))])
4687 (set (match_dup 0) (match_dup 4))])
4688
4689 (define_split
4690 [(set (match_operand:SWI24 0 "memory_operand" "")
4691 (fix:SWI24 (match_operand 1 "register_operand" "")))
4692 (use (match_operand:HI 2 "memory_operand" ""))
4693 (use (match_operand:HI 3 "memory_operand" ""))
4694 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4695 "reload_completed"
4696 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4697 (use (match_dup 2))
4698 (use (match_dup 3))])])
4699
4700 (define_insn "x86_fnstcw_1"
4701 [(set (match_operand:HI 0 "memory_operand" "=m")
4702 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4703 "TARGET_80387"
4704 "fnstcw\t%0"
4705 [(set (attr "length")
4706 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4707 (set_attr "mode" "HI")
4708 (set_attr "unit" "i387")
4709 (set_attr "bdver1_decode" "vector")])
4710
4711 (define_insn "x86_fldcw_1"
4712 [(set (reg:HI FPCR_REG)
4713 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4714 "TARGET_80387"
4715 "fldcw\t%0"
4716 [(set (attr "length")
4717 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4718 (set_attr "mode" "HI")
4719 (set_attr "unit" "i387")
4720 (set_attr "athlon_decode" "vector")
4721 (set_attr "amdfam10_decode" "vector")
4722 (set_attr "bdver1_decode" "vector")])
4723 \f
4724 ;; Conversion between fixed point and floating point.
4725
4726 ;; Even though we only accept memory inputs, the backend _really_
4727 ;; wants to be able to do this between registers.
4728
4729 (define_expand "floathi<mode>2"
4730 [(set (match_operand:X87MODEF 0 "register_operand" "")
4731 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4732 "TARGET_80387
4733 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4734 || TARGET_MIX_SSE_I387)")
4735
4736 ;; Pre-reload splitter to add memory clobber to the pattern.
4737 (define_insn_and_split "*floathi<mode>2_1"
4738 [(set (match_operand:X87MODEF 0 "register_operand" "")
4739 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4740 "TARGET_80387
4741 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4742 || TARGET_MIX_SSE_I387)
4743 && can_create_pseudo_p ()"
4744 "#"
4745 "&& 1"
4746 [(parallel [(set (match_dup 0)
4747 (float:X87MODEF (match_dup 1)))
4748 (clobber (match_dup 2))])]
4749 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4750
4751 (define_insn "*floathi<mode>2_i387_with_temp"
4752 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4753 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4754 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4755 "TARGET_80387
4756 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4757 || TARGET_MIX_SSE_I387)"
4758 "#"
4759 [(set_attr "type" "fmov,multi")
4760 (set_attr "mode" "<MODE>")
4761 (set_attr "unit" "*,i387")
4762 (set_attr "fp_int_src" "true")])
4763
4764 (define_insn "*floathi<mode>2_i387"
4765 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4766 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4767 "TARGET_80387
4768 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4769 || TARGET_MIX_SSE_I387)"
4770 "fild%Z1\t%1"
4771 [(set_attr "type" "fmov")
4772 (set_attr "mode" "<MODE>")
4773 (set_attr "fp_int_src" "true")])
4774
4775 (define_split
4776 [(set (match_operand:X87MODEF 0 "register_operand" "")
4777 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4778 (clobber (match_operand:HI 2 "memory_operand" ""))]
4779 "TARGET_80387
4780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4781 || TARGET_MIX_SSE_I387)
4782 && reload_completed"
4783 [(set (match_dup 2) (match_dup 1))
4784 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4785
4786 (define_split
4787 [(set (match_operand:X87MODEF 0 "register_operand" "")
4788 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4789 (clobber (match_operand:HI 2 "memory_operand" ""))]
4790 "TARGET_80387
4791 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4792 || TARGET_MIX_SSE_I387)
4793 && reload_completed"
4794 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4795
4796 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4797 [(set (match_operand:X87MODEF 0 "register_operand" "")
4798 (float:X87MODEF
4799 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4800 "TARGET_80387
4801 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4802 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4803 {
4804 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4805 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4806 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4807 {
4808 rtx reg = gen_reg_rtx (XFmode);
4809 rtx (*insn)(rtx, rtx);
4810
4811 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4812
4813 if (<X87MODEF:MODE>mode == SFmode)
4814 insn = gen_truncxfsf2;
4815 else if (<X87MODEF:MODE>mode == DFmode)
4816 insn = gen_truncxfdf2;
4817 else
4818 gcc_unreachable ();
4819
4820 emit_insn (insn (operands[0], reg));
4821 DONE;
4822 }
4823 })
4824
4825 ;; Pre-reload splitter to add memory clobber to the pattern.
4826 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4827 [(set (match_operand:X87MODEF 0 "register_operand" "")
4828 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4829 "((TARGET_80387
4830 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4831 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4832 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4833 || TARGET_MIX_SSE_I387))
4834 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4835 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4836 && ((<SWI48x:MODE>mode == SImode
4837 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4838 && optimize_function_for_speed_p (cfun)
4839 && flag_trapping_math)
4840 || !(TARGET_INTER_UNIT_CONVERSIONS
4841 || optimize_function_for_size_p (cfun)))))
4842 && can_create_pseudo_p ()"
4843 "#"
4844 "&& 1"
4845 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4846 (clobber (match_dup 2))])]
4847 {
4848 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4849
4850 /* Avoid store forwarding (partial memory) stall penalty
4851 by passing DImode value through XMM registers. */
4852 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4853 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4854 && optimize_function_for_speed_p (cfun))
4855 {
4856 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4857 operands[1],
4858 operands[2]));
4859 DONE;
4860 }
4861 })
4862
4863 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4864 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4865 (float:MODEF
4866 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4867 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4868 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4869 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4870 "#"
4871 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4872 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4873 (set_attr "unit" "*,i387,*,*,*")
4874 (set_attr "athlon_decode" "*,*,double,direct,double")
4875 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4876 (set_attr "bdver1_decode" "*,*,double,direct,double")
4877 (set_attr "fp_int_src" "true")])
4878
4879 (define_insn "*floatsi<mode>2_vector_mixed"
4880 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4881 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4882 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4883 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4884 "@
4885 fild%Z1\t%1
4886 #"
4887 [(set_attr "type" "fmov,sseicvt")
4888 (set_attr "mode" "<MODE>,<ssevecmode>")
4889 (set_attr "unit" "i387,*")
4890 (set_attr "athlon_decode" "*,direct")
4891 (set_attr "amdfam10_decode" "*,double")
4892 (set_attr "bdver1_decode" "*,direct")
4893 (set_attr "fp_int_src" "true")])
4894
4895 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4896 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4897 (float:MODEF
4898 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4899 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4900 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4901 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4902 "#"
4903 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4904 (set_attr "mode" "<MODEF:MODE>")
4905 (set_attr "unit" "*,i387,*,*")
4906 (set_attr "athlon_decode" "*,*,double,direct")
4907 (set_attr "amdfam10_decode" "*,*,vector,double")
4908 (set_attr "bdver1_decode" "*,*,double,direct")
4909 (set_attr "fp_int_src" "true")])
4910
4911 (define_split
4912 [(set (match_operand:MODEF 0 "register_operand" "")
4913 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4914 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4915 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4916 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4917 && TARGET_INTER_UNIT_CONVERSIONS
4918 && reload_completed
4919 && (SSE_REG_P (operands[0])
4920 || (GET_CODE (operands[0]) == SUBREG
4921 && SSE_REG_P (operands[0])))"
4922 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4923
4924 (define_split
4925 [(set (match_operand:MODEF 0 "register_operand" "")
4926 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4927 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4928 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4929 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4930 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4931 && reload_completed
4932 && (SSE_REG_P (operands[0])
4933 || (GET_CODE (operands[0]) == SUBREG
4934 && SSE_REG_P (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_REG_P (operands[0])
5024 || (GET_CODE (operands[0]) == SUBREG
5025 && SSE_REG_P (operands[0])))"
5026 [(const_int 0)]
5027 {
5028 rtx op1 = operands[1];
5029
5030 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5031 <MODE>mode, 0);
5032 if (GET_CODE (op1) == SUBREG)
5033 op1 = SUBREG_REG (op1);
5034
5035 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5036 {
5037 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5038 emit_insn (gen_sse2_loadld (operands[4],
5039 CONST0_RTX (V4SImode), operands[1]));
5040 }
5041 /* We can ignore possible trapping value in the
5042 high part of SSE register for non-trapping math. */
5043 else if (SSE_REG_P (op1) && !flag_trapping_math)
5044 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5045 else
5046 {
5047 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5048 emit_move_insn (operands[2], operands[1]);
5049 emit_insn (gen_sse2_loadld (operands[4],
5050 CONST0_RTX (V4SImode), operands[2]));
5051 }
5052 emit_insn
5053 (gen_sse2_cvtdq2<ssevecmodesuffix> (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_REG_P (operands[0])
5065 || (GET_CODE (operands[0]) == SUBREG
5066 && SSE_REG_P (operands[0])))"
5067 [(const_int 0)]
5068 {
5069 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5070 <MODE>mode, 0);
5071 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5072
5073 emit_insn (gen_sse2_loadld (operands[4],
5074 CONST0_RTX (V4SImode), operands[1]));
5075 emit_insn
5076 (gen_sse2_cvtdq2<ssevecmodesuffix> (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_REG_P (operands[0])
5087 || (GET_CODE (operands[0]) == SUBREG
5088 && SSE_REG_P (operands[0])))"
5089 [(const_int 0)]
5090 {
5091 rtx op1 = operands[1];
5092
5093 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5094 <MODE>mode, 0);
5095 if (GET_CODE (op1) == SUBREG)
5096 op1 = SUBREG_REG (op1);
5097
5098 if (GENERAL_REG_P (op1))
5099 {
5100 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5101 if (TARGET_INTER_UNIT_MOVES)
5102 emit_insn (gen_sse2_loadld (operands[4],
5103 CONST0_RTX (V4SImode), operands[1]));
5104 else
5105 {
5106 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5107 operands[1]);
5108 emit_insn (gen_sse2_loadld (operands[4],
5109 CONST0_RTX (V4SImode), operands[5]));
5110 ix86_free_from_memory (GET_MODE (operands[1]));
5111 }
5112 }
5113 /* We can ignore possible trapping value in the
5114 high part of SSE register for non-trapping math. */
5115 else if (SSE_REG_P (op1) && !flag_trapping_math)
5116 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5117 else
5118 gcc_unreachable ();
5119 emit_insn
5120 (gen_sse2_cvtdq2<ssevecmodesuffix> (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_REG_P (operands[0])
5131 || (GET_CODE (operands[0]) == SUBREG
5132 && SSE_REG_P (operands[0])))"
5133 [(const_int 0)]
5134 {
5135 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5136 <MODE>mode, 0);
5137 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5138
5139 emit_insn (gen_sse2_loadld (operands[4],
5140 CONST0_RTX (V4SImode), operands[1]));
5141 emit_insn
5142 (gen_sse2_cvtdq2<ssevecmodesuffix> (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_REG_P (operands[0])
5192 || (GET_CODE (operands[0]) == SUBREG
5193 && SSE_REG_P (operands[0])))"
5194 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5195
5196 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5197 [(set (match_operand:MODEF 0 "register_operand" "=x")
5198 (float:MODEF
5199 (match_operand:SWI48x 1 "memory_operand" "m")))]
5200 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5201 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5202 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5203 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5204 [(set_attr "type" "sseicvt")
5205 (set_attr "prefix" "maybe_vex")
5206 (set_attr "mode" "<MODEF:MODE>")
5207 (set (attr "prefix_rex")
5208 (if_then_else
5209 (and (eq_attr "prefix" "maybe_vex")
5210 (match_test "<SWI48x:MODE>mode == DImode"))
5211 (const_string "1")
5212 (const_string "*")))
5213 (set_attr "athlon_decode" "direct")
5214 (set_attr "amdfam10_decode" "double")
5215 (set_attr "bdver1_decode" "direct")
5216 (set_attr "fp_int_src" "true")])
5217
5218 (define_split
5219 [(set (match_operand:MODEF 0 "register_operand" "")
5220 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5221 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5222 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5223 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5224 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5225 && reload_completed
5226 && (SSE_REG_P (operands[0])
5227 || (GET_CODE (operands[0]) == SUBREG
5228 && SSE_REG_P (operands[0])))"
5229 [(set (match_dup 2) (match_dup 1))
5230 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5231
5232 (define_split
5233 [(set (match_operand:MODEF 0 "register_operand" "")
5234 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5235 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5236 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5237 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5238 && reload_completed
5239 && (SSE_REG_P (operands[0])
5240 || (GET_CODE (operands[0]) == SUBREG
5241 && SSE_REG_P (operands[0])))"
5242 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5243
5244 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5245 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5246 (float:X87MODEF
5247 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5248 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5249 "TARGET_80387
5250 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5251 "@
5252 fild%Z1\t%1
5253 #"
5254 [(set_attr "type" "fmov,multi")
5255 (set_attr "mode" "<X87MODEF:MODE>")
5256 (set_attr "unit" "*,i387")
5257 (set_attr "fp_int_src" "true")])
5258
5259 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5260 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5261 (float:X87MODEF
5262 (match_operand:SWI48x 1 "memory_operand" "m")))]
5263 "TARGET_80387
5264 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5265 "fild%Z1\t%1"
5266 [(set_attr "type" "fmov")
5267 (set_attr "mode" "<X87MODEF:MODE>")
5268 (set_attr "fp_int_src" "true")])
5269
5270 (define_split
5271 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5272 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5273 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5274 "TARGET_80387
5275 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5276 && reload_completed"
5277 [(set (match_dup 2) (match_dup 1))
5278 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5279
5280 (define_split
5281 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5282 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5283 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5284 "TARGET_80387
5285 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5286 && reload_completed"
5287 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5288
5289 ;; Avoid store forwarding (partial memory) stall penalty
5290 ;; by passing DImode value through XMM registers. */
5291
5292 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5293 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5294 (float:X87MODEF
5295 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5296 (clobber (match_scratch:V4SI 3 "=X,x"))
5297 (clobber (match_scratch:V4SI 4 "=X,x"))
5298 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5299 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5300 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5301 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5302 "#"
5303 [(set_attr "type" "multi")
5304 (set_attr "mode" "<X87MODEF:MODE>")
5305 (set_attr "unit" "i387")
5306 (set_attr "fp_int_src" "true")])
5307
5308 (define_split
5309 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5310 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5311 (clobber (match_scratch:V4SI 3 ""))
5312 (clobber (match_scratch:V4SI 4 ""))
5313 (clobber (match_operand:DI 2 "memory_operand" ""))]
5314 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5315 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5316 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5317 && reload_completed"
5318 [(set (match_dup 2) (match_dup 3))
5319 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5320 {
5321 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5322 Assemble the 64-bit DImode value in an xmm register. */
5323 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5324 gen_rtx_SUBREG (SImode, operands[1], 0)));
5325 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5326 gen_rtx_SUBREG (SImode, operands[1], 4)));
5327 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5328 operands[4]));
5329
5330 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5331 })
5332
5333 (define_split
5334 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5335 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5336 (clobber (match_scratch:V4SI 3 ""))
5337 (clobber (match_scratch:V4SI 4 ""))
5338 (clobber (match_operand:DI 2 "memory_operand" ""))]
5339 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5340 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5341 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5342 && reload_completed"
5343 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5344
5345 ;; Avoid store forwarding (partial memory) stall penalty by extending
5346 ;; SImode value to DImode through XMM register instead of pushing two
5347 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5348 ;; targets benefit from this optimization. Also note that fild
5349 ;; loads from memory only.
5350
5351 (define_insn "*floatunssi<mode>2_1"
5352 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5353 (unsigned_float:X87MODEF
5354 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5355 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5356 (clobber (match_scratch:SI 3 "=X,x"))]
5357 "!TARGET_64BIT
5358 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5359 && TARGET_SSE"
5360 "#"
5361 [(set_attr "type" "multi")
5362 (set_attr "mode" "<MODE>")])
5363
5364 (define_split
5365 [(set (match_operand:X87MODEF 0 "register_operand" "")
5366 (unsigned_float:X87MODEF
5367 (match_operand:SI 1 "register_operand" "")))
5368 (clobber (match_operand:DI 2 "memory_operand" ""))
5369 (clobber (match_scratch:SI 3 ""))]
5370 "!TARGET_64BIT
5371 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5372 && TARGET_SSE
5373 && reload_completed"
5374 [(set (match_dup 2) (match_dup 1))
5375 (set (match_dup 0)
5376 (float:X87MODEF (match_dup 2)))]
5377 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5378
5379 (define_split
5380 [(set (match_operand:X87MODEF 0 "register_operand" "")
5381 (unsigned_float:X87MODEF
5382 (match_operand:SI 1 "memory_operand" "")))
5383 (clobber (match_operand:DI 2 "memory_operand" ""))
5384 (clobber (match_scratch:SI 3 ""))]
5385 "!TARGET_64BIT
5386 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5387 && TARGET_SSE
5388 && reload_completed"
5389 [(set (match_dup 2) (match_dup 3))
5390 (set (match_dup 0)
5391 (float:X87MODEF (match_dup 2)))]
5392 {
5393 emit_move_insn (operands[3], operands[1]);
5394 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5395 })
5396
5397 (define_expand "floatunssi<mode>2"
5398 [(parallel
5399 [(set (match_operand:X87MODEF 0 "register_operand" "")
5400 (unsigned_float:X87MODEF
5401 (match_operand:SI 1 "nonimmediate_operand" "")))
5402 (clobber (match_dup 2))
5403 (clobber (match_scratch:SI 3 ""))])]
5404 "!TARGET_64BIT
5405 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5406 && TARGET_SSE)
5407 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5408 {
5409 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5410 {
5411 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5412 DONE;
5413 }
5414 else
5415 {
5416 enum ix86_stack_slot slot = (virtuals_instantiated
5417 ? SLOT_TEMP
5418 : SLOT_VIRTUAL);
5419 operands[2] = assign_386_stack_local (DImode, slot);
5420 }
5421 })
5422
5423 (define_expand "floatunsdisf2"
5424 [(use (match_operand:SF 0 "register_operand" ""))
5425 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5426 "TARGET_64BIT && TARGET_SSE_MATH"
5427 "x86_emit_floatuns (operands); DONE;")
5428
5429 (define_expand "floatunsdidf2"
5430 [(use (match_operand:DF 0 "register_operand" ""))
5431 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5432 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5433 && TARGET_SSE2 && TARGET_SSE_MATH"
5434 {
5435 if (TARGET_64BIT)
5436 x86_emit_floatuns (operands);
5437 else
5438 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5439 DONE;
5440 })
5441 \f
5442 ;; Add instructions
5443
5444 (define_expand "add<mode>3"
5445 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5446 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5447 (match_operand:SDWIM 2 "<general_operand>" "")))]
5448 ""
5449 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5450
5451 (define_insn_and_split "*add<dwi>3_doubleword"
5452 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5453 (plus:<DWI>
5454 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5455 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5456 (clobber (reg:CC FLAGS_REG))]
5457 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5458 "#"
5459 "reload_completed"
5460 [(parallel [(set (reg:CC FLAGS_REG)
5461 (unspec:CC [(match_dup 1) (match_dup 2)]
5462 UNSPEC_ADD_CARRY))
5463 (set (match_dup 0)
5464 (plus:DWIH (match_dup 1) (match_dup 2)))])
5465 (parallel [(set (match_dup 3)
5466 (plus:DWIH
5467 (match_dup 4)
5468 (plus:DWIH
5469 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5470 (match_dup 5))))
5471 (clobber (reg:CC FLAGS_REG))])]
5472 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5473
5474 (define_insn "*add<mode>3_cc"
5475 [(set (reg:CC FLAGS_REG)
5476 (unspec:CC
5477 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5478 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5479 UNSPEC_ADD_CARRY))
5480 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5481 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5482 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5483 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5484 [(set_attr "type" "alu")
5485 (set_attr "mode" "<MODE>")])
5486
5487 (define_insn "addqi3_cc"
5488 [(set (reg:CC FLAGS_REG)
5489 (unspec:CC
5490 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5491 (match_operand:QI 2 "general_operand" "qn,qm")]
5492 UNSPEC_ADD_CARRY))
5493 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5494 (plus:QI (match_dup 1) (match_dup 2)))]
5495 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5496 "add{b}\t{%2, %0|%0, %2}"
5497 [(set_attr "type" "alu")
5498 (set_attr "mode" "QI")])
5499
5500 (define_insn_and_split "*lea_1"
5501 [(set (match_operand:SI 0 "register_operand" "=r")
5502 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5503 "TARGET_64BIT"
5504 "lea{l}\t{%a1, %0|%0, %a1}"
5505 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5506 [(const_int 0)]
5507 {
5508 ix86_split_lea_for_addr (operands, SImode);
5509 DONE;
5510 }
5511 [(set_attr "type" "lea")
5512 (set_attr "mode" "SI")])
5513
5514 (define_insn_and_split "*lea<mode>_2"
5515 [(set (match_operand:SWI48 0 "register_operand" "=r")
5516 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5517 ""
5518 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5519 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5520 [(const_int 0)]
5521 {
5522 ix86_split_lea_for_addr (operands, <MODE>mode);
5523 DONE;
5524 }
5525 [(set_attr "type" "lea")
5526 (set_attr "mode" "<MODE>")])
5527
5528 (define_insn "*lea_3_zext"
5529 [(set (match_operand:DI 0 "register_operand" "=r")
5530 (zero_extend:DI
5531 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
5532 "TARGET_64BIT"
5533 "lea{l}\t{%a1, %k0|%k0, %a1}"
5534 [(set_attr "type" "lea")
5535 (set_attr "mode" "SI")])
5536
5537 (define_insn "*lea_4_zext"
5538 [(set (match_operand:DI 0 "register_operand" "=r")
5539 (zero_extend:DI
5540 (match_operand:SI 1 "lea_address_operand" "p")))]
5541 "TARGET_64BIT"
5542 "lea{l}\t{%a1, %k0|%k0, %a1}"
5543 [(set_attr "type" "lea")
5544 (set_attr "mode" "SI")])
5545
5546 (define_insn "*lea_5_zext"
5547 [(set (match_operand:DI 0 "register_operand" "=r")
5548 (and:DI
5549 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5550 (match_operand:DI 2 "const_32bit_mask" "n")))]
5551 "TARGET_64BIT"
5552 "lea{l}\t{%a1, %k0|%k0, %a1}"
5553 [(set_attr "type" "lea")
5554 (set_attr "mode" "SI")])
5555
5556 (define_insn "*lea_6_zext"
5557 [(set (match_operand:DI 0 "register_operand" "=r")
5558 (and:DI
5559 (match_operand:DI 1 "lea_address_operand" "p")
5560 (match_operand:DI 2 "const_32bit_mask" "n")))]
5561 "TARGET_64BIT"
5562 "lea{l}\t{%a1, %k0|%k0, %a1}"
5563 [(set_attr "type" "lea")
5564 (set_attr "mode" "SI")])
5565
5566 (define_insn "*add<mode>_1"
5567 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5568 (plus:SWI48
5569 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5570 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5571 (clobber (reg:CC FLAGS_REG))]
5572 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5573 {
5574 switch (get_attr_type (insn))
5575 {
5576 case TYPE_LEA:
5577 return "#";
5578
5579 case TYPE_INCDEC:
5580 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5581 if (operands[2] == const1_rtx)
5582 return "inc{<imodesuffix>}\t%0";
5583 else
5584 {
5585 gcc_assert (operands[2] == constm1_rtx);
5586 return "dec{<imodesuffix>}\t%0";
5587 }
5588
5589 default:
5590 /* For most processors, ADD is faster than LEA. This alternative
5591 was added to use ADD as much as possible. */
5592 if (which_alternative == 2)
5593 {
5594 rtx tmp;
5595 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5596 }
5597
5598 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5600 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5601
5602 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5603 }
5604 }
5605 [(set (attr "type")
5606 (cond [(eq_attr "alternative" "3")
5607 (const_string "lea")
5608 (match_operand:SWI48 2 "incdec_operand" "")
5609 (const_string "incdec")
5610 ]
5611 (const_string "alu")))
5612 (set (attr "length_immediate")
5613 (if_then_else
5614 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5615 (const_string "1")
5616 (const_string "*")))
5617 (set_attr "mode" "<MODE>")])
5618
5619 ;; It may seem that nonimmediate operand is proper one for operand 1.
5620 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5621 ;; we take care in ix86_binary_operator_ok to not allow two memory
5622 ;; operands so proper swapping will be done in reload. This allow
5623 ;; patterns constructed from addsi_1 to match.
5624
5625 (define_insn "addsi_1_zext"
5626 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5627 (zero_extend:DI
5628 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5629 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5630 (clobber (reg:CC FLAGS_REG))]
5631 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5632 {
5633 switch (get_attr_type (insn))
5634 {
5635 case TYPE_LEA:
5636 return "#";
5637
5638 case TYPE_INCDEC:
5639 if (operands[2] == const1_rtx)
5640 return "inc{l}\t%k0";
5641 else
5642 {
5643 gcc_assert (operands[2] == constm1_rtx);
5644 return "dec{l}\t%k0";
5645 }
5646
5647 default:
5648 /* For most processors, ADD is faster than LEA. This alternative
5649 was added to use ADD as much as possible. */
5650 if (which_alternative == 1)
5651 {
5652 rtx tmp;
5653 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5654 }
5655
5656 if (x86_maybe_negate_const_int (&operands[2], SImode))
5657 return "sub{l}\t{%2, %k0|%k0, %2}";
5658
5659 return "add{l}\t{%2, %k0|%k0, %2}";
5660 }
5661 }
5662 [(set (attr "type")
5663 (cond [(eq_attr "alternative" "2")
5664 (const_string "lea")
5665 (match_operand:SI 2 "incdec_operand" "")
5666 (const_string "incdec")
5667 ]
5668 (const_string "alu")))
5669 (set (attr "length_immediate")
5670 (if_then_else
5671 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5672 (const_string "1")
5673 (const_string "*")))
5674 (set_attr "mode" "SI")])
5675
5676 (define_insn "*addhi_1"
5677 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5678 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5679 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5680 (clobber (reg:CC FLAGS_REG))]
5681 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5682 {
5683 switch (get_attr_type (insn))
5684 {
5685 case TYPE_LEA:
5686 return "#";
5687
5688 case TYPE_INCDEC:
5689 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5690 if (operands[2] == const1_rtx)
5691 return "inc{w}\t%0";
5692 else
5693 {
5694 gcc_assert (operands[2] == constm1_rtx);
5695 return "dec{w}\t%0";
5696 }
5697
5698 default:
5699 /* For most processors, ADD is faster than LEA. This alternative
5700 was added to use ADD as much as possible. */
5701 if (which_alternative == 2)
5702 {
5703 rtx tmp;
5704 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5705 }
5706
5707 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5708 if (x86_maybe_negate_const_int (&operands[2], HImode))
5709 return "sub{w}\t{%2, %0|%0, %2}";
5710
5711 return "add{w}\t{%2, %0|%0, %2}";
5712 }
5713 }
5714 [(set (attr "type")
5715 (cond [(eq_attr "alternative" "3")
5716 (const_string "lea")
5717 (match_operand:HI 2 "incdec_operand" "")
5718 (const_string "incdec")
5719 ]
5720 (const_string "alu")))
5721 (set (attr "length_immediate")
5722 (if_then_else
5723 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5724 (const_string "1")
5725 (const_string "*")))
5726 (set_attr "mode" "HI,HI,HI,SI")])
5727
5728 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5729 (define_insn "*addqi_1"
5730 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5731 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5732 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5733 (clobber (reg:CC FLAGS_REG))]
5734 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5735 {
5736 bool widen = (which_alternative == 3 || which_alternative == 4);
5737
5738 switch (get_attr_type (insn))
5739 {
5740 case TYPE_LEA:
5741 return "#";
5742
5743 case TYPE_INCDEC:
5744 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5745 if (operands[2] == const1_rtx)
5746 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5747 else
5748 {
5749 gcc_assert (operands[2] == constm1_rtx);
5750 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5751 }
5752
5753 default:
5754 /* For most processors, ADD is faster than LEA. These alternatives
5755 were added to use ADD as much as possible. */
5756 if (which_alternative == 2 || which_alternative == 4)
5757 {
5758 rtx tmp;
5759 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5760 }
5761
5762 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5763 if (x86_maybe_negate_const_int (&operands[2], QImode))
5764 {
5765 if (widen)
5766 return "sub{l}\t{%2, %k0|%k0, %2}";
5767 else
5768 return "sub{b}\t{%2, %0|%0, %2}";
5769 }
5770 if (widen)
5771 return "add{l}\t{%k2, %k0|%k0, %k2}";
5772 else
5773 return "add{b}\t{%2, %0|%0, %2}";
5774 }
5775 }
5776 [(set (attr "type")
5777 (cond [(eq_attr "alternative" "5")
5778 (const_string "lea")
5779 (match_operand:QI 2 "incdec_operand" "")
5780 (const_string "incdec")
5781 ]
5782 (const_string "alu")))
5783 (set (attr "length_immediate")
5784 (if_then_else
5785 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5786 (const_string "1")
5787 (const_string "*")))
5788 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5789
5790 (define_insn "*addqi_1_slp"
5791 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5792 (plus:QI (match_dup 0)
5793 (match_operand:QI 1 "general_operand" "qn,qm")))
5794 (clobber (reg:CC FLAGS_REG))]
5795 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5796 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5797 {
5798 switch (get_attr_type (insn))
5799 {
5800 case TYPE_INCDEC:
5801 if (operands[1] == const1_rtx)
5802 return "inc{b}\t%0";
5803 else
5804 {
5805 gcc_assert (operands[1] == constm1_rtx);
5806 return "dec{b}\t%0";
5807 }
5808
5809 default:
5810 if (x86_maybe_negate_const_int (&operands[1], QImode))
5811 return "sub{b}\t{%1, %0|%0, %1}";
5812
5813 return "add{b}\t{%1, %0|%0, %1}";
5814 }
5815 }
5816 [(set (attr "type")
5817 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5818 (const_string "incdec")
5819 (const_string "alu1")))
5820 (set (attr "memory")
5821 (if_then_else (match_operand 1 "memory_operand" "")
5822 (const_string "load")
5823 (const_string "none")))
5824 (set_attr "mode" "QI")])
5825
5826 ;; Split non destructive adds if we cannot use lea.
5827 (define_split
5828 [(set (match_operand:SWI48 0 "register_operand" "")
5829 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5830 (match_operand:SWI48 2 "nonmemory_operand" "")))
5831 (clobber (reg:CC FLAGS_REG))]
5832 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5833 [(set (match_dup 0) (match_dup 1))
5834 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5835 (clobber (reg:CC FLAGS_REG))])])
5836
5837 ;; Convert add to the lea pattern to avoid flags dependency.
5838 (define_split
5839 [(set (match_operand:SWI 0 "register_operand" "")
5840 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5841 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5842 (clobber (reg:CC FLAGS_REG))]
5843 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5844 [(const_int 0)]
5845 {
5846 enum machine_mode mode = <MODE>mode;
5847 rtx pat;
5848
5849 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5850 {
5851 mode = SImode;
5852 operands[0] = gen_lowpart (mode, operands[0]);
5853 operands[1] = gen_lowpart (mode, operands[1]);
5854 operands[2] = gen_lowpart (mode, operands[2]);
5855 }
5856
5857 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5858
5859 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5860 DONE;
5861 })
5862
5863 ;; Convert add to the lea pattern to avoid flags dependency.
5864 (define_split
5865 [(set (match_operand:DI 0 "register_operand" "")
5866 (zero_extend:DI
5867 (plus:SI (match_operand:SI 1 "register_operand" "")
5868 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5869 (clobber (reg:CC FLAGS_REG))]
5870 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5871 [(set (match_dup 0)
5872 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5873
5874 (define_insn "*add<mode>_2"
5875 [(set (reg FLAGS_REG)
5876 (compare
5877 (plus:SWI
5878 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5879 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5880 (const_int 0)))
5881 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5882 (plus:SWI (match_dup 1) (match_dup 2)))]
5883 "ix86_match_ccmode (insn, CCGOCmode)
5884 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5885 {
5886 switch (get_attr_type (insn))
5887 {
5888 case TYPE_INCDEC:
5889 if (operands[2] == const1_rtx)
5890 return "inc{<imodesuffix>}\t%0";
5891 else
5892 {
5893 gcc_assert (operands[2] == constm1_rtx);
5894 return "dec{<imodesuffix>}\t%0";
5895 }
5896
5897 default:
5898 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5899 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5900
5901 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5902 }
5903 }
5904 [(set (attr "type")
5905 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5906 (const_string "incdec")
5907 (const_string "alu")))
5908 (set (attr "length_immediate")
5909 (if_then_else
5910 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5911 (const_string "1")
5912 (const_string "*")))
5913 (set_attr "mode" "<MODE>")])
5914
5915 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5916 (define_insn "*addsi_2_zext"
5917 [(set (reg FLAGS_REG)
5918 (compare
5919 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5920 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5921 (const_int 0)))
5922 (set (match_operand:DI 0 "register_operand" "=r")
5923 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5924 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5925 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5926 {
5927 switch (get_attr_type (insn))
5928 {
5929 case TYPE_INCDEC:
5930 if (operands[2] == const1_rtx)
5931 return "inc{l}\t%k0";
5932 else
5933 {
5934 gcc_assert (operands[2] == constm1_rtx);
5935 return "dec{l}\t%k0";
5936 }
5937
5938 default:
5939 if (x86_maybe_negate_const_int (&operands[2], SImode))
5940 return "sub{l}\t{%2, %k0|%k0, %2}";
5941
5942 return "add{l}\t{%2, %k0|%k0, %2}";
5943 }
5944 }
5945 [(set (attr "type")
5946 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5947 (const_string "incdec")
5948 (const_string "alu")))
5949 (set (attr "length_immediate")
5950 (if_then_else
5951 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5952 (const_string "1")
5953 (const_string "*")))
5954 (set_attr "mode" "SI")])
5955
5956 (define_insn "*add<mode>_3"
5957 [(set (reg FLAGS_REG)
5958 (compare
5959 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5960 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5961 (clobber (match_scratch:SWI 0 "=<r>"))]
5962 "ix86_match_ccmode (insn, CCZmode)
5963 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5964 {
5965 switch (get_attr_type (insn))
5966 {
5967 case TYPE_INCDEC:
5968 if (operands[2] == const1_rtx)
5969 return "inc{<imodesuffix>}\t%0";
5970 else
5971 {
5972 gcc_assert (operands[2] == constm1_rtx);
5973 return "dec{<imodesuffix>}\t%0";
5974 }
5975
5976 default:
5977 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5978 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5979
5980 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5981 }
5982 }
5983 [(set (attr "type")
5984 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5985 (const_string "incdec")
5986 (const_string "alu")))
5987 (set (attr "length_immediate")
5988 (if_then_else
5989 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5990 (const_string "1")
5991 (const_string "*")))
5992 (set_attr "mode" "<MODE>")])
5993
5994 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5995 (define_insn "*addsi_3_zext"
5996 [(set (reg FLAGS_REG)
5997 (compare
5998 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5999 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6000 (set (match_operand:DI 0 "register_operand" "=r")
6001 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6002 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6003 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6004 {
6005 switch (get_attr_type (insn))
6006 {
6007 case TYPE_INCDEC:
6008 if (operands[2] == const1_rtx)
6009 return "inc{l}\t%k0";
6010 else
6011 {
6012 gcc_assert (operands[2] == constm1_rtx);
6013 return "dec{l}\t%k0";
6014 }
6015
6016 default:
6017 if (x86_maybe_negate_const_int (&operands[2], SImode))
6018 return "sub{l}\t{%2, %k0|%k0, %2}";
6019
6020 return "add{l}\t{%2, %k0|%k0, %2}";
6021 }
6022 }
6023 [(set (attr "type")
6024 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6025 (const_string "incdec")
6026 (const_string "alu")))
6027 (set (attr "length_immediate")
6028 (if_then_else
6029 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6030 (const_string "1")
6031 (const_string "*")))
6032 (set_attr "mode" "SI")])
6033
6034 ; For comparisons against 1, -1 and 128, we may generate better code
6035 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6036 ; is matched then. We can't accept general immediate, because for
6037 ; case of overflows, the result is messed up.
6038 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6039 ; only for comparisons not depending on it.
6040
6041 (define_insn "*adddi_4"
6042 [(set (reg FLAGS_REG)
6043 (compare
6044 (match_operand:DI 1 "nonimmediate_operand" "0")
6045 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6046 (clobber (match_scratch:DI 0 "=rm"))]
6047 "TARGET_64BIT
6048 && ix86_match_ccmode (insn, CCGCmode)"
6049 {
6050 switch (get_attr_type (insn))
6051 {
6052 case TYPE_INCDEC:
6053 if (operands[2] == constm1_rtx)
6054 return "inc{q}\t%0";
6055 else
6056 {
6057 gcc_assert (operands[2] == const1_rtx);
6058 return "dec{q}\t%0";
6059 }
6060
6061 default:
6062 if (x86_maybe_negate_const_int (&operands[2], DImode))
6063 return "add{q}\t{%2, %0|%0, %2}";
6064
6065 return "sub{q}\t{%2, %0|%0, %2}";
6066 }
6067 }
6068 [(set (attr "type")
6069 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6070 (const_string "incdec")
6071 (const_string "alu")))
6072 (set (attr "length_immediate")
6073 (if_then_else
6074 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6075 (const_string "1")
6076 (const_string "*")))
6077 (set_attr "mode" "DI")])
6078
6079 ; For comparisons against 1, -1 and 128, we may generate better code
6080 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6081 ; is matched then. We can't accept general immediate, because for
6082 ; case of overflows, the result is messed up.
6083 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6084 ; only for comparisons not depending on it.
6085
6086 (define_insn "*add<mode>_4"
6087 [(set (reg FLAGS_REG)
6088 (compare
6089 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6090 (match_operand:SWI124 2 "const_int_operand" "n")))
6091 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6092 "ix86_match_ccmode (insn, CCGCmode)"
6093 {
6094 switch (get_attr_type (insn))
6095 {
6096 case TYPE_INCDEC:
6097 if (operands[2] == constm1_rtx)
6098 return "inc{<imodesuffix>}\t%0";
6099 else
6100 {
6101 gcc_assert (operands[2] == const1_rtx);
6102 return "dec{<imodesuffix>}\t%0";
6103 }
6104
6105 default:
6106 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6107 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6108
6109 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6110 }
6111 }
6112 [(set (attr "type")
6113 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6114 (const_string "incdec")
6115 (const_string "alu")))
6116 (set (attr "length_immediate")
6117 (if_then_else
6118 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6119 (const_string "1")
6120 (const_string "*")))
6121 (set_attr "mode" "<MODE>")])
6122
6123 (define_insn "*add<mode>_5"
6124 [(set (reg FLAGS_REG)
6125 (compare
6126 (plus:SWI
6127 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6128 (match_operand:SWI 2 "<general_operand>" "<g>"))
6129 (const_int 0)))
6130 (clobber (match_scratch:SWI 0 "=<r>"))]
6131 "ix86_match_ccmode (insn, CCGOCmode)
6132 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6133 {
6134 switch (get_attr_type (insn))
6135 {
6136 case TYPE_INCDEC:
6137 if (operands[2] == const1_rtx)
6138 return "inc{<imodesuffix>}\t%0";
6139 else
6140 {
6141 gcc_assert (operands[2] == constm1_rtx);
6142 return "dec{<imodesuffix>}\t%0";
6143 }
6144
6145 default:
6146 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6147 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6148
6149 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6150 }
6151 }
6152 [(set (attr "type")
6153 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6154 (const_string "incdec")
6155 (const_string "alu")))
6156 (set (attr "length_immediate")
6157 (if_then_else
6158 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6159 (const_string "1")
6160 (const_string "*")))
6161 (set_attr "mode" "<MODE>")])
6162
6163 (define_insn "*addqi_ext_1_rex64"
6164 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6165 (const_int 8)
6166 (const_int 8))
6167 (plus:SI
6168 (zero_extract:SI
6169 (match_operand 1 "ext_register_operand" "0")
6170 (const_int 8)
6171 (const_int 8))
6172 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6173 (clobber (reg:CC FLAGS_REG))]
6174 "TARGET_64BIT"
6175 {
6176 switch (get_attr_type (insn))
6177 {
6178 case TYPE_INCDEC:
6179 if (operands[2] == const1_rtx)
6180 return "inc{b}\t%h0";
6181 else
6182 {
6183 gcc_assert (operands[2] == constm1_rtx);
6184 return "dec{b}\t%h0";
6185 }
6186
6187 default:
6188 return "add{b}\t{%2, %h0|%h0, %2}";
6189 }
6190 }
6191 [(set (attr "type")
6192 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6193 (const_string "incdec")
6194 (const_string "alu")))
6195 (set_attr "modrm" "1")
6196 (set_attr "mode" "QI")])
6197
6198 (define_insn "addqi_ext_1"
6199 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6200 (const_int 8)
6201 (const_int 8))
6202 (plus:SI
6203 (zero_extract:SI
6204 (match_operand 1 "ext_register_operand" "0")
6205 (const_int 8)
6206 (const_int 8))
6207 (match_operand:QI 2 "general_operand" "Qmn")))
6208 (clobber (reg:CC FLAGS_REG))]
6209 "!TARGET_64BIT"
6210 {
6211 switch (get_attr_type (insn))
6212 {
6213 case TYPE_INCDEC:
6214 if (operands[2] == const1_rtx)
6215 return "inc{b}\t%h0";
6216 else
6217 {
6218 gcc_assert (operands[2] == constm1_rtx);
6219 return "dec{b}\t%h0";
6220 }
6221
6222 default:
6223 return "add{b}\t{%2, %h0|%h0, %2}";
6224 }
6225 }
6226 [(set (attr "type")
6227 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6228 (const_string "incdec")
6229 (const_string "alu")))
6230 (set_attr "modrm" "1")
6231 (set_attr "mode" "QI")])
6232
6233 (define_insn "*addqi_ext_2"
6234 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6235 (const_int 8)
6236 (const_int 8))
6237 (plus:SI
6238 (zero_extract:SI
6239 (match_operand 1 "ext_register_operand" "%0")
6240 (const_int 8)
6241 (const_int 8))
6242 (zero_extract:SI
6243 (match_operand 2 "ext_register_operand" "Q")
6244 (const_int 8)
6245 (const_int 8))))
6246 (clobber (reg:CC FLAGS_REG))]
6247 ""
6248 "add{b}\t{%h2, %h0|%h0, %h2}"
6249 [(set_attr "type" "alu")
6250 (set_attr "mode" "QI")])
6251
6252 ;; The lea patterns for modes less than 32 bits need to be matched by
6253 ;; several insns converted to real lea by splitters.
6254
6255 (define_insn_and_split "*lea_general_1"
6256 [(set (match_operand 0 "register_operand" "=r")
6257 (plus (plus (match_operand 1 "index_register_operand" "l")
6258 (match_operand 2 "register_operand" "r"))
6259 (match_operand 3 "immediate_operand" "i")))]
6260 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6261 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6262 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6263 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6264 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6265 || GET_MODE (operands[3]) == VOIDmode)"
6266 "#"
6267 "&& reload_completed"
6268 [(const_int 0)]
6269 {
6270 enum machine_mode mode = SImode;
6271 rtx pat;
6272
6273 operands[0] = gen_lowpart (mode, operands[0]);
6274 operands[1] = gen_lowpart (mode, operands[1]);
6275 operands[2] = gen_lowpart (mode, operands[2]);
6276 operands[3] = gen_lowpart (mode, operands[3]);
6277
6278 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6279 operands[3]);
6280
6281 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6282 DONE;
6283 }
6284 [(set_attr "type" "lea")
6285 (set_attr "mode" "SI")])
6286
6287 (define_insn_and_split "*lea_general_2"
6288 [(set (match_operand 0 "register_operand" "=r")
6289 (plus (mult (match_operand 1 "index_register_operand" "l")
6290 (match_operand 2 "const248_operand" "n"))
6291 (match_operand 3 "nonmemory_operand" "ri")))]
6292 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6293 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6294 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6295 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6296 || GET_MODE (operands[3]) == VOIDmode)"
6297 "#"
6298 "&& reload_completed"
6299 [(const_int 0)]
6300 {
6301 enum machine_mode mode = SImode;
6302 rtx pat;
6303
6304 operands[0] = gen_lowpart (mode, operands[0]);
6305 operands[1] = gen_lowpart (mode, operands[1]);
6306 operands[3] = gen_lowpart (mode, operands[3]);
6307
6308 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6309 operands[3]);
6310
6311 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6312 DONE;
6313 }
6314 [(set_attr "type" "lea")
6315 (set_attr "mode" "SI")])
6316
6317 (define_insn_and_split "*lea_general_3"
6318 [(set (match_operand 0 "register_operand" "=r")
6319 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6320 (match_operand 2 "const248_operand" "n"))
6321 (match_operand 3 "register_operand" "r"))
6322 (match_operand 4 "immediate_operand" "i")))]
6323 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6324 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6325 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6326 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6327 "#"
6328 "&& reload_completed"
6329 [(const_int 0)]
6330 {
6331 enum machine_mode mode = SImode;
6332 rtx pat;
6333
6334 operands[0] = gen_lowpart (mode, operands[0]);
6335 operands[1] = gen_lowpart (mode, operands[1]);
6336 operands[3] = gen_lowpart (mode, operands[3]);
6337 operands[4] = gen_lowpart (mode, operands[4]);
6338
6339 pat = gen_rtx_PLUS (mode,
6340 gen_rtx_PLUS (mode,
6341 gen_rtx_MULT (mode, operands[1],
6342 operands[2]),
6343 operands[3]),
6344 operands[4]);
6345
6346 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6347 DONE;
6348 }
6349 [(set_attr "type" "lea")
6350 (set_attr "mode" "SI")])
6351
6352 (define_insn_and_split "*lea_general_4"
6353 [(set (match_operand 0 "register_operand" "=r")
6354 (any_or (ashift
6355 (match_operand 1 "index_register_operand" "l")
6356 (match_operand 2 "const_int_operand" "n"))
6357 (match_operand 3 "const_int_operand" "n")))]
6358 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6359 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6360 || GET_MODE (operands[0]) == SImode
6361 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6362 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6363 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6364 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6365 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6366 "#"
6367 "&& reload_completed"
6368 [(const_int 0)]
6369 {
6370 enum machine_mode mode = GET_MODE (operands[0]);
6371 rtx pat;
6372
6373 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6374 {
6375 mode = SImode;
6376 operands[0] = gen_lowpart (mode, operands[0]);
6377 operands[1] = gen_lowpart (mode, operands[1]);
6378 }
6379
6380 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6381
6382 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6383 INTVAL (operands[3]));
6384
6385 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6386 DONE;
6387 }
6388 [(set_attr "type" "lea")
6389 (set (attr "mode")
6390 (if_then_else (match_operand:DI 0 "" "")
6391 (const_string "DI")
6392 (const_string "SI")))])
6393 \f
6394 ;; Subtract instructions
6395
6396 (define_expand "sub<mode>3"
6397 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6398 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6399 (match_operand:SDWIM 2 "<general_operand>" "")))]
6400 ""
6401 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6402
6403 (define_insn_and_split "*sub<dwi>3_doubleword"
6404 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6405 (minus:<DWI>
6406 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6407 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6408 (clobber (reg:CC FLAGS_REG))]
6409 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6410 "#"
6411 "reload_completed"
6412 [(parallel [(set (reg:CC FLAGS_REG)
6413 (compare:CC (match_dup 1) (match_dup 2)))
6414 (set (match_dup 0)
6415 (minus:DWIH (match_dup 1) (match_dup 2)))])
6416 (parallel [(set (match_dup 3)
6417 (minus:DWIH
6418 (match_dup 4)
6419 (plus:DWIH
6420 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6421 (match_dup 5))))
6422 (clobber (reg:CC FLAGS_REG))])]
6423 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6424
6425 (define_insn "*sub<mode>_1"
6426 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6427 (minus:SWI
6428 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6429 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6430 (clobber (reg:CC FLAGS_REG))]
6431 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6432 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6433 [(set_attr "type" "alu")
6434 (set_attr "mode" "<MODE>")])
6435
6436 (define_insn "*subsi_1_zext"
6437 [(set (match_operand:DI 0 "register_operand" "=r")
6438 (zero_extend:DI
6439 (minus:SI (match_operand:SI 1 "register_operand" "0")
6440 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6441 (clobber (reg:CC FLAGS_REG))]
6442 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6443 "sub{l}\t{%2, %k0|%k0, %2}"
6444 [(set_attr "type" "alu")
6445 (set_attr "mode" "SI")])
6446
6447 (define_insn "*subqi_1_slp"
6448 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6449 (minus:QI (match_dup 0)
6450 (match_operand:QI 1 "general_operand" "qn,qm")))
6451 (clobber (reg:CC FLAGS_REG))]
6452 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6453 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6454 "sub{b}\t{%1, %0|%0, %1}"
6455 [(set_attr "type" "alu1")
6456 (set_attr "mode" "QI")])
6457
6458 (define_insn "*sub<mode>_2"
6459 [(set (reg FLAGS_REG)
6460 (compare
6461 (minus:SWI
6462 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6463 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6464 (const_int 0)))
6465 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6466 (minus:SWI (match_dup 1) (match_dup 2)))]
6467 "ix86_match_ccmode (insn, CCGOCmode)
6468 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6469 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6470 [(set_attr "type" "alu")
6471 (set_attr "mode" "<MODE>")])
6472
6473 (define_insn "*subsi_2_zext"
6474 [(set (reg FLAGS_REG)
6475 (compare
6476 (minus:SI (match_operand:SI 1 "register_operand" "0")
6477 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6478 (const_int 0)))
6479 (set (match_operand:DI 0 "register_operand" "=r")
6480 (zero_extend:DI
6481 (minus:SI (match_dup 1)
6482 (match_dup 2))))]
6483 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6484 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6485 "sub{l}\t{%2, %k0|%k0, %2}"
6486 [(set_attr "type" "alu")
6487 (set_attr "mode" "SI")])
6488
6489 (define_insn "*sub<mode>_3"
6490 [(set (reg FLAGS_REG)
6491 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6492 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6493 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6494 (minus:SWI (match_dup 1) (match_dup 2)))]
6495 "ix86_match_ccmode (insn, CCmode)
6496 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6497 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6498 [(set_attr "type" "alu")
6499 (set_attr "mode" "<MODE>")])
6500
6501 (define_insn "*subsi_3_zext"
6502 [(set (reg FLAGS_REG)
6503 (compare (match_operand:SI 1 "register_operand" "0")
6504 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6505 (set (match_operand:DI 0 "register_operand" "=r")
6506 (zero_extend:DI
6507 (minus:SI (match_dup 1)
6508 (match_dup 2))))]
6509 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6510 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6511 "sub{l}\t{%2, %1|%1, %2}"
6512 [(set_attr "type" "alu")
6513 (set_attr "mode" "SI")])
6514 \f
6515 ;; Add with carry and subtract with borrow
6516
6517 (define_expand "<plusminus_insn><mode>3_carry"
6518 [(parallel
6519 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6520 (plusminus:SWI
6521 (match_operand:SWI 1 "nonimmediate_operand" "")
6522 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6523 [(match_operand 3 "flags_reg_operand" "")
6524 (const_int 0)])
6525 (match_operand:SWI 2 "<general_operand>" ""))))
6526 (clobber (reg:CC FLAGS_REG))])]
6527 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6528
6529 (define_insn "*<plusminus_insn><mode>3_carry"
6530 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6531 (plusminus:SWI
6532 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6533 (plus:SWI
6534 (match_operator 3 "ix86_carry_flag_operator"
6535 [(reg FLAGS_REG) (const_int 0)])
6536 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6537 (clobber (reg:CC FLAGS_REG))]
6538 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6539 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6540 [(set_attr "type" "alu")
6541 (set_attr "use_carry" "1")
6542 (set_attr "pent_pair" "pu")
6543 (set_attr "mode" "<MODE>")])
6544
6545 (define_insn "*addsi3_carry_zext"
6546 [(set (match_operand:DI 0 "register_operand" "=r")
6547 (zero_extend:DI
6548 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6549 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6550 [(reg FLAGS_REG) (const_int 0)])
6551 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6552 (clobber (reg:CC FLAGS_REG))]
6553 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6554 "adc{l}\t{%2, %k0|%k0, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "use_carry" "1")
6557 (set_attr "pent_pair" "pu")
6558 (set_attr "mode" "SI")])
6559
6560 (define_insn "*subsi3_carry_zext"
6561 [(set (match_operand:DI 0 "register_operand" "=r")
6562 (zero_extend:DI
6563 (minus:SI (match_operand:SI 1 "register_operand" "0")
6564 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6565 [(reg FLAGS_REG) (const_int 0)])
6566 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6567 (clobber (reg:CC FLAGS_REG))]
6568 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6569 "sbb{l}\t{%2, %k0|%k0, %2}"
6570 [(set_attr "type" "alu")
6571 (set_attr "pent_pair" "pu")
6572 (set_attr "mode" "SI")])
6573 \f
6574 ;; Overflow setting add and subtract instructions
6575
6576 (define_insn "*add<mode>3_cconly_overflow"
6577 [(set (reg:CCC FLAGS_REG)
6578 (compare:CCC
6579 (plus:SWI
6580 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6581 (match_operand:SWI 2 "<general_operand>" "<g>"))
6582 (match_dup 1)))
6583 (clobber (match_scratch:SWI 0 "=<r>"))]
6584 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6585 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6586 [(set_attr "type" "alu")
6587 (set_attr "mode" "<MODE>")])
6588
6589 (define_insn "*sub<mode>3_cconly_overflow"
6590 [(set (reg:CCC FLAGS_REG)
6591 (compare:CCC
6592 (minus:SWI
6593 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6594 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6595 (match_dup 0)))]
6596 ""
6597 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6598 [(set_attr "type" "icmp")
6599 (set_attr "mode" "<MODE>")])
6600
6601 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6602 [(set (reg:CCC FLAGS_REG)
6603 (compare:CCC
6604 (plusminus:SWI
6605 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6606 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6607 (match_dup 1)))
6608 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6609 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6610 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6611 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6612 [(set_attr "type" "alu")
6613 (set_attr "mode" "<MODE>")])
6614
6615 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6616 [(set (reg:CCC FLAGS_REG)
6617 (compare:CCC
6618 (plusminus:SI
6619 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6620 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6621 (match_dup 1)))
6622 (set (match_operand:DI 0 "register_operand" "=r")
6623 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6624 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6625 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6626 [(set_attr "type" "alu")
6627 (set_attr "mode" "SI")])
6628
6629 ;; The patterns that match these are at the end of this file.
6630
6631 (define_expand "<plusminus_insn>xf3"
6632 [(set (match_operand:XF 0 "register_operand" "")
6633 (plusminus:XF
6634 (match_operand:XF 1 "register_operand" "")
6635 (match_operand:XF 2 "register_operand" "")))]
6636 "TARGET_80387")
6637
6638 (define_expand "<plusminus_insn><mode>3"
6639 [(set (match_operand:MODEF 0 "register_operand" "")
6640 (plusminus:MODEF
6641 (match_operand:MODEF 1 "register_operand" "")
6642 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6643 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6644 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6645 \f
6646 ;; Multiply instructions
6647
6648 (define_expand "mul<mode>3"
6649 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6650 (mult:SWIM248
6651 (match_operand:SWIM248 1 "register_operand" "")
6652 (match_operand:SWIM248 2 "<general_operand>" "")))
6653 (clobber (reg:CC FLAGS_REG))])])
6654
6655 (define_expand "mulqi3"
6656 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6657 (mult:QI
6658 (match_operand:QI 1 "register_operand" "")
6659 (match_operand:QI 2 "nonimmediate_operand" "")))
6660 (clobber (reg:CC FLAGS_REG))])]
6661 "TARGET_QIMODE_MATH")
6662
6663 ;; On AMDFAM10
6664 ;; IMUL reg32/64, reg32/64, imm8 Direct
6665 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6666 ;; IMUL reg32/64, reg32/64, imm32 Direct
6667 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6668 ;; IMUL reg32/64, reg32/64 Direct
6669 ;; IMUL reg32/64, mem32/64 Direct
6670 ;;
6671 ;; On BDVER1, all above IMULs use DirectPath
6672
6673 (define_insn "*mul<mode>3_1"
6674 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6675 (mult:SWI48
6676 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6677 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6678 (clobber (reg:CC FLAGS_REG))]
6679 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6680 "@
6681 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6682 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6683 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6684 [(set_attr "type" "imul")
6685 (set_attr "prefix_0f" "0,0,1")
6686 (set (attr "athlon_decode")
6687 (cond [(eq_attr "cpu" "athlon")
6688 (const_string "vector")
6689 (eq_attr "alternative" "1")
6690 (const_string "vector")
6691 (and (eq_attr "alternative" "2")
6692 (match_operand 1 "memory_operand" ""))
6693 (const_string "vector")]
6694 (const_string "direct")))
6695 (set (attr "amdfam10_decode")
6696 (cond [(and (eq_attr "alternative" "0,1")
6697 (match_operand 1 "memory_operand" ""))
6698 (const_string "vector")]
6699 (const_string "direct")))
6700 (set_attr "bdver1_decode" "direct")
6701 (set_attr "mode" "<MODE>")])
6702
6703 (define_insn "*mulsi3_1_zext"
6704 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6705 (zero_extend:DI
6706 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6707 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6708 (clobber (reg:CC FLAGS_REG))]
6709 "TARGET_64BIT
6710 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6711 "@
6712 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6713 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6714 imul{l}\t{%2, %k0|%k0, %2}"
6715 [(set_attr "type" "imul")
6716 (set_attr "prefix_0f" "0,0,1")
6717 (set (attr "athlon_decode")
6718 (cond [(eq_attr "cpu" "athlon")
6719 (const_string "vector")
6720 (eq_attr "alternative" "1")
6721 (const_string "vector")
6722 (and (eq_attr "alternative" "2")
6723 (match_operand 1 "memory_operand" ""))
6724 (const_string "vector")]
6725 (const_string "direct")))
6726 (set (attr "amdfam10_decode")
6727 (cond [(and (eq_attr "alternative" "0,1")
6728 (match_operand 1 "memory_operand" ""))
6729 (const_string "vector")]
6730 (const_string "direct")))
6731 (set_attr "bdver1_decode" "direct")
6732 (set_attr "mode" "SI")])
6733
6734 ;; On AMDFAM10
6735 ;; IMUL reg16, reg16, imm8 VectorPath
6736 ;; IMUL reg16, mem16, imm8 VectorPath
6737 ;; IMUL reg16, reg16, imm16 VectorPath
6738 ;; IMUL reg16, mem16, imm16 VectorPath
6739 ;; IMUL reg16, reg16 Direct
6740 ;; IMUL reg16, mem16 Direct
6741 ;;
6742 ;; On BDVER1, all HI MULs use DoublePath
6743
6744 (define_insn "*mulhi3_1"
6745 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6746 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6747 (match_operand:HI 2 "general_operand" "K,n,mr")))
6748 (clobber (reg:CC FLAGS_REG))]
6749 "TARGET_HIMODE_MATH
6750 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6751 "@
6752 imul{w}\t{%2, %1, %0|%0, %1, %2}
6753 imul{w}\t{%2, %1, %0|%0, %1, %2}
6754 imul{w}\t{%2, %0|%0, %2}"
6755 [(set_attr "type" "imul")
6756 (set_attr "prefix_0f" "0,0,1")
6757 (set (attr "athlon_decode")
6758 (cond [(eq_attr "cpu" "athlon")
6759 (const_string "vector")
6760 (eq_attr "alternative" "1,2")
6761 (const_string "vector")]
6762 (const_string "direct")))
6763 (set (attr "amdfam10_decode")
6764 (cond [(eq_attr "alternative" "0,1")
6765 (const_string "vector")]
6766 (const_string "direct")))
6767 (set_attr "bdver1_decode" "double")
6768 (set_attr "mode" "HI")])
6769
6770 ;;On AMDFAM10 and BDVER1
6771 ;; MUL reg8 Direct
6772 ;; MUL mem8 Direct
6773
6774 (define_insn "*mulqi3_1"
6775 [(set (match_operand:QI 0 "register_operand" "=a")
6776 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6777 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6778 (clobber (reg:CC FLAGS_REG))]
6779 "TARGET_QIMODE_MATH
6780 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6781 "mul{b}\t%2"
6782 [(set_attr "type" "imul")
6783 (set_attr "length_immediate" "0")
6784 (set (attr "athlon_decode")
6785 (if_then_else (eq_attr "cpu" "athlon")
6786 (const_string "vector")
6787 (const_string "direct")))
6788 (set_attr "amdfam10_decode" "direct")
6789 (set_attr "bdver1_decode" "direct")
6790 (set_attr "mode" "QI")])
6791
6792 (define_expand "<u>mul<mode><dwi>3"
6793 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6794 (mult:<DWI>
6795 (any_extend:<DWI>
6796 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6797 (any_extend:<DWI>
6798 (match_operand:DWIH 2 "register_operand" ""))))
6799 (clobber (reg:CC FLAGS_REG))])])
6800
6801 (define_expand "<u>mulqihi3"
6802 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6803 (mult:HI
6804 (any_extend:HI
6805 (match_operand:QI 1 "nonimmediate_operand" ""))
6806 (any_extend:HI
6807 (match_operand:QI 2 "register_operand" ""))))
6808 (clobber (reg:CC FLAGS_REG))])]
6809 "TARGET_QIMODE_MATH")
6810
6811 (define_insn "*bmi2_umulditi3_1"
6812 [(set (match_operand:DI 0 "register_operand" "=r")
6813 (mult:DI
6814 (match_operand:DI 2 "nonimmediate_operand" "%d")
6815 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6816 (set (match_operand:DI 1 "register_operand" "=r")
6817 (truncate:DI
6818 (lshiftrt:TI
6819 (mult:TI (zero_extend:TI (match_dup 2))
6820 (zero_extend:TI (match_dup 3)))
6821 (const_int 64))))]
6822 "TARGET_64BIT && TARGET_BMI2
6823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6824 "mulx\t{%3, %0, %1|%1, %0, %3}"
6825 [(set_attr "type" "imulx")
6826 (set_attr "prefix" "vex")
6827 (set_attr "mode" "DI")])
6828
6829 (define_insn "*bmi2_umulsidi3_1"
6830 [(set (match_operand:SI 0 "register_operand" "=r")
6831 (mult:SI
6832 (match_operand:SI 2 "nonimmediate_operand" "%d")
6833 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6834 (set (match_operand:SI 1 "register_operand" "=r")
6835 (truncate:SI
6836 (lshiftrt:DI
6837 (mult:DI (zero_extend:DI (match_dup 2))
6838 (zero_extend:DI (match_dup 3)))
6839 (const_int 32))))]
6840 "!TARGET_64BIT && TARGET_BMI2
6841 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6842 "mulx\t{%3, %0, %1|%1, %0, %3}"
6843 [(set_attr "type" "imulx")
6844 (set_attr "prefix" "vex")
6845 (set_attr "mode" "SI")])
6846
6847 (define_insn "*umul<mode><dwi>3_1"
6848 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6849 (mult:<DWI>
6850 (zero_extend:<DWI>
6851 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6852 (zero_extend:<DWI>
6853 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6854 (clobber (reg:CC FLAGS_REG))]
6855 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856 "@
6857 mul{<imodesuffix>}\t%2
6858 #"
6859 [(set_attr "isa" "*,bmi2")
6860 (set_attr "type" "imul,imulx")
6861 (set_attr "length_immediate" "0,*")
6862 (set (attr "athlon_decode")
6863 (cond [(eq_attr "alternative" "0")
6864 (if_then_else (eq_attr "cpu" "athlon")
6865 (const_string "vector")
6866 (const_string "double"))]
6867 (const_string "*")))
6868 (set_attr "amdfam10_decode" "double,*")
6869 (set_attr "bdver1_decode" "direct,*")
6870 (set_attr "prefix" "orig,vex")
6871 (set_attr "mode" "<MODE>")])
6872
6873 ;; Convert mul to the mulx pattern to avoid flags dependency.
6874 (define_split
6875 [(set (match_operand:<DWI> 0 "register_operand" "")
6876 (mult:<DWI>
6877 (zero_extend:<DWI>
6878 (match_operand:DWIH 1 "register_operand" ""))
6879 (zero_extend:<DWI>
6880 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6881 (clobber (reg:CC FLAGS_REG))]
6882 "TARGET_BMI2 && reload_completed
6883 && true_regnum (operands[1]) == DX_REG"
6884 [(parallel [(set (match_dup 3)
6885 (mult:DWIH (match_dup 1) (match_dup 2)))
6886 (set (match_dup 4)
6887 (truncate:DWIH
6888 (lshiftrt:<DWI>
6889 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6890 (zero_extend:<DWI> (match_dup 2)))
6891 (match_dup 5))))])]
6892 {
6893 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6894
6895 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6896 })
6897
6898 (define_insn "*mul<mode><dwi>3_1"
6899 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6900 (mult:<DWI>
6901 (sign_extend:<DWI>
6902 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6903 (sign_extend:<DWI>
6904 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6905 (clobber (reg:CC FLAGS_REG))]
6906 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6907 "imul{<imodesuffix>}\t%2"
6908 [(set_attr "type" "imul")
6909 (set_attr "length_immediate" "0")
6910 (set (attr "athlon_decode")
6911 (if_then_else (eq_attr "cpu" "athlon")
6912 (const_string "vector")
6913 (const_string "double")))
6914 (set_attr "amdfam10_decode" "double")
6915 (set_attr "bdver1_decode" "direct")
6916 (set_attr "mode" "<MODE>")])
6917
6918 (define_insn "*<u>mulqihi3_1"
6919 [(set (match_operand:HI 0 "register_operand" "=a")
6920 (mult:HI
6921 (any_extend:HI
6922 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6923 (any_extend:HI
6924 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6925 (clobber (reg:CC FLAGS_REG))]
6926 "TARGET_QIMODE_MATH
6927 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6928 "<sgnprefix>mul{b}\t%2"
6929 [(set_attr "type" "imul")
6930 (set_attr "length_immediate" "0")
6931 (set (attr "athlon_decode")
6932 (if_then_else (eq_attr "cpu" "athlon")
6933 (const_string "vector")
6934 (const_string "direct")))
6935 (set_attr "amdfam10_decode" "direct")
6936 (set_attr "bdver1_decode" "direct")
6937 (set_attr "mode" "QI")])
6938
6939 (define_expand "<s>mul<mode>3_highpart"
6940 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6941 (truncate:SWI48
6942 (lshiftrt:<DWI>
6943 (mult:<DWI>
6944 (any_extend:<DWI>
6945 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6946 (any_extend:<DWI>
6947 (match_operand:SWI48 2 "register_operand" "")))
6948 (match_dup 4))))
6949 (clobber (match_scratch:SWI48 3 ""))
6950 (clobber (reg:CC FLAGS_REG))])]
6951 ""
6952 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6953
6954 (define_insn "*<s>muldi3_highpart_1"
6955 [(set (match_operand:DI 0 "register_operand" "=d")
6956 (truncate:DI
6957 (lshiftrt:TI
6958 (mult:TI
6959 (any_extend:TI
6960 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6961 (any_extend:TI
6962 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6963 (const_int 64))))
6964 (clobber (match_scratch:DI 3 "=1"))
6965 (clobber (reg:CC FLAGS_REG))]
6966 "TARGET_64BIT
6967 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6968 "<sgnprefix>mul{q}\t%2"
6969 [(set_attr "type" "imul")
6970 (set_attr "length_immediate" "0")
6971 (set (attr "athlon_decode")
6972 (if_then_else (eq_attr "cpu" "athlon")
6973 (const_string "vector")
6974 (const_string "double")))
6975 (set_attr "amdfam10_decode" "double")
6976 (set_attr "bdver1_decode" "direct")
6977 (set_attr "mode" "DI")])
6978
6979 (define_insn "*<s>mulsi3_highpart_1"
6980 [(set (match_operand:SI 0 "register_operand" "=d")
6981 (truncate:SI
6982 (lshiftrt:DI
6983 (mult:DI
6984 (any_extend:DI
6985 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6986 (any_extend:DI
6987 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6988 (const_int 32))))
6989 (clobber (match_scratch:SI 3 "=1"))
6990 (clobber (reg:CC FLAGS_REG))]
6991 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6992 "<sgnprefix>mul{l}\t%2"
6993 [(set_attr "type" "imul")
6994 (set_attr "length_immediate" "0")
6995 (set (attr "athlon_decode")
6996 (if_then_else (eq_attr "cpu" "athlon")
6997 (const_string "vector")
6998 (const_string "double")))
6999 (set_attr "amdfam10_decode" "double")
7000 (set_attr "bdver1_decode" "direct")
7001 (set_attr "mode" "SI")])
7002
7003 (define_insn "*<s>mulsi3_highpart_zext"
7004 [(set (match_operand:DI 0 "register_operand" "=d")
7005 (zero_extend:DI (truncate:SI
7006 (lshiftrt:DI
7007 (mult:DI (any_extend:DI
7008 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7009 (any_extend:DI
7010 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7011 (const_int 32)))))
7012 (clobber (match_scratch:SI 3 "=1"))
7013 (clobber (reg:CC FLAGS_REG))]
7014 "TARGET_64BIT
7015 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7016 "<sgnprefix>mul{l}\t%2"
7017 [(set_attr "type" "imul")
7018 (set_attr "length_immediate" "0")
7019 (set (attr "athlon_decode")
7020 (if_then_else (eq_attr "cpu" "athlon")
7021 (const_string "vector")
7022 (const_string "double")))
7023 (set_attr "amdfam10_decode" "double")
7024 (set_attr "bdver1_decode" "direct")
7025 (set_attr "mode" "SI")])
7026
7027 ;; The patterns that match these are at the end of this file.
7028
7029 (define_expand "mulxf3"
7030 [(set (match_operand:XF 0 "register_operand" "")
7031 (mult:XF (match_operand:XF 1 "register_operand" "")
7032 (match_operand:XF 2 "register_operand" "")))]
7033 "TARGET_80387")
7034
7035 (define_expand "mul<mode>3"
7036 [(set (match_operand:MODEF 0 "register_operand" "")
7037 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7038 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7039 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7040 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7041 \f
7042 ;; Divide instructions
7043
7044 ;; The patterns that match these are at the end of this file.
7045
7046 (define_expand "divxf3"
7047 [(set (match_operand:XF 0 "register_operand" "")
7048 (div:XF (match_operand:XF 1 "register_operand" "")
7049 (match_operand:XF 2 "register_operand" "")))]
7050 "TARGET_80387")
7051
7052 (define_expand "divdf3"
7053 [(set (match_operand:DF 0 "register_operand" "")
7054 (div:DF (match_operand:DF 1 "register_operand" "")
7055 (match_operand:DF 2 "nonimmediate_operand" "")))]
7056 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7057 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7058
7059 (define_expand "divsf3"
7060 [(set (match_operand:SF 0 "register_operand" "")
7061 (div:SF (match_operand:SF 1 "register_operand" "")
7062 (match_operand:SF 2 "nonimmediate_operand" "")))]
7063 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7064 || TARGET_SSE_MATH"
7065 {
7066 if (TARGET_SSE_MATH
7067 && TARGET_RECIP_DIV
7068 && optimize_insn_for_speed_p ()
7069 && flag_finite_math_only && !flag_trapping_math
7070 && flag_unsafe_math_optimizations)
7071 {
7072 ix86_emit_swdivsf (operands[0], operands[1],
7073 operands[2], SFmode);
7074 DONE;
7075 }
7076 })
7077 \f
7078 ;; Divmod instructions.
7079
7080 (define_expand "divmod<mode>4"
7081 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7082 (div:SWIM248
7083 (match_operand:SWIM248 1 "register_operand" "")
7084 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7085 (set (match_operand:SWIM248 3 "register_operand" "")
7086 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7087 (clobber (reg:CC FLAGS_REG))])])
7088
7089 ;; Split with 8bit unsigned divide:
7090 ;; if (dividend an divisor are in [0-255])
7091 ;; use 8bit unsigned integer divide
7092 ;; else
7093 ;; use original integer divide
7094 (define_split
7095 [(set (match_operand:SWI48 0 "register_operand" "")
7096 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7097 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7098 (set (match_operand:SWI48 1 "register_operand" "")
7099 (mod:SWI48 (match_dup 2) (match_dup 3)))
7100 (clobber (reg:CC FLAGS_REG))]
7101 "TARGET_USE_8BIT_IDIV
7102 && TARGET_QIMODE_MATH
7103 && can_create_pseudo_p ()
7104 && !optimize_insn_for_size_p ()"
7105 [(const_int 0)]
7106 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7107
7108 (define_insn_and_split "divmod<mode>4_1"
7109 [(set (match_operand:SWI48 0 "register_operand" "=a")
7110 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7111 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7112 (set (match_operand:SWI48 1 "register_operand" "=&d")
7113 (mod:SWI48 (match_dup 2) (match_dup 3)))
7114 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7115 (clobber (reg:CC FLAGS_REG))]
7116 ""
7117 "#"
7118 "reload_completed"
7119 [(parallel [(set (match_dup 1)
7120 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7121 (clobber (reg:CC FLAGS_REG))])
7122 (parallel [(set (match_dup 0)
7123 (div:SWI48 (match_dup 2) (match_dup 3)))
7124 (set (match_dup 1)
7125 (mod:SWI48 (match_dup 2) (match_dup 3)))
7126 (use (match_dup 1))
7127 (clobber (reg:CC FLAGS_REG))])]
7128 {
7129 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7130
7131 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7132 operands[4] = operands[2];
7133 else
7134 {
7135 /* Avoid use of cltd in favor of a mov+shift. */
7136 emit_move_insn (operands[1], operands[2]);
7137 operands[4] = operands[1];
7138 }
7139 }
7140 [(set_attr "type" "multi")
7141 (set_attr "mode" "<MODE>")])
7142
7143 (define_insn_and_split "*divmod<mode>4"
7144 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7145 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7146 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7147 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7148 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7149 (clobber (reg:CC FLAGS_REG))]
7150 ""
7151 "#"
7152 "reload_completed"
7153 [(parallel [(set (match_dup 1)
7154 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7155 (clobber (reg:CC FLAGS_REG))])
7156 (parallel [(set (match_dup 0)
7157 (div:SWIM248 (match_dup 2) (match_dup 3)))
7158 (set (match_dup 1)
7159 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7160 (use (match_dup 1))
7161 (clobber (reg:CC FLAGS_REG))])]
7162 {
7163 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7164
7165 if (<MODE>mode != HImode
7166 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7167 operands[4] = operands[2];
7168 else
7169 {
7170 /* Avoid use of cltd in favor of a mov+shift. */
7171 emit_move_insn (operands[1], operands[2]);
7172 operands[4] = operands[1];
7173 }
7174 }
7175 [(set_attr "type" "multi")
7176 (set_attr "mode" "<MODE>")])
7177
7178 (define_insn "*divmod<mode>4_noext"
7179 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7180 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7181 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7182 (set (match_operand:SWIM248 1 "register_operand" "=d")
7183 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7184 (use (match_operand:SWIM248 4 "register_operand" "1"))
7185 (clobber (reg:CC FLAGS_REG))]
7186 ""
7187 "idiv{<imodesuffix>}\t%3"
7188 [(set_attr "type" "idiv")
7189 (set_attr "mode" "<MODE>")])
7190
7191 (define_expand "divmodqi4"
7192 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7193 (div:QI
7194 (match_operand:QI 1 "register_operand" "")
7195 (match_operand:QI 2 "nonimmediate_operand" "")))
7196 (set (match_operand:QI 3 "register_operand" "")
7197 (mod:QI (match_dup 1) (match_dup 2)))
7198 (clobber (reg:CC FLAGS_REG))])]
7199 "TARGET_QIMODE_MATH"
7200 {
7201 rtx div, mod, insn;
7202 rtx tmp0, tmp1;
7203
7204 tmp0 = gen_reg_rtx (HImode);
7205 tmp1 = gen_reg_rtx (HImode);
7206
7207 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7208 in AX. */
7209 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7210 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7211
7212 /* Extract remainder from AH. */
7213 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7214 insn = emit_move_insn (operands[3], tmp1);
7215
7216 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7217 set_unique_reg_note (insn, REG_EQUAL, mod);
7218
7219 /* Extract quotient from AL. */
7220 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7221
7222 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7223 set_unique_reg_note (insn, REG_EQUAL, div);
7224
7225 DONE;
7226 })
7227
7228 ;; Divide AX by r/m8, with result stored in
7229 ;; AL <- Quotient
7230 ;; AH <- Remainder
7231 ;; Change div/mod to HImode and extend the second argument to HImode
7232 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7233 ;; combine may fail.
7234 (define_insn "divmodhiqi3"
7235 [(set (match_operand:HI 0 "register_operand" "=a")
7236 (ior:HI
7237 (ashift:HI
7238 (zero_extend:HI
7239 (truncate:QI
7240 (mod:HI (match_operand:HI 1 "register_operand" "0")
7241 (sign_extend:HI
7242 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7243 (const_int 8))
7244 (zero_extend:HI
7245 (truncate:QI
7246 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7247 (clobber (reg:CC FLAGS_REG))]
7248 "TARGET_QIMODE_MATH"
7249 "idiv{b}\t%2"
7250 [(set_attr "type" "idiv")
7251 (set_attr "mode" "QI")])
7252
7253 (define_expand "udivmod<mode>4"
7254 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7255 (udiv:SWIM248
7256 (match_operand:SWIM248 1 "register_operand" "")
7257 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7258 (set (match_operand:SWIM248 3 "register_operand" "")
7259 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7260 (clobber (reg:CC FLAGS_REG))])])
7261
7262 ;; Split with 8bit unsigned divide:
7263 ;; if (dividend an divisor are in [0-255])
7264 ;; use 8bit unsigned integer divide
7265 ;; else
7266 ;; use original integer divide
7267 (define_split
7268 [(set (match_operand:SWI48 0 "register_operand" "")
7269 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7270 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7271 (set (match_operand:SWI48 1 "register_operand" "")
7272 (umod:SWI48 (match_dup 2) (match_dup 3)))
7273 (clobber (reg:CC FLAGS_REG))]
7274 "TARGET_USE_8BIT_IDIV
7275 && TARGET_QIMODE_MATH
7276 && can_create_pseudo_p ()
7277 && !optimize_insn_for_size_p ()"
7278 [(const_int 0)]
7279 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7280
7281 (define_insn_and_split "udivmod<mode>4_1"
7282 [(set (match_operand:SWI48 0 "register_operand" "=a")
7283 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7284 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7285 (set (match_operand:SWI48 1 "register_operand" "=&d")
7286 (umod:SWI48 (match_dup 2) (match_dup 3)))
7287 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7288 (clobber (reg:CC FLAGS_REG))]
7289 ""
7290 "#"
7291 "reload_completed"
7292 [(set (match_dup 1) (const_int 0))
7293 (parallel [(set (match_dup 0)
7294 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7295 (set (match_dup 1)
7296 (umod:SWI48 (match_dup 2) (match_dup 3)))
7297 (use (match_dup 1))
7298 (clobber (reg:CC FLAGS_REG))])]
7299 ""
7300 [(set_attr "type" "multi")
7301 (set_attr "mode" "<MODE>")])
7302
7303 (define_insn_and_split "*udivmod<mode>4"
7304 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7305 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7306 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7307 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7308 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7309 (clobber (reg:CC FLAGS_REG))]
7310 ""
7311 "#"
7312 "reload_completed"
7313 [(set (match_dup 1) (const_int 0))
7314 (parallel [(set (match_dup 0)
7315 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7316 (set (match_dup 1)
7317 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7318 (use (match_dup 1))
7319 (clobber (reg:CC FLAGS_REG))])]
7320 ""
7321 [(set_attr "type" "multi")
7322 (set_attr "mode" "<MODE>")])
7323
7324 (define_insn "*udivmod<mode>4_noext"
7325 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7326 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7327 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7328 (set (match_operand:SWIM248 1 "register_operand" "=d")
7329 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7330 (use (match_operand:SWIM248 4 "register_operand" "1"))
7331 (clobber (reg:CC FLAGS_REG))]
7332 ""
7333 "div{<imodesuffix>}\t%3"
7334 [(set_attr "type" "idiv")
7335 (set_attr "mode" "<MODE>")])
7336
7337 (define_expand "udivmodqi4"
7338 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7339 (udiv:QI
7340 (match_operand:QI 1 "register_operand" "")
7341 (match_operand:QI 2 "nonimmediate_operand" "")))
7342 (set (match_operand:QI 3 "register_operand" "")
7343 (umod:QI (match_dup 1) (match_dup 2)))
7344 (clobber (reg:CC FLAGS_REG))])]
7345 "TARGET_QIMODE_MATH"
7346 {
7347 rtx div, mod, insn;
7348 rtx tmp0, tmp1;
7349
7350 tmp0 = gen_reg_rtx (HImode);
7351 tmp1 = gen_reg_rtx (HImode);
7352
7353 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7354 in AX. */
7355 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7356 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7357
7358 /* Extract remainder from AH. */
7359 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7360 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7361 insn = emit_move_insn (operands[3], tmp1);
7362
7363 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7364 set_unique_reg_note (insn, REG_EQUAL, mod);
7365
7366 /* Extract quotient from AL. */
7367 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7368
7369 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7370 set_unique_reg_note (insn, REG_EQUAL, div);
7371
7372 DONE;
7373 })
7374
7375 (define_insn "udivmodhiqi3"
7376 [(set (match_operand:HI 0 "register_operand" "=a")
7377 (ior:HI
7378 (ashift:HI
7379 (zero_extend:HI
7380 (truncate:QI
7381 (mod:HI (match_operand:HI 1 "register_operand" "0")
7382 (zero_extend:HI
7383 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7384 (const_int 8))
7385 (zero_extend:HI
7386 (truncate:QI
7387 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7388 (clobber (reg:CC FLAGS_REG))]
7389 "TARGET_QIMODE_MATH"
7390 "div{b}\t%2"
7391 [(set_attr "type" "idiv")
7392 (set_attr "mode" "QI")])
7393
7394 ;; We cannot use div/idiv for double division, because it causes
7395 ;; "division by zero" on the overflow and that's not what we expect
7396 ;; from truncate. Because true (non truncating) double division is
7397 ;; never generated, we can't create this insn anyway.
7398 ;
7399 ;(define_insn ""
7400 ; [(set (match_operand:SI 0 "register_operand" "=a")
7401 ; (truncate:SI
7402 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7403 ; (zero_extend:DI
7404 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7405 ; (set (match_operand:SI 3 "register_operand" "=d")
7406 ; (truncate:SI
7407 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7408 ; (clobber (reg:CC FLAGS_REG))]
7409 ; ""
7410 ; "div{l}\t{%2, %0|%0, %2}"
7411 ; [(set_attr "type" "idiv")])
7412 \f
7413 ;;- Logical AND instructions
7414
7415 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7416 ;; Note that this excludes ah.
7417
7418 (define_expand "testsi_ccno_1"
7419 [(set (reg:CCNO FLAGS_REG)
7420 (compare:CCNO
7421 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7422 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7423 (const_int 0)))])
7424
7425 (define_expand "testqi_ccz_1"
7426 [(set (reg:CCZ FLAGS_REG)
7427 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7428 (match_operand:QI 1 "nonmemory_operand" ""))
7429 (const_int 0)))])
7430
7431 (define_expand "testdi_ccno_1"
7432 [(set (reg:CCNO FLAGS_REG)
7433 (compare:CCNO
7434 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7435 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7436 (const_int 0)))]
7437 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7438
7439 (define_insn "*testdi_1"
7440 [(set (reg FLAGS_REG)
7441 (compare
7442 (and:DI
7443 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7444 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7445 (const_int 0)))]
7446 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7447 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7448 "@
7449 test{l}\t{%k1, %k0|%k0, %k1}
7450 test{l}\t{%k1, %k0|%k0, %k1}
7451 test{q}\t{%1, %0|%0, %1}
7452 test{q}\t{%1, %0|%0, %1}
7453 test{q}\t{%1, %0|%0, %1}"
7454 [(set_attr "type" "test")
7455 (set_attr "modrm" "0,1,0,1,1")
7456 (set_attr "mode" "SI,SI,DI,DI,DI")])
7457
7458 (define_insn "*testqi_1_maybe_si"
7459 [(set (reg FLAGS_REG)
7460 (compare
7461 (and:QI
7462 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7463 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7464 (const_int 0)))]
7465 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7466 && ix86_match_ccmode (insn,
7467 CONST_INT_P (operands[1])
7468 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7469 {
7470 if (which_alternative == 3)
7471 {
7472 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7473 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7474 return "test{l}\t{%1, %k0|%k0, %1}";
7475 }
7476 return "test{b}\t{%1, %0|%0, %1}";
7477 }
7478 [(set_attr "type" "test")
7479 (set_attr "modrm" "0,1,1,1")
7480 (set_attr "mode" "QI,QI,QI,SI")
7481 (set_attr "pent_pair" "uv,np,uv,np")])
7482
7483 (define_insn "*test<mode>_1"
7484 [(set (reg FLAGS_REG)
7485 (compare
7486 (and:SWI124
7487 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7488 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7489 (const_int 0)))]
7490 "ix86_match_ccmode (insn, CCNOmode)
7491 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7492 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7493 [(set_attr "type" "test")
7494 (set_attr "modrm" "0,1,1")
7495 (set_attr "mode" "<MODE>")
7496 (set_attr "pent_pair" "uv,np,uv")])
7497
7498 (define_expand "testqi_ext_ccno_0"
7499 [(set (reg:CCNO FLAGS_REG)
7500 (compare:CCNO
7501 (and:SI
7502 (zero_extract:SI
7503 (match_operand 0 "ext_register_operand" "")
7504 (const_int 8)
7505 (const_int 8))
7506 (match_operand 1 "const_int_operand" ""))
7507 (const_int 0)))])
7508
7509 (define_insn "*testqi_ext_0"
7510 [(set (reg FLAGS_REG)
7511 (compare
7512 (and:SI
7513 (zero_extract:SI
7514 (match_operand 0 "ext_register_operand" "Q")
7515 (const_int 8)
7516 (const_int 8))
7517 (match_operand 1 "const_int_operand" "n"))
7518 (const_int 0)))]
7519 "ix86_match_ccmode (insn, CCNOmode)"
7520 "test{b}\t{%1, %h0|%h0, %1}"
7521 [(set_attr "type" "test")
7522 (set_attr "mode" "QI")
7523 (set_attr "length_immediate" "1")
7524 (set_attr "modrm" "1")
7525 (set_attr "pent_pair" "np")])
7526
7527 (define_insn "*testqi_ext_1_rex64"
7528 [(set (reg FLAGS_REG)
7529 (compare
7530 (and:SI
7531 (zero_extract:SI
7532 (match_operand 0 "ext_register_operand" "Q")
7533 (const_int 8)
7534 (const_int 8))
7535 (zero_extend:SI
7536 (match_operand:QI 1 "register_operand" "Q")))
7537 (const_int 0)))]
7538 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7539 "test{b}\t{%1, %h0|%h0, %1}"
7540 [(set_attr "type" "test")
7541 (set_attr "mode" "QI")])
7542
7543 (define_insn "*testqi_ext_1"
7544 [(set (reg FLAGS_REG)
7545 (compare
7546 (and:SI
7547 (zero_extract:SI
7548 (match_operand 0 "ext_register_operand" "Q")
7549 (const_int 8)
7550 (const_int 8))
7551 (zero_extend:SI
7552 (match_operand:QI 1 "general_operand" "Qm")))
7553 (const_int 0)))]
7554 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7555 "test{b}\t{%1, %h0|%h0, %1}"
7556 [(set_attr "type" "test")
7557 (set_attr "mode" "QI")])
7558
7559 (define_insn "*testqi_ext_2"
7560 [(set (reg FLAGS_REG)
7561 (compare
7562 (and:SI
7563 (zero_extract:SI
7564 (match_operand 0 "ext_register_operand" "Q")
7565 (const_int 8)
7566 (const_int 8))
7567 (zero_extract:SI
7568 (match_operand 1 "ext_register_operand" "Q")
7569 (const_int 8)
7570 (const_int 8)))
7571 (const_int 0)))]
7572 "ix86_match_ccmode (insn, CCNOmode)"
7573 "test{b}\t{%h1, %h0|%h0, %h1}"
7574 [(set_attr "type" "test")
7575 (set_attr "mode" "QI")])
7576
7577 (define_insn "*testqi_ext_3_rex64"
7578 [(set (reg FLAGS_REG)
7579 (compare (zero_extract:DI
7580 (match_operand 0 "nonimmediate_operand" "rm")
7581 (match_operand:DI 1 "const_int_operand" "")
7582 (match_operand:DI 2 "const_int_operand" ""))
7583 (const_int 0)))]
7584 "TARGET_64BIT
7585 && ix86_match_ccmode (insn, CCNOmode)
7586 && INTVAL (operands[1]) > 0
7587 && INTVAL (operands[2]) >= 0
7588 /* Ensure that resulting mask is zero or sign extended operand. */
7589 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7590 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7591 && INTVAL (operands[1]) > 32))
7592 && (GET_MODE (operands[0]) == SImode
7593 || GET_MODE (operands[0]) == DImode
7594 || GET_MODE (operands[0]) == HImode
7595 || GET_MODE (operands[0]) == QImode)"
7596 "#")
7597
7598 ;; Combine likes to form bit extractions for some tests. Humor it.
7599 (define_insn "*testqi_ext_3"
7600 [(set (reg FLAGS_REG)
7601 (compare (zero_extract:SI
7602 (match_operand 0 "nonimmediate_operand" "rm")
7603 (match_operand:SI 1 "const_int_operand" "")
7604 (match_operand:SI 2 "const_int_operand" ""))
7605 (const_int 0)))]
7606 "ix86_match_ccmode (insn, CCNOmode)
7607 && INTVAL (operands[1]) > 0
7608 && INTVAL (operands[2]) >= 0
7609 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7610 && (GET_MODE (operands[0]) == SImode
7611 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7612 || GET_MODE (operands[0]) == HImode
7613 || GET_MODE (operands[0]) == QImode)"
7614 "#")
7615
7616 (define_split
7617 [(set (match_operand 0 "flags_reg_operand" "")
7618 (match_operator 1 "compare_operator"
7619 [(zero_extract
7620 (match_operand 2 "nonimmediate_operand" "")
7621 (match_operand 3 "const_int_operand" "")
7622 (match_operand 4 "const_int_operand" ""))
7623 (const_int 0)]))]
7624 "ix86_match_ccmode (insn, CCNOmode)"
7625 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7626 {
7627 rtx val = operands[2];
7628 HOST_WIDE_INT len = INTVAL (operands[3]);
7629 HOST_WIDE_INT pos = INTVAL (operands[4]);
7630 HOST_WIDE_INT mask;
7631 enum machine_mode mode, submode;
7632
7633 mode = GET_MODE (val);
7634 if (MEM_P (val))
7635 {
7636 /* ??? Combine likes to put non-volatile mem extractions in QImode
7637 no matter the size of the test. So find a mode that works. */
7638 if (! MEM_VOLATILE_P (val))
7639 {
7640 mode = smallest_mode_for_size (pos + len, MODE_INT);
7641 val = adjust_address (val, mode, 0);
7642 }
7643 }
7644 else if (GET_CODE (val) == SUBREG
7645 && (submode = GET_MODE (SUBREG_REG (val)),
7646 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7647 && pos + len <= GET_MODE_BITSIZE (submode)
7648 && GET_MODE_CLASS (submode) == MODE_INT)
7649 {
7650 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7651 mode = submode;
7652 val = SUBREG_REG (val);
7653 }
7654 else if (mode == HImode && pos + len <= 8)
7655 {
7656 /* Small HImode tests can be converted to QImode. */
7657 mode = QImode;
7658 val = gen_lowpart (QImode, val);
7659 }
7660
7661 if (len == HOST_BITS_PER_WIDE_INT)
7662 mask = -1;
7663 else
7664 mask = ((HOST_WIDE_INT)1 << len) - 1;
7665 mask <<= pos;
7666
7667 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7668 })
7669
7670 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7671 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7672 ;; this is relatively important trick.
7673 ;; Do the conversion only post-reload to avoid limiting of the register class
7674 ;; to QI regs.
7675 (define_split
7676 [(set (match_operand 0 "flags_reg_operand" "")
7677 (match_operator 1 "compare_operator"
7678 [(and (match_operand 2 "register_operand" "")
7679 (match_operand 3 "const_int_operand" ""))
7680 (const_int 0)]))]
7681 "reload_completed
7682 && QI_REG_P (operands[2])
7683 && GET_MODE (operands[2]) != QImode
7684 && ((ix86_match_ccmode (insn, CCZmode)
7685 && !(INTVAL (operands[3]) & ~(255 << 8)))
7686 || (ix86_match_ccmode (insn, CCNOmode)
7687 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7688 [(set (match_dup 0)
7689 (match_op_dup 1
7690 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7691 (match_dup 3))
7692 (const_int 0)]))]
7693 "operands[2] = gen_lowpart (SImode, operands[2]);
7694 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7695
7696 (define_split
7697 [(set (match_operand 0 "flags_reg_operand" "")
7698 (match_operator 1 "compare_operator"
7699 [(and (match_operand 2 "nonimmediate_operand" "")
7700 (match_operand 3 "const_int_operand" ""))
7701 (const_int 0)]))]
7702 "reload_completed
7703 && GET_MODE (operands[2]) != QImode
7704 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7705 && ((ix86_match_ccmode (insn, CCZmode)
7706 && !(INTVAL (operands[3]) & ~255))
7707 || (ix86_match_ccmode (insn, CCNOmode)
7708 && !(INTVAL (operands[3]) & ~127)))"
7709 [(set (match_dup 0)
7710 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7711 (const_int 0)]))]
7712 "operands[2] = gen_lowpart (QImode, operands[2]);
7713 operands[3] = gen_lowpart (QImode, operands[3]);")
7714
7715 ;; %%% This used to optimize known byte-wide and operations to memory,
7716 ;; and sometimes to QImode registers. If this is considered useful,
7717 ;; it should be done with splitters.
7718
7719 (define_expand "and<mode>3"
7720 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7721 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7722 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7723 ""
7724 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7725
7726 (define_insn "*anddi_1"
7727 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7728 (and:DI
7729 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7730 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7731 (clobber (reg:CC FLAGS_REG))]
7732 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7733 {
7734 switch (get_attr_type (insn))
7735 {
7736 case TYPE_IMOVX:
7737 {
7738 enum machine_mode mode;
7739
7740 gcc_assert (CONST_INT_P (operands[2]));
7741 if (INTVAL (operands[2]) == 0xff)
7742 mode = QImode;
7743 else
7744 {
7745 gcc_assert (INTVAL (operands[2]) == 0xffff);
7746 mode = HImode;
7747 }
7748
7749 operands[1] = gen_lowpart (mode, operands[1]);
7750 if (mode == QImode)
7751 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7752 else
7753 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7754 }
7755
7756 default:
7757 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7758 if (get_attr_mode (insn) == MODE_SI)
7759 return "and{l}\t{%k2, %k0|%k0, %k2}";
7760 else
7761 return "and{q}\t{%2, %0|%0, %2}";
7762 }
7763 }
7764 [(set_attr "type" "alu,alu,alu,imovx")
7765 (set_attr "length_immediate" "*,*,*,0")
7766 (set (attr "prefix_rex")
7767 (if_then_else
7768 (and (eq_attr "type" "imovx")
7769 (and (match_test "INTVAL (operands[2]) == 0xff")
7770 (match_operand 1 "ext_QIreg_operand" "")))
7771 (const_string "1")
7772 (const_string "*")))
7773 (set_attr "mode" "SI,DI,DI,SI")])
7774
7775 (define_insn "*andsi_1"
7776 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7777 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7778 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7779 (clobber (reg:CC FLAGS_REG))]
7780 "ix86_binary_operator_ok (AND, SImode, operands)"
7781 {
7782 switch (get_attr_type (insn))
7783 {
7784 case TYPE_IMOVX:
7785 {
7786 enum machine_mode mode;
7787
7788 gcc_assert (CONST_INT_P (operands[2]));
7789 if (INTVAL (operands[2]) == 0xff)
7790 mode = QImode;
7791 else
7792 {
7793 gcc_assert (INTVAL (operands[2]) == 0xffff);
7794 mode = HImode;
7795 }
7796
7797 operands[1] = gen_lowpart (mode, operands[1]);
7798 if (mode == QImode)
7799 return "movz{bl|x}\t{%1, %0|%0, %1}";
7800 else
7801 return "movz{wl|x}\t{%1, %0|%0, %1}";
7802 }
7803
7804 default:
7805 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7806 return "and{l}\t{%2, %0|%0, %2}";
7807 }
7808 }
7809 [(set_attr "type" "alu,alu,imovx")
7810 (set (attr "prefix_rex")
7811 (if_then_else
7812 (and (eq_attr "type" "imovx")
7813 (and (match_test "INTVAL (operands[2]) == 0xff")
7814 (match_operand 1 "ext_QIreg_operand" "")))
7815 (const_string "1")
7816 (const_string "*")))
7817 (set_attr "length_immediate" "*,*,0")
7818 (set_attr "mode" "SI")])
7819
7820 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7821 (define_insn "*andsi_1_zext"
7822 [(set (match_operand:DI 0 "register_operand" "=r")
7823 (zero_extend:DI
7824 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7825 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7826 (clobber (reg:CC FLAGS_REG))]
7827 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7828 "and{l}\t{%2, %k0|%k0, %2}"
7829 [(set_attr "type" "alu")
7830 (set_attr "mode" "SI")])
7831
7832 (define_insn "*andhi_1"
7833 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7834 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7835 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7836 (clobber (reg:CC FLAGS_REG))]
7837 "ix86_binary_operator_ok (AND, HImode, operands)"
7838 {
7839 switch (get_attr_type (insn))
7840 {
7841 case TYPE_IMOVX:
7842 gcc_assert (CONST_INT_P (operands[2]));
7843 gcc_assert (INTVAL (operands[2]) == 0xff);
7844 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7845
7846 default:
7847 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7848
7849 return "and{w}\t{%2, %0|%0, %2}";
7850 }
7851 }
7852 [(set_attr "type" "alu,alu,imovx")
7853 (set_attr "length_immediate" "*,*,0")
7854 (set (attr "prefix_rex")
7855 (if_then_else
7856 (and (eq_attr "type" "imovx")
7857 (match_operand 1 "ext_QIreg_operand" ""))
7858 (const_string "1")
7859 (const_string "*")))
7860 (set_attr "mode" "HI,HI,SI")])
7861
7862 ;; %%% Potential partial reg stall on alternative 2. What to do?
7863 (define_insn "*andqi_1"
7864 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7865 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7866 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7867 (clobber (reg:CC FLAGS_REG))]
7868 "ix86_binary_operator_ok (AND, QImode, operands)"
7869 "@
7870 and{b}\t{%2, %0|%0, %2}
7871 and{b}\t{%2, %0|%0, %2}
7872 and{l}\t{%k2, %k0|%k0, %k2}"
7873 [(set_attr "type" "alu")
7874 (set_attr "mode" "QI,QI,SI")])
7875
7876 (define_insn "*andqi_1_slp"
7877 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7878 (and:QI (match_dup 0)
7879 (match_operand:QI 1 "general_operand" "qn,qmn")))
7880 (clobber (reg:CC FLAGS_REG))]
7881 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7882 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7883 "and{b}\t{%1, %0|%0, %1}"
7884 [(set_attr "type" "alu1")
7885 (set_attr "mode" "QI")])
7886
7887 (define_split
7888 [(set (match_operand 0 "register_operand" "")
7889 (and (match_dup 0)
7890 (const_int -65536)))
7891 (clobber (reg:CC FLAGS_REG))]
7892 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7893 || optimize_function_for_size_p (cfun)"
7894 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7895 "operands[1] = gen_lowpart (HImode, operands[0]);")
7896
7897 (define_split
7898 [(set (match_operand 0 "ext_register_operand" "")
7899 (and (match_dup 0)
7900 (const_int -256)))
7901 (clobber (reg:CC FLAGS_REG))]
7902 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7903 && reload_completed"
7904 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7905 "operands[1] = gen_lowpart (QImode, operands[0]);")
7906
7907 (define_split
7908 [(set (match_operand 0 "ext_register_operand" "")
7909 (and (match_dup 0)
7910 (const_int -65281)))
7911 (clobber (reg:CC FLAGS_REG))]
7912 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7913 && reload_completed"
7914 [(parallel [(set (zero_extract:SI (match_dup 0)
7915 (const_int 8)
7916 (const_int 8))
7917 (xor:SI
7918 (zero_extract:SI (match_dup 0)
7919 (const_int 8)
7920 (const_int 8))
7921 (zero_extract:SI (match_dup 0)
7922 (const_int 8)
7923 (const_int 8))))
7924 (clobber (reg:CC FLAGS_REG))])]
7925 "operands[0] = gen_lowpart (SImode, operands[0]);")
7926
7927 (define_insn "*anddi_2"
7928 [(set (reg FLAGS_REG)
7929 (compare
7930 (and:DI
7931 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7932 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7933 (const_int 0)))
7934 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7935 (and:DI (match_dup 1) (match_dup 2)))]
7936 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7937 && ix86_binary_operator_ok (AND, DImode, operands)"
7938 "@
7939 and{l}\t{%k2, %k0|%k0, %k2}
7940 and{q}\t{%2, %0|%0, %2}
7941 and{q}\t{%2, %0|%0, %2}"
7942 [(set_attr "type" "alu")
7943 (set_attr "mode" "SI,DI,DI")])
7944
7945 (define_insn "*andqi_2_maybe_si"
7946 [(set (reg FLAGS_REG)
7947 (compare (and:QI
7948 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7949 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7950 (const_int 0)))
7951 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7952 (and:QI (match_dup 1) (match_dup 2)))]
7953 "ix86_binary_operator_ok (AND, QImode, operands)
7954 && ix86_match_ccmode (insn,
7955 CONST_INT_P (operands[2])
7956 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7957 {
7958 if (which_alternative == 2)
7959 {
7960 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7961 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7962 return "and{l}\t{%2, %k0|%k0, %2}";
7963 }
7964 return "and{b}\t{%2, %0|%0, %2}";
7965 }
7966 [(set_attr "type" "alu")
7967 (set_attr "mode" "QI,QI,SI")])
7968
7969 (define_insn "*and<mode>_2"
7970 [(set (reg FLAGS_REG)
7971 (compare (and:SWI124
7972 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7973 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7974 (const_int 0)))
7975 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7976 (and:SWI124 (match_dup 1) (match_dup 2)))]
7977 "ix86_match_ccmode (insn, CCNOmode)
7978 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7979 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7980 [(set_attr "type" "alu")
7981 (set_attr "mode" "<MODE>")])
7982
7983 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7984 (define_insn "*andsi_2_zext"
7985 [(set (reg FLAGS_REG)
7986 (compare (and:SI
7987 (match_operand:SI 1 "nonimmediate_operand" "%0")
7988 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7989 (const_int 0)))
7990 (set (match_operand:DI 0 "register_operand" "=r")
7991 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7992 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7993 && ix86_binary_operator_ok (AND, SImode, operands)"
7994 "and{l}\t{%2, %k0|%k0, %2}"
7995 [(set_attr "type" "alu")
7996 (set_attr "mode" "SI")])
7997
7998 (define_insn "*andqi_2_slp"
7999 [(set (reg FLAGS_REG)
8000 (compare (and:QI
8001 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8002 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8003 (const_int 0)))
8004 (set (strict_low_part (match_dup 0))
8005 (and:QI (match_dup 0) (match_dup 1)))]
8006 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8007 && ix86_match_ccmode (insn, CCNOmode)
8008 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8009 "and{b}\t{%1, %0|%0, %1}"
8010 [(set_attr "type" "alu1")
8011 (set_attr "mode" "QI")])
8012
8013 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8014 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8015 ;; for a QImode operand, which of course failed.
8016 (define_insn "andqi_ext_0"
8017 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8018 (const_int 8)
8019 (const_int 8))
8020 (and:SI
8021 (zero_extract:SI
8022 (match_operand 1 "ext_register_operand" "0")
8023 (const_int 8)
8024 (const_int 8))
8025 (match_operand 2 "const_int_operand" "n")))
8026 (clobber (reg:CC FLAGS_REG))]
8027 ""
8028 "and{b}\t{%2, %h0|%h0, %2}"
8029 [(set_attr "type" "alu")
8030 (set_attr "length_immediate" "1")
8031 (set_attr "modrm" "1")
8032 (set_attr "mode" "QI")])
8033
8034 ;; Generated by peephole translating test to and. This shows up
8035 ;; often in fp comparisons.
8036 (define_insn "*andqi_ext_0_cc"
8037 [(set (reg FLAGS_REG)
8038 (compare
8039 (and:SI
8040 (zero_extract:SI
8041 (match_operand 1 "ext_register_operand" "0")
8042 (const_int 8)
8043 (const_int 8))
8044 (match_operand 2 "const_int_operand" "n"))
8045 (const_int 0)))
8046 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8047 (const_int 8)
8048 (const_int 8))
8049 (and:SI
8050 (zero_extract:SI
8051 (match_dup 1)
8052 (const_int 8)
8053 (const_int 8))
8054 (match_dup 2)))]
8055 "ix86_match_ccmode (insn, CCNOmode)"
8056 "and{b}\t{%2, %h0|%h0, %2}"
8057 [(set_attr "type" "alu")
8058 (set_attr "length_immediate" "1")
8059 (set_attr "modrm" "1")
8060 (set_attr "mode" "QI")])
8061
8062 (define_insn "*andqi_ext_1_rex64"
8063 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8064 (const_int 8)
8065 (const_int 8))
8066 (and:SI
8067 (zero_extract:SI
8068 (match_operand 1 "ext_register_operand" "0")
8069 (const_int 8)
8070 (const_int 8))
8071 (zero_extend:SI
8072 (match_operand 2 "ext_register_operand" "Q"))))
8073 (clobber (reg:CC FLAGS_REG))]
8074 "TARGET_64BIT"
8075 "and{b}\t{%2, %h0|%h0, %2}"
8076 [(set_attr "type" "alu")
8077 (set_attr "length_immediate" "0")
8078 (set_attr "mode" "QI")])
8079
8080 (define_insn "*andqi_ext_1"
8081 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8082 (const_int 8)
8083 (const_int 8))
8084 (and:SI
8085 (zero_extract:SI
8086 (match_operand 1 "ext_register_operand" "0")
8087 (const_int 8)
8088 (const_int 8))
8089 (zero_extend:SI
8090 (match_operand:QI 2 "general_operand" "Qm"))))
8091 (clobber (reg:CC FLAGS_REG))]
8092 "!TARGET_64BIT"
8093 "and{b}\t{%2, %h0|%h0, %2}"
8094 [(set_attr "type" "alu")
8095 (set_attr "length_immediate" "0")
8096 (set_attr "mode" "QI")])
8097
8098 (define_insn "*andqi_ext_2"
8099 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8100 (const_int 8)
8101 (const_int 8))
8102 (and:SI
8103 (zero_extract:SI
8104 (match_operand 1 "ext_register_operand" "%0")
8105 (const_int 8)
8106 (const_int 8))
8107 (zero_extract:SI
8108 (match_operand 2 "ext_register_operand" "Q")
8109 (const_int 8)
8110 (const_int 8))))
8111 (clobber (reg:CC FLAGS_REG))]
8112 ""
8113 "and{b}\t{%h2, %h0|%h0, %h2}"
8114 [(set_attr "type" "alu")
8115 (set_attr "length_immediate" "0")
8116 (set_attr "mode" "QI")])
8117
8118 ;; Convert wide AND instructions with immediate operand to shorter QImode
8119 ;; equivalents when possible.
8120 ;; Don't do the splitting with memory operands, since it introduces risk
8121 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8122 ;; for size, but that can (should?) be handled by generic code instead.
8123 (define_split
8124 [(set (match_operand 0 "register_operand" "")
8125 (and (match_operand 1 "register_operand" "")
8126 (match_operand 2 "const_int_operand" "")))
8127 (clobber (reg:CC FLAGS_REG))]
8128 "reload_completed
8129 && QI_REG_P (operands[0])
8130 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8131 && !(~INTVAL (operands[2]) & ~(255 << 8))
8132 && GET_MODE (operands[0]) != QImode"
8133 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8134 (and:SI (zero_extract:SI (match_dup 1)
8135 (const_int 8) (const_int 8))
8136 (match_dup 2)))
8137 (clobber (reg:CC FLAGS_REG))])]
8138 "operands[0] = gen_lowpart (SImode, operands[0]);
8139 operands[1] = gen_lowpart (SImode, operands[1]);
8140 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8141
8142 ;; Since AND can be encoded with sign extended immediate, this is only
8143 ;; profitable when 7th bit is not set.
8144 (define_split
8145 [(set (match_operand 0 "register_operand" "")
8146 (and (match_operand 1 "general_operand" "")
8147 (match_operand 2 "const_int_operand" "")))
8148 (clobber (reg:CC FLAGS_REG))]
8149 "reload_completed
8150 && ANY_QI_REG_P (operands[0])
8151 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8152 && !(~INTVAL (operands[2]) & ~255)
8153 && !(INTVAL (operands[2]) & 128)
8154 && GET_MODE (operands[0]) != QImode"
8155 [(parallel [(set (strict_low_part (match_dup 0))
8156 (and:QI (match_dup 1)
8157 (match_dup 2)))
8158 (clobber (reg:CC FLAGS_REG))])]
8159 "operands[0] = gen_lowpart (QImode, operands[0]);
8160 operands[1] = gen_lowpart (QImode, operands[1]);
8161 operands[2] = gen_lowpart (QImode, operands[2]);")
8162 \f
8163 ;; Logical inclusive and exclusive OR instructions
8164
8165 ;; %%% This used to optimize known byte-wide and operations to memory.
8166 ;; If this is considered useful, it should be done with splitters.
8167
8168 (define_expand "<code><mode>3"
8169 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8170 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8171 (match_operand:SWIM 2 "<general_operand>" "")))]
8172 ""
8173 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8174
8175 (define_insn "*<code><mode>_1"
8176 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8177 (any_or:SWI248
8178 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8179 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8180 (clobber (reg:CC FLAGS_REG))]
8181 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8182 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8183 [(set_attr "type" "alu")
8184 (set_attr "mode" "<MODE>")])
8185
8186 ;; %%% Potential partial reg stall on alternative 2. What to do?
8187 (define_insn "*<code>qi_1"
8188 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8189 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8190 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8191 (clobber (reg:CC FLAGS_REG))]
8192 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8193 "@
8194 <logic>{b}\t{%2, %0|%0, %2}
8195 <logic>{b}\t{%2, %0|%0, %2}
8196 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8197 [(set_attr "type" "alu")
8198 (set_attr "mode" "QI,QI,SI")])
8199
8200 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8201 (define_insn "*<code>si_1_zext"
8202 [(set (match_operand:DI 0 "register_operand" "=r")
8203 (zero_extend:DI
8204 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8205 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8206 (clobber (reg:CC FLAGS_REG))]
8207 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8208 "<logic>{l}\t{%2, %k0|%k0, %2}"
8209 [(set_attr "type" "alu")
8210 (set_attr "mode" "SI")])
8211
8212 (define_insn "*<code>si_1_zext_imm"
8213 [(set (match_operand:DI 0 "register_operand" "=r")
8214 (any_or:DI
8215 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8216 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8217 (clobber (reg:CC FLAGS_REG))]
8218 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8219 "<logic>{l}\t{%2, %k0|%k0, %2}"
8220 [(set_attr "type" "alu")
8221 (set_attr "mode" "SI")])
8222
8223 (define_insn "*<code>qi_1_slp"
8224 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8225 (any_or:QI (match_dup 0)
8226 (match_operand:QI 1 "general_operand" "qmn,qn")))
8227 (clobber (reg:CC FLAGS_REG))]
8228 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8229 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8230 "<logic>{b}\t{%1, %0|%0, %1}"
8231 [(set_attr "type" "alu1")
8232 (set_attr "mode" "QI")])
8233
8234 (define_insn "*<code><mode>_2"
8235 [(set (reg FLAGS_REG)
8236 (compare (any_or:SWI
8237 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8238 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8239 (const_int 0)))
8240 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8241 (any_or:SWI (match_dup 1) (match_dup 2)))]
8242 "ix86_match_ccmode (insn, CCNOmode)
8243 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8244 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8245 [(set_attr "type" "alu")
8246 (set_attr "mode" "<MODE>")])
8247
8248 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8249 ;; ??? Special case for immediate operand is missing - it is tricky.
8250 (define_insn "*<code>si_2_zext"
8251 [(set (reg FLAGS_REG)
8252 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8253 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8254 (const_int 0)))
8255 (set (match_operand:DI 0 "register_operand" "=r")
8256 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8257 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8258 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8259 "<logic>{l}\t{%2, %k0|%k0, %2}"
8260 [(set_attr "type" "alu")
8261 (set_attr "mode" "SI")])
8262
8263 (define_insn "*<code>si_2_zext_imm"
8264 [(set (reg FLAGS_REG)
8265 (compare (any_or:SI
8266 (match_operand:SI 1 "nonimmediate_operand" "%0")
8267 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8268 (const_int 0)))
8269 (set (match_operand:DI 0 "register_operand" "=r")
8270 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8271 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8272 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8273 "<logic>{l}\t{%2, %k0|%k0, %2}"
8274 [(set_attr "type" "alu")
8275 (set_attr "mode" "SI")])
8276
8277 (define_insn "*<code>qi_2_slp"
8278 [(set (reg FLAGS_REG)
8279 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8280 (match_operand:QI 1 "general_operand" "qmn,qn"))
8281 (const_int 0)))
8282 (set (strict_low_part (match_dup 0))
8283 (any_or:QI (match_dup 0) (match_dup 1)))]
8284 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8285 && ix86_match_ccmode (insn, CCNOmode)
8286 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8287 "<logic>{b}\t{%1, %0|%0, %1}"
8288 [(set_attr "type" "alu1")
8289 (set_attr "mode" "QI")])
8290
8291 (define_insn "*<code><mode>_3"
8292 [(set (reg FLAGS_REG)
8293 (compare (any_or:SWI
8294 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8295 (match_operand:SWI 2 "<general_operand>" "<g>"))
8296 (const_int 0)))
8297 (clobber (match_scratch:SWI 0 "=<r>"))]
8298 "ix86_match_ccmode (insn, CCNOmode)
8299 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8300 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8301 [(set_attr "type" "alu")
8302 (set_attr "mode" "<MODE>")])
8303
8304 (define_insn "*<code>qi_ext_0"
8305 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8306 (const_int 8)
8307 (const_int 8))
8308 (any_or:SI
8309 (zero_extract:SI
8310 (match_operand 1 "ext_register_operand" "0")
8311 (const_int 8)
8312 (const_int 8))
8313 (match_operand 2 "const_int_operand" "n")))
8314 (clobber (reg:CC FLAGS_REG))]
8315 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8316 "<logic>{b}\t{%2, %h0|%h0, %2}"
8317 [(set_attr "type" "alu")
8318 (set_attr "length_immediate" "1")
8319 (set_attr "modrm" "1")
8320 (set_attr "mode" "QI")])
8321
8322 (define_insn "*<code>qi_ext_1_rex64"
8323 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8324 (const_int 8)
8325 (const_int 8))
8326 (any_or:SI
8327 (zero_extract:SI
8328 (match_operand 1 "ext_register_operand" "0")
8329 (const_int 8)
8330 (const_int 8))
8331 (zero_extend:SI
8332 (match_operand 2 "ext_register_operand" "Q"))))
8333 (clobber (reg:CC FLAGS_REG))]
8334 "TARGET_64BIT
8335 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8336 "<logic>{b}\t{%2, %h0|%h0, %2}"
8337 [(set_attr "type" "alu")
8338 (set_attr "length_immediate" "0")
8339 (set_attr "mode" "QI")])
8340
8341 (define_insn "*<code>qi_ext_1"
8342 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8343 (const_int 8)
8344 (const_int 8))
8345 (any_or:SI
8346 (zero_extract:SI
8347 (match_operand 1 "ext_register_operand" "0")
8348 (const_int 8)
8349 (const_int 8))
8350 (zero_extend:SI
8351 (match_operand:QI 2 "general_operand" "Qm"))))
8352 (clobber (reg:CC FLAGS_REG))]
8353 "!TARGET_64BIT
8354 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8355 "<logic>{b}\t{%2, %h0|%h0, %2}"
8356 [(set_attr "type" "alu")
8357 (set_attr "length_immediate" "0")
8358 (set_attr "mode" "QI")])
8359
8360 (define_insn "*<code>qi_ext_2"
8361 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8362 (const_int 8)
8363 (const_int 8))
8364 (any_or:SI
8365 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8366 (const_int 8)
8367 (const_int 8))
8368 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8369 (const_int 8)
8370 (const_int 8))))
8371 (clobber (reg:CC FLAGS_REG))]
8372 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8373 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8374 [(set_attr "type" "alu")
8375 (set_attr "length_immediate" "0")
8376 (set_attr "mode" "QI")])
8377
8378 (define_split
8379 [(set (match_operand 0 "register_operand" "")
8380 (any_or (match_operand 1 "register_operand" "")
8381 (match_operand 2 "const_int_operand" "")))
8382 (clobber (reg:CC FLAGS_REG))]
8383 "reload_completed
8384 && QI_REG_P (operands[0])
8385 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8386 && !(INTVAL (operands[2]) & ~(255 << 8))
8387 && GET_MODE (operands[0]) != QImode"
8388 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8389 (any_or:SI (zero_extract:SI (match_dup 1)
8390 (const_int 8) (const_int 8))
8391 (match_dup 2)))
8392 (clobber (reg:CC FLAGS_REG))])]
8393 "operands[0] = gen_lowpart (SImode, operands[0]);
8394 operands[1] = gen_lowpart (SImode, operands[1]);
8395 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8396
8397 ;; Since OR can be encoded with sign extended immediate, this is only
8398 ;; profitable when 7th bit is set.
8399 (define_split
8400 [(set (match_operand 0 "register_operand" "")
8401 (any_or (match_operand 1 "general_operand" "")
8402 (match_operand 2 "const_int_operand" "")))
8403 (clobber (reg:CC FLAGS_REG))]
8404 "reload_completed
8405 && ANY_QI_REG_P (operands[0])
8406 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8407 && !(INTVAL (operands[2]) & ~255)
8408 && (INTVAL (operands[2]) & 128)
8409 && GET_MODE (operands[0]) != QImode"
8410 [(parallel [(set (strict_low_part (match_dup 0))
8411 (any_or:QI (match_dup 1)
8412 (match_dup 2)))
8413 (clobber (reg:CC FLAGS_REG))])]
8414 "operands[0] = gen_lowpart (QImode, operands[0]);
8415 operands[1] = gen_lowpart (QImode, operands[1]);
8416 operands[2] = gen_lowpart (QImode, operands[2]);")
8417
8418 (define_expand "xorqi_cc_ext_1"
8419 [(parallel [
8420 (set (reg:CCNO FLAGS_REG)
8421 (compare:CCNO
8422 (xor:SI
8423 (zero_extract:SI
8424 (match_operand 1 "ext_register_operand" "")
8425 (const_int 8)
8426 (const_int 8))
8427 (match_operand:QI 2 "general_operand" ""))
8428 (const_int 0)))
8429 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8430 (const_int 8)
8431 (const_int 8))
8432 (xor:SI
8433 (zero_extract:SI
8434 (match_dup 1)
8435 (const_int 8)
8436 (const_int 8))
8437 (match_dup 2)))])])
8438
8439 (define_insn "*xorqi_cc_ext_1_rex64"
8440 [(set (reg FLAGS_REG)
8441 (compare
8442 (xor:SI
8443 (zero_extract:SI
8444 (match_operand 1 "ext_register_operand" "0")
8445 (const_int 8)
8446 (const_int 8))
8447 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8448 (const_int 0)))
8449 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8450 (const_int 8)
8451 (const_int 8))
8452 (xor:SI
8453 (zero_extract:SI
8454 (match_dup 1)
8455 (const_int 8)
8456 (const_int 8))
8457 (match_dup 2)))]
8458 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8459 "xor{b}\t{%2, %h0|%h0, %2}"
8460 [(set_attr "type" "alu")
8461 (set_attr "modrm" "1")
8462 (set_attr "mode" "QI")])
8463
8464 (define_insn "*xorqi_cc_ext_1"
8465 [(set (reg FLAGS_REG)
8466 (compare
8467 (xor:SI
8468 (zero_extract:SI
8469 (match_operand 1 "ext_register_operand" "0")
8470 (const_int 8)
8471 (const_int 8))
8472 (match_operand:QI 2 "general_operand" "qmn"))
8473 (const_int 0)))
8474 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8475 (const_int 8)
8476 (const_int 8))
8477 (xor:SI
8478 (zero_extract:SI
8479 (match_dup 1)
8480 (const_int 8)
8481 (const_int 8))
8482 (match_dup 2)))]
8483 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8484 "xor{b}\t{%2, %h0|%h0, %2}"
8485 [(set_attr "type" "alu")
8486 (set_attr "modrm" "1")
8487 (set_attr "mode" "QI")])
8488 \f
8489 ;; Negation instructions
8490
8491 (define_expand "neg<mode>2"
8492 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8493 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8494 ""
8495 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8496
8497 (define_insn_and_split "*neg<dwi>2_doubleword"
8498 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8499 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8500 (clobber (reg:CC FLAGS_REG))]
8501 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8502 "#"
8503 "reload_completed"
8504 [(parallel
8505 [(set (reg:CCZ FLAGS_REG)
8506 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8507 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8508 (parallel
8509 [(set (match_dup 2)
8510 (plus:DWIH (match_dup 3)
8511 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8512 (const_int 0))))
8513 (clobber (reg:CC FLAGS_REG))])
8514 (parallel
8515 [(set (match_dup 2)
8516 (neg:DWIH (match_dup 2)))
8517 (clobber (reg:CC FLAGS_REG))])]
8518 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8519
8520 (define_insn "*neg<mode>2_1"
8521 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8522 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8523 (clobber (reg:CC FLAGS_REG))]
8524 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8525 "neg{<imodesuffix>}\t%0"
8526 [(set_attr "type" "negnot")
8527 (set_attr "mode" "<MODE>")])
8528
8529 ;; Combine is quite creative about this pattern.
8530 (define_insn "*negsi2_1_zext"
8531 [(set (match_operand:DI 0 "register_operand" "=r")
8532 (lshiftrt:DI
8533 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8534 (const_int 32)))
8535 (const_int 32)))
8536 (clobber (reg:CC FLAGS_REG))]
8537 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8538 "neg{l}\t%k0"
8539 [(set_attr "type" "negnot")
8540 (set_attr "mode" "SI")])
8541
8542 ;; The problem with neg is that it does not perform (compare x 0),
8543 ;; it really performs (compare 0 x), which leaves us with the zero
8544 ;; flag being the only useful item.
8545
8546 (define_insn "*neg<mode>2_cmpz"
8547 [(set (reg:CCZ FLAGS_REG)
8548 (compare:CCZ
8549 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8550 (const_int 0)))
8551 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8552 (neg:SWI (match_dup 1)))]
8553 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8554 "neg{<imodesuffix>}\t%0"
8555 [(set_attr "type" "negnot")
8556 (set_attr "mode" "<MODE>")])
8557
8558 (define_insn "*negsi2_cmpz_zext"
8559 [(set (reg:CCZ FLAGS_REG)
8560 (compare:CCZ
8561 (lshiftrt:DI
8562 (neg:DI (ashift:DI
8563 (match_operand:DI 1 "register_operand" "0")
8564 (const_int 32)))
8565 (const_int 32))
8566 (const_int 0)))
8567 (set (match_operand:DI 0 "register_operand" "=r")
8568 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8569 (const_int 32)))
8570 (const_int 32)))]
8571 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8572 "neg{l}\t%k0"
8573 [(set_attr "type" "negnot")
8574 (set_attr "mode" "SI")])
8575
8576 ;; Changing of sign for FP values is doable using integer unit too.
8577
8578 (define_expand "<code><mode>2"
8579 [(set (match_operand:X87MODEF 0 "register_operand" "")
8580 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8581 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8582 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8583
8584 (define_insn "*absneg<mode>2_mixed"
8585 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8586 (match_operator:MODEF 3 "absneg_operator"
8587 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8588 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8589 (clobber (reg:CC FLAGS_REG))]
8590 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8591 "#")
8592
8593 (define_insn "*absneg<mode>2_sse"
8594 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8595 (match_operator:MODEF 3 "absneg_operator"
8596 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8597 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8598 (clobber (reg:CC FLAGS_REG))]
8599 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8600 "#")
8601
8602 (define_insn "*absneg<mode>2_i387"
8603 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8604 (match_operator:X87MODEF 3 "absneg_operator"
8605 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8606 (use (match_operand 2 "" ""))
8607 (clobber (reg:CC FLAGS_REG))]
8608 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8609 "#")
8610
8611 (define_expand "<code>tf2"
8612 [(set (match_operand:TF 0 "register_operand" "")
8613 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8614 "TARGET_SSE2"
8615 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8616
8617 (define_insn "*absnegtf2_sse"
8618 [(set (match_operand:TF 0 "register_operand" "=x,x")
8619 (match_operator:TF 3 "absneg_operator"
8620 [(match_operand:TF 1 "register_operand" "0,x")]))
8621 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8622 (clobber (reg:CC FLAGS_REG))]
8623 "TARGET_SSE2"
8624 "#")
8625
8626 ;; Splitters for fp abs and neg.
8627
8628 (define_split
8629 [(set (match_operand 0 "fp_register_operand" "")
8630 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8631 (use (match_operand 2 "" ""))
8632 (clobber (reg:CC FLAGS_REG))]
8633 "reload_completed"
8634 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8635
8636 (define_split
8637 [(set (match_operand 0 "register_operand" "")
8638 (match_operator 3 "absneg_operator"
8639 [(match_operand 1 "register_operand" "")]))
8640 (use (match_operand 2 "nonimmediate_operand" ""))
8641 (clobber (reg:CC FLAGS_REG))]
8642 "reload_completed && SSE_REG_P (operands[0])"
8643 [(set (match_dup 0) (match_dup 3))]
8644 {
8645 enum machine_mode mode = GET_MODE (operands[0]);
8646 enum machine_mode vmode = GET_MODE (operands[2]);
8647 rtx tmp;
8648
8649 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8650 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8651 if (operands_match_p (operands[0], operands[2]))
8652 {
8653 tmp = operands[1];
8654 operands[1] = operands[2];
8655 operands[2] = tmp;
8656 }
8657 if (GET_CODE (operands[3]) == ABS)
8658 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8659 else
8660 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8661 operands[3] = tmp;
8662 })
8663
8664 (define_split
8665 [(set (match_operand:SF 0 "register_operand" "")
8666 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8667 (use (match_operand:V4SF 2 "" ""))
8668 (clobber (reg:CC FLAGS_REG))]
8669 "reload_completed"
8670 [(parallel [(set (match_dup 0) (match_dup 1))
8671 (clobber (reg:CC FLAGS_REG))])]
8672 {
8673 rtx tmp;
8674 operands[0] = gen_lowpart (SImode, operands[0]);
8675 if (GET_CODE (operands[1]) == ABS)
8676 {
8677 tmp = gen_int_mode (0x7fffffff, SImode);
8678 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8679 }
8680 else
8681 {
8682 tmp = gen_int_mode (0x80000000, SImode);
8683 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8684 }
8685 operands[1] = tmp;
8686 })
8687
8688 (define_split
8689 [(set (match_operand:DF 0 "register_operand" "")
8690 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8691 (use (match_operand 2 "" ""))
8692 (clobber (reg:CC FLAGS_REG))]
8693 "reload_completed"
8694 [(parallel [(set (match_dup 0) (match_dup 1))
8695 (clobber (reg:CC FLAGS_REG))])]
8696 {
8697 rtx tmp;
8698 if (TARGET_64BIT)
8699 {
8700 tmp = gen_lowpart (DImode, operands[0]);
8701 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8702 operands[0] = tmp;
8703
8704 if (GET_CODE (operands[1]) == ABS)
8705 tmp = const0_rtx;
8706 else
8707 tmp = gen_rtx_NOT (DImode, tmp);
8708 }
8709 else
8710 {
8711 operands[0] = gen_highpart (SImode, operands[0]);
8712 if (GET_CODE (operands[1]) == ABS)
8713 {
8714 tmp = gen_int_mode (0x7fffffff, SImode);
8715 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8716 }
8717 else
8718 {
8719 tmp = gen_int_mode (0x80000000, SImode);
8720 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8721 }
8722 }
8723 operands[1] = tmp;
8724 })
8725
8726 (define_split
8727 [(set (match_operand:XF 0 "register_operand" "")
8728 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8729 (use (match_operand 2 "" ""))
8730 (clobber (reg:CC FLAGS_REG))]
8731 "reload_completed"
8732 [(parallel [(set (match_dup 0) (match_dup 1))
8733 (clobber (reg:CC FLAGS_REG))])]
8734 {
8735 rtx tmp;
8736 operands[0] = gen_rtx_REG (SImode,
8737 true_regnum (operands[0])
8738 + (TARGET_64BIT ? 1 : 2));
8739 if (GET_CODE (operands[1]) == ABS)
8740 {
8741 tmp = GEN_INT (0x7fff);
8742 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8743 }
8744 else
8745 {
8746 tmp = GEN_INT (0x8000);
8747 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8748 }
8749 operands[1] = tmp;
8750 })
8751
8752 ;; Conditionalize these after reload. If they match before reload, we
8753 ;; lose the clobber and ability to use integer instructions.
8754
8755 (define_insn "*<code><mode>2_1"
8756 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8757 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8758 "TARGET_80387
8759 && (reload_completed
8760 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8761 "f<absneg_mnemonic>"
8762 [(set_attr "type" "fsgn")
8763 (set_attr "mode" "<MODE>")])
8764
8765 (define_insn "*<code>extendsfdf2"
8766 [(set (match_operand:DF 0 "register_operand" "=f")
8767 (absneg:DF (float_extend:DF
8768 (match_operand:SF 1 "register_operand" "0"))))]
8769 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8770 "f<absneg_mnemonic>"
8771 [(set_attr "type" "fsgn")
8772 (set_attr "mode" "DF")])
8773
8774 (define_insn "*<code>extendsfxf2"
8775 [(set (match_operand:XF 0 "register_operand" "=f")
8776 (absneg:XF (float_extend:XF
8777 (match_operand:SF 1 "register_operand" "0"))))]
8778 "TARGET_80387"
8779 "f<absneg_mnemonic>"
8780 [(set_attr "type" "fsgn")
8781 (set_attr "mode" "XF")])
8782
8783 (define_insn "*<code>extenddfxf2"
8784 [(set (match_operand:XF 0 "register_operand" "=f")
8785 (absneg:XF (float_extend:XF
8786 (match_operand:DF 1 "register_operand" "0"))))]
8787 "TARGET_80387"
8788 "f<absneg_mnemonic>"
8789 [(set_attr "type" "fsgn")
8790 (set_attr "mode" "XF")])
8791
8792 ;; Copysign instructions
8793
8794 (define_mode_iterator CSGNMODE [SF DF TF])
8795 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8796
8797 (define_expand "copysign<mode>3"
8798 [(match_operand:CSGNMODE 0 "register_operand" "")
8799 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8800 (match_operand:CSGNMODE 2 "register_operand" "")]
8801 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8802 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8803 "ix86_expand_copysign (operands); DONE;")
8804
8805 (define_insn_and_split "copysign<mode>3_const"
8806 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8807 (unspec:CSGNMODE
8808 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8809 (match_operand:CSGNMODE 2 "register_operand" "0")
8810 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8811 UNSPEC_COPYSIGN))]
8812 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8813 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8814 "#"
8815 "&& reload_completed"
8816 [(const_int 0)]
8817 "ix86_split_copysign_const (operands); DONE;")
8818
8819 (define_insn "copysign<mode>3_var"
8820 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8821 (unspec:CSGNMODE
8822 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8823 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8824 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8825 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8826 UNSPEC_COPYSIGN))
8827 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8828 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8829 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8830 "#")
8831
8832 (define_split
8833 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8834 (unspec:CSGNMODE
8835 [(match_operand:CSGNMODE 2 "register_operand" "")
8836 (match_operand:CSGNMODE 3 "register_operand" "")
8837 (match_operand:<CSGNVMODE> 4 "" "")
8838 (match_operand:<CSGNVMODE> 5 "" "")]
8839 UNSPEC_COPYSIGN))
8840 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8841 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8842 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8843 && reload_completed"
8844 [(const_int 0)]
8845 "ix86_split_copysign_var (operands); DONE;")
8846 \f
8847 ;; One complement instructions
8848
8849 (define_expand "one_cmpl<mode>2"
8850 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8851 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8852 ""
8853 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8854
8855 (define_insn "*one_cmpl<mode>2_1"
8856 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8857 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8858 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8859 "not{<imodesuffix>}\t%0"
8860 [(set_attr "type" "negnot")
8861 (set_attr "mode" "<MODE>")])
8862
8863 ;; %%% Potential partial reg stall on alternative 1. What to do?
8864 (define_insn "*one_cmplqi2_1"
8865 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8866 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8867 "ix86_unary_operator_ok (NOT, QImode, operands)"
8868 "@
8869 not{b}\t%0
8870 not{l}\t%k0"
8871 [(set_attr "type" "negnot")
8872 (set_attr "mode" "QI,SI")])
8873
8874 ;; ??? Currently never generated - xor is used instead.
8875 (define_insn "*one_cmplsi2_1_zext"
8876 [(set (match_operand:DI 0 "register_operand" "=r")
8877 (zero_extend:DI
8878 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8879 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8880 "not{l}\t%k0"
8881 [(set_attr "type" "negnot")
8882 (set_attr "mode" "SI")])
8883
8884 (define_insn "*one_cmpl<mode>2_2"
8885 [(set (reg FLAGS_REG)
8886 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8887 (const_int 0)))
8888 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8889 (not:SWI (match_dup 1)))]
8890 "ix86_match_ccmode (insn, CCNOmode)
8891 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8892 "#"
8893 [(set_attr "type" "alu1")
8894 (set_attr "mode" "<MODE>")])
8895
8896 (define_split
8897 [(set (match_operand 0 "flags_reg_operand" "")
8898 (match_operator 2 "compare_operator"
8899 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8900 (const_int 0)]))
8901 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8902 (not:SWI (match_dup 3)))]
8903 "ix86_match_ccmode (insn, CCNOmode)"
8904 [(parallel [(set (match_dup 0)
8905 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8906 (const_int 0)]))
8907 (set (match_dup 1)
8908 (xor:SWI (match_dup 3) (const_int -1)))])])
8909
8910 ;; ??? Currently never generated - xor is used instead.
8911 (define_insn "*one_cmplsi2_2_zext"
8912 [(set (reg FLAGS_REG)
8913 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8914 (const_int 0)))
8915 (set (match_operand:DI 0 "register_operand" "=r")
8916 (zero_extend:DI (not:SI (match_dup 1))))]
8917 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8918 && ix86_unary_operator_ok (NOT, SImode, operands)"
8919 "#"
8920 [(set_attr "type" "alu1")
8921 (set_attr "mode" "SI")])
8922
8923 (define_split
8924 [(set (match_operand 0 "flags_reg_operand" "")
8925 (match_operator 2 "compare_operator"
8926 [(not:SI (match_operand:SI 3 "register_operand" ""))
8927 (const_int 0)]))
8928 (set (match_operand:DI 1 "register_operand" "")
8929 (zero_extend:DI (not:SI (match_dup 3))))]
8930 "ix86_match_ccmode (insn, CCNOmode)"
8931 [(parallel [(set (match_dup 0)
8932 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8933 (const_int 0)]))
8934 (set (match_dup 1)
8935 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8936 \f
8937 ;; Shift instructions
8938
8939 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8940 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8941 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8942 ;; from the assembler input.
8943 ;;
8944 ;; This instruction shifts the target reg/mem as usual, but instead of
8945 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8946 ;; is a left shift double, bits are taken from the high order bits of
8947 ;; reg, else if the insn is a shift right double, bits are taken from the
8948 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8949 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8950 ;;
8951 ;; Since sh[lr]d does not change the `reg' operand, that is done
8952 ;; separately, making all shifts emit pairs of shift double and normal
8953 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8954 ;; support a 63 bit shift, each shift where the count is in a reg expands
8955 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8956 ;;
8957 ;; If the shift count is a constant, we need never emit more than one
8958 ;; shift pair, instead using moves and sign extension for counts greater
8959 ;; than 31.
8960
8961 (define_expand "ashl<mode>3"
8962 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8963 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8964 (match_operand:QI 2 "nonmemory_operand" "")))]
8965 ""
8966 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8967
8968 (define_insn "*ashl<mode>3_doubleword"
8969 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8970 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8971 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8972 (clobber (reg:CC FLAGS_REG))]
8973 ""
8974 "#"
8975 [(set_attr "type" "multi")])
8976
8977 (define_split
8978 [(set (match_operand:DWI 0 "register_operand" "")
8979 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8980 (match_operand:QI 2 "nonmemory_operand" "")))
8981 (clobber (reg:CC FLAGS_REG))]
8982 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8983 [(const_int 0)]
8984 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8985
8986 ;; By default we don't ask for a scratch register, because when DWImode
8987 ;; values are manipulated, registers are already at a premium. But if
8988 ;; we have one handy, we won't turn it away.
8989
8990 (define_peephole2
8991 [(match_scratch:DWIH 3 "r")
8992 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8993 (ashift:<DWI>
8994 (match_operand:<DWI> 1 "nonmemory_operand" "")
8995 (match_operand:QI 2 "nonmemory_operand" "")))
8996 (clobber (reg:CC FLAGS_REG))])
8997 (match_dup 3)]
8998 "TARGET_CMOVE"
8999 [(const_int 0)]
9000 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9001
9002 (define_insn "x86_64_shld"
9003 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9004 (ior:DI (ashift:DI (match_dup 0)
9005 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9006 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9007 (minus:QI (const_int 64) (match_dup 2)))))
9008 (clobber (reg:CC FLAGS_REG))]
9009 "TARGET_64BIT"
9010 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9011 [(set_attr "type" "ishift")
9012 (set_attr "prefix_0f" "1")
9013 (set_attr "mode" "DI")
9014 (set_attr "athlon_decode" "vector")
9015 (set_attr "amdfam10_decode" "vector")
9016 (set_attr "bdver1_decode" "vector")])
9017
9018 (define_insn "x86_shld"
9019 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9020 (ior:SI (ashift:SI (match_dup 0)
9021 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9022 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9023 (minus:QI (const_int 32) (match_dup 2)))))
9024 (clobber (reg:CC FLAGS_REG))]
9025 ""
9026 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9027 [(set_attr "type" "ishift")
9028 (set_attr "prefix_0f" "1")
9029 (set_attr "mode" "SI")
9030 (set_attr "pent_pair" "np")
9031 (set_attr "athlon_decode" "vector")
9032 (set_attr "amdfam10_decode" "vector")
9033 (set_attr "bdver1_decode" "vector")])
9034
9035 (define_expand "x86_shift<mode>_adj_1"
9036 [(set (reg:CCZ FLAGS_REG)
9037 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9038 (match_dup 4))
9039 (const_int 0)))
9040 (set (match_operand:SWI48 0 "register_operand" "")
9041 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9042 (match_operand:SWI48 1 "register_operand" "")
9043 (match_dup 0)))
9044 (set (match_dup 1)
9045 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9046 (match_operand:SWI48 3 "register_operand" "r")
9047 (match_dup 1)))]
9048 "TARGET_CMOVE"
9049 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9050
9051 (define_expand "x86_shift<mode>_adj_2"
9052 [(use (match_operand:SWI48 0 "register_operand" ""))
9053 (use (match_operand:SWI48 1 "register_operand" ""))
9054 (use (match_operand:QI 2 "register_operand" ""))]
9055 ""
9056 {
9057 rtx label = gen_label_rtx ();
9058 rtx tmp;
9059
9060 emit_insn (gen_testqi_ccz_1 (operands[2],
9061 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9062
9063 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9064 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9065 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9066 gen_rtx_LABEL_REF (VOIDmode, label),
9067 pc_rtx);
9068 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9069 JUMP_LABEL (tmp) = label;
9070
9071 emit_move_insn (operands[0], operands[1]);
9072 ix86_expand_clear (operands[1]);
9073
9074 emit_label (label);
9075 LABEL_NUSES (label) = 1;
9076
9077 DONE;
9078 })
9079
9080 ;; Avoid useless masking of count operand.
9081 (define_insn_and_split "*ashl<mode>3_mask"
9082 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9083 (ashift:SWI48
9084 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9085 (subreg:QI
9086 (and:SI
9087 (match_operand:SI 2 "nonimmediate_operand" "c")
9088 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9089 (clobber (reg:CC FLAGS_REG))]
9090 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9091 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9092 == GET_MODE_BITSIZE (<MODE>mode)-1"
9093 "#"
9094 "&& 1"
9095 [(parallel [(set (match_dup 0)
9096 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9097 (clobber (reg:CC FLAGS_REG))])]
9098 {
9099 if (can_create_pseudo_p ())
9100 operands [2] = force_reg (SImode, operands[2]);
9101
9102 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9103 }
9104 [(set_attr "type" "ishift")
9105 (set_attr "mode" "<MODE>")])
9106
9107 (define_insn "*bmi2_ashl<mode>3_1"
9108 [(set (match_operand:SWI48 0 "register_operand" "=r")
9109 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9110 (match_operand:SWI48 2 "register_operand" "r")))]
9111 "TARGET_BMI2"
9112 "shlx\t{%2, %1, %0|%0, %1, %2}"
9113 [(set_attr "type" "ishiftx")
9114 (set_attr "mode" "<MODE>")])
9115
9116 (define_insn "*ashl<mode>3_1"
9117 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9118 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9119 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9120 (clobber (reg:CC FLAGS_REG))]
9121 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9122 {
9123 switch (get_attr_type (insn))
9124 {
9125 case TYPE_LEA:
9126 case TYPE_ISHIFTX:
9127 return "#";
9128
9129 case TYPE_ALU:
9130 gcc_assert (operands[2] == const1_rtx);
9131 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9132 return "add{<imodesuffix>}\t%0, %0";
9133
9134 default:
9135 if (operands[2] == const1_rtx
9136 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9137 return "sal{<imodesuffix>}\t%0";
9138 else
9139 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9140 }
9141 }
9142 [(set_attr "isa" "*,*,bmi2")
9143 (set (attr "type")
9144 (cond [(eq_attr "alternative" "1")
9145 (const_string "lea")
9146 (eq_attr "alternative" "2")
9147 (const_string "ishiftx")
9148 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9149 (match_operand 0 "register_operand" ""))
9150 (match_operand 2 "const1_operand" ""))
9151 (const_string "alu")
9152 ]
9153 (const_string "ishift")))
9154 (set (attr "length_immediate")
9155 (if_then_else
9156 (ior (eq_attr "type" "alu")
9157 (and (eq_attr "type" "ishift")
9158 (and (match_operand 2 "const1_operand" "")
9159 (ior (match_test "TARGET_SHIFT1")
9160 (match_test "optimize_function_for_size_p (cfun)")))))
9161 (const_string "0")
9162 (const_string "*")))
9163 (set_attr "mode" "<MODE>")])
9164
9165 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9166 (define_split
9167 [(set (match_operand:SWI48 0 "register_operand" "")
9168 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9169 (match_operand:QI 2 "register_operand" "")))
9170 (clobber (reg:CC FLAGS_REG))]
9171 "TARGET_BMI2 && reload_completed"
9172 [(set (match_dup 0)
9173 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9174 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9175
9176 (define_insn "*bmi2_ashlsi3_1_zext"
9177 [(set (match_operand:DI 0 "register_operand" "=r")
9178 (zero_extend:DI
9179 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9180 (match_operand:SI 2 "register_operand" "r"))))]
9181 "TARGET_64BIT && TARGET_BMI2"
9182 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9183 [(set_attr "type" "ishiftx")
9184 (set_attr "mode" "SI")])
9185
9186 (define_insn "*ashlsi3_1_zext"
9187 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9188 (zero_extend:DI
9189 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9190 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9191 (clobber (reg:CC FLAGS_REG))]
9192 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9193 {
9194 switch (get_attr_type (insn))
9195 {
9196 case TYPE_LEA:
9197 case TYPE_ISHIFTX:
9198 return "#";
9199
9200 case TYPE_ALU:
9201 gcc_assert (operands[2] == const1_rtx);
9202 return "add{l}\t%k0, %k0";
9203
9204 default:
9205 if (operands[2] == const1_rtx
9206 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9207 return "sal{l}\t%k0";
9208 else
9209 return "sal{l}\t{%2, %k0|%k0, %2}";
9210 }
9211 }
9212 [(set_attr "isa" "*,*,bmi2")
9213 (set (attr "type")
9214 (cond [(eq_attr "alternative" "1")
9215 (const_string "lea")
9216 (eq_attr "alternative" "2")
9217 (const_string "ishiftx")
9218 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9219 (match_operand 2 "const1_operand" ""))
9220 (const_string "alu")
9221 ]
9222 (const_string "ishift")))
9223 (set (attr "length_immediate")
9224 (if_then_else
9225 (ior (eq_attr "type" "alu")
9226 (and (eq_attr "type" "ishift")
9227 (and (match_operand 2 "const1_operand" "")
9228 (ior (match_test "TARGET_SHIFT1")
9229 (match_test "optimize_function_for_size_p (cfun)")))))
9230 (const_string "0")
9231 (const_string "*")))
9232 (set_attr "mode" "SI")])
9233
9234 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9235 (define_split
9236 [(set (match_operand:DI 0 "register_operand" "")
9237 (zero_extend:DI
9238 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9239 (match_operand:QI 2 "register_operand" ""))))
9240 (clobber (reg:CC FLAGS_REG))]
9241 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9242 [(set (match_dup 0)
9243 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9244 "operands[2] = gen_lowpart (SImode, operands[2]);")
9245
9246 (define_insn "*ashlhi3_1"
9247 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9248 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9249 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9250 (clobber (reg:CC FLAGS_REG))]
9251 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9252 {
9253 switch (get_attr_type (insn))
9254 {
9255 case TYPE_LEA:
9256 return "#";
9257
9258 case TYPE_ALU:
9259 gcc_assert (operands[2] == const1_rtx);
9260 return "add{w}\t%0, %0";
9261
9262 default:
9263 if (operands[2] == const1_rtx
9264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265 return "sal{w}\t%0";
9266 else
9267 return "sal{w}\t{%2, %0|%0, %2}";
9268 }
9269 }
9270 [(set (attr "type")
9271 (cond [(eq_attr "alternative" "1")
9272 (const_string "lea")
9273 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9274 (match_operand 0 "register_operand" ""))
9275 (match_operand 2 "const1_operand" ""))
9276 (const_string "alu")
9277 ]
9278 (const_string "ishift")))
9279 (set (attr "length_immediate")
9280 (if_then_else
9281 (ior (eq_attr "type" "alu")
9282 (and (eq_attr "type" "ishift")
9283 (and (match_operand 2 "const1_operand" "")
9284 (ior (match_test "TARGET_SHIFT1")
9285 (match_test "optimize_function_for_size_p (cfun)")))))
9286 (const_string "0")
9287 (const_string "*")))
9288 (set_attr "mode" "HI,SI")])
9289
9290 ;; %%% Potential partial reg stall on alternative 1. What to do?
9291 (define_insn "*ashlqi3_1"
9292 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9293 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9294 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9295 (clobber (reg:CC FLAGS_REG))]
9296 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9297 {
9298 switch (get_attr_type (insn))
9299 {
9300 case TYPE_LEA:
9301 return "#";
9302
9303 case TYPE_ALU:
9304 gcc_assert (operands[2] == const1_rtx);
9305 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9306 return "add{l}\t%k0, %k0";
9307 else
9308 return "add{b}\t%0, %0";
9309
9310 default:
9311 if (operands[2] == const1_rtx
9312 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9313 {
9314 if (get_attr_mode (insn) == MODE_SI)
9315 return "sal{l}\t%k0";
9316 else
9317 return "sal{b}\t%0";
9318 }
9319 else
9320 {
9321 if (get_attr_mode (insn) == MODE_SI)
9322 return "sal{l}\t{%2, %k0|%k0, %2}";
9323 else
9324 return "sal{b}\t{%2, %0|%0, %2}";
9325 }
9326 }
9327 }
9328 [(set (attr "type")
9329 (cond [(eq_attr "alternative" "2")
9330 (const_string "lea")
9331 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9332 (match_operand 0 "register_operand" ""))
9333 (match_operand 2 "const1_operand" ""))
9334 (const_string "alu")
9335 ]
9336 (const_string "ishift")))
9337 (set (attr "length_immediate")
9338 (if_then_else
9339 (ior (eq_attr "type" "alu")
9340 (and (eq_attr "type" "ishift")
9341 (and (match_operand 2 "const1_operand" "")
9342 (ior (match_test "TARGET_SHIFT1")
9343 (match_test "optimize_function_for_size_p (cfun)")))))
9344 (const_string "0")
9345 (const_string "*")))
9346 (set_attr "mode" "QI,SI,SI")])
9347
9348 (define_insn "*ashlqi3_1_slp"
9349 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9350 (ashift:QI (match_dup 0)
9351 (match_operand:QI 1 "nonmemory_operand" "cI")))
9352 (clobber (reg:CC FLAGS_REG))]
9353 "(optimize_function_for_size_p (cfun)
9354 || !TARGET_PARTIAL_FLAG_REG_STALL
9355 || (operands[1] == const1_rtx
9356 && (TARGET_SHIFT1
9357 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9358 {
9359 switch (get_attr_type (insn))
9360 {
9361 case TYPE_ALU:
9362 gcc_assert (operands[1] == const1_rtx);
9363 return "add{b}\t%0, %0";
9364
9365 default:
9366 if (operands[1] == const1_rtx
9367 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9368 return "sal{b}\t%0";
9369 else
9370 return "sal{b}\t{%1, %0|%0, %1}";
9371 }
9372 }
9373 [(set (attr "type")
9374 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9375 (match_operand 0 "register_operand" ""))
9376 (match_operand 1 "const1_operand" ""))
9377 (const_string "alu")
9378 ]
9379 (const_string "ishift1")))
9380 (set (attr "length_immediate")
9381 (if_then_else
9382 (ior (eq_attr "type" "alu")
9383 (and (eq_attr "type" "ishift1")
9384 (and (match_operand 1 "const1_operand" "")
9385 (ior (match_test "TARGET_SHIFT1")
9386 (match_test "optimize_function_for_size_p (cfun)")))))
9387 (const_string "0")
9388 (const_string "*")))
9389 (set_attr "mode" "QI")])
9390
9391 ;; Convert ashift to the lea pattern to avoid flags dependency.
9392 (define_split
9393 [(set (match_operand 0 "register_operand" "")
9394 (ashift (match_operand 1 "index_register_operand" "")
9395 (match_operand:QI 2 "const_int_operand" "")))
9396 (clobber (reg:CC FLAGS_REG))]
9397 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9398 && reload_completed
9399 && true_regnum (operands[0]) != true_regnum (operands[1])"
9400 [(const_int 0)]
9401 {
9402 enum machine_mode mode = GET_MODE (operands[0]);
9403 rtx pat;
9404
9405 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9406 {
9407 mode = SImode;
9408 operands[0] = gen_lowpart (mode, operands[0]);
9409 operands[1] = gen_lowpart (mode, operands[1]);
9410 }
9411
9412 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9413
9414 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9415
9416 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9417 DONE;
9418 })
9419
9420 ;; Convert ashift to the lea pattern to avoid flags dependency.
9421 (define_split
9422 [(set (match_operand:DI 0 "register_operand" "")
9423 (zero_extend:DI
9424 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9425 (match_operand:QI 2 "const_int_operand" ""))))
9426 (clobber (reg:CC FLAGS_REG))]
9427 "TARGET_64BIT && reload_completed
9428 && true_regnum (operands[0]) != true_regnum (operands[1])"
9429 [(set (match_dup 0)
9430 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9431 {
9432 operands[1] = gen_lowpart (DImode, operands[1]);
9433 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9434 })
9435
9436 ;; This pattern can't accept a variable shift count, since shifts by
9437 ;; zero don't affect the flags. We assume that shifts by constant
9438 ;; zero are optimized away.
9439 (define_insn "*ashl<mode>3_cmp"
9440 [(set (reg FLAGS_REG)
9441 (compare
9442 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9443 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9444 (const_int 0)))
9445 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9446 (ashift:SWI (match_dup 1) (match_dup 2)))]
9447 "(optimize_function_for_size_p (cfun)
9448 || !TARGET_PARTIAL_FLAG_REG_STALL
9449 || (operands[2] == const1_rtx
9450 && (TARGET_SHIFT1
9451 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9452 && ix86_match_ccmode (insn, CCGOCmode)
9453 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9454 {
9455 switch (get_attr_type (insn))
9456 {
9457 case TYPE_ALU:
9458 gcc_assert (operands[2] == const1_rtx);
9459 return "add{<imodesuffix>}\t%0, %0";
9460
9461 default:
9462 if (operands[2] == const1_rtx
9463 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9464 return "sal{<imodesuffix>}\t%0";
9465 else
9466 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9467 }
9468 }
9469 [(set (attr "type")
9470 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9471 (match_operand 0 "register_operand" ""))
9472 (match_operand 2 "const1_operand" ""))
9473 (const_string "alu")
9474 ]
9475 (const_string "ishift")))
9476 (set (attr "length_immediate")
9477 (if_then_else
9478 (ior (eq_attr "type" "alu")
9479 (and (eq_attr "type" "ishift")
9480 (and (match_operand 2 "const1_operand" "")
9481 (ior (match_test "TARGET_SHIFT1")
9482 (match_test "optimize_function_for_size_p (cfun)")))))
9483 (const_string "0")
9484 (const_string "*")))
9485 (set_attr "mode" "<MODE>")])
9486
9487 (define_insn "*ashlsi3_cmp_zext"
9488 [(set (reg FLAGS_REG)
9489 (compare
9490 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9491 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9492 (const_int 0)))
9493 (set (match_operand:DI 0 "register_operand" "=r")
9494 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9495 "TARGET_64BIT
9496 && (optimize_function_for_size_p (cfun)
9497 || !TARGET_PARTIAL_FLAG_REG_STALL
9498 || (operands[2] == const1_rtx
9499 && (TARGET_SHIFT1
9500 || TARGET_DOUBLE_WITH_ADD)))
9501 && ix86_match_ccmode (insn, CCGOCmode)
9502 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9503 {
9504 switch (get_attr_type (insn))
9505 {
9506 case TYPE_ALU:
9507 gcc_assert (operands[2] == const1_rtx);
9508 return "add{l}\t%k0, %k0";
9509
9510 default:
9511 if (operands[2] == const1_rtx
9512 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9513 return "sal{l}\t%k0";
9514 else
9515 return "sal{l}\t{%2, %k0|%k0, %2}";
9516 }
9517 }
9518 [(set (attr "type")
9519 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9520 (match_operand 2 "const1_operand" ""))
9521 (const_string "alu")
9522 ]
9523 (const_string "ishift")))
9524 (set (attr "length_immediate")
9525 (if_then_else
9526 (ior (eq_attr "type" "alu")
9527 (and (eq_attr "type" "ishift")
9528 (and (match_operand 2 "const1_operand" "")
9529 (ior (match_test "TARGET_SHIFT1")
9530 (match_test "optimize_function_for_size_p (cfun)")))))
9531 (const_string "0")
9532 (const_string "*")))
9533 (set_attr "mode" "SI")])
9534
9535 (define_insn "*ashl<mode>3_cconly"
9536 [(set (reg FLAGS_REG)
9537 (compare
9538 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9539 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9540 (const_int 0)))
9541 (clobber (match_scratch:SWI 0 "=<r>"))]
9542 "(optimize_function_for_size_p (cfun)
9543 || !TARGET_PARTIAL_FLAG_REG_STALL
9544 || (operands[2] == const1_rtx
9545 && (TARGET_SHIFT1
9546 || TARGET_DOUBLE_WITH_ADD)))
9547 && ix86_match_ccmode (insn, CCGOCmode)"
9548 {
9549 switch (get_attr_type (insn))
9550 {
9551 case TYPE_ALU:
9552 gcc_assert (operands[2] == const1_rtx);
9553 return "add{<imodesuffix>}\t%0, %0";
9554
9555 default:
9556 if (operands[2] == const1_rtx
9557 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9558 return "sal{<imodesuffix>}\t%0";
9559 else
9560 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9561 }
9562 }
9563 [(set (attr "type")
9564 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9565 (match_operand 0 "register_operand" ""))
9566 (match_operand 2 "const1_operand" ""))
9567 (const_string "alu")
9568 ]
9569 (const_string "ishift")))
9570 (set (attr "length_immediate")
9571 (if_then_else
9572 (ior (eq_attr "type" "alu")
9573 (and (eq_attr "type" "ishift")
9574 (and (match_operand 2 "const1_operand" "")
9575 (ior (match_test "TARGET_SHIFT1")
9576 (match_test "optimize_function_for_size_p (cfun)")))))
9577 (const_string "0")
9578 (const_string "*")))
9579 (set_attr "mode" "<MODE>")])
9580
9581 ;; See comment above `ashl<mode>3' about how this works.
9582
9583 (define_expand "<shift_insn><mode>3"
9584 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9585 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9586 (match_operand:QI 2 "nonmemory_operand" "")))]
9587 ""
9588 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9589
9590 ;; Avoid useless masking of count operand.
9591 (define_insn_and_split "*<shift_insn><mode>3_mask"
9592 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9593 (any_shiftrt:SWI48
9594 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9595 (subreg:QI
9596 (and:SI
9597 (match_operand:SI 2 "nonimmediate_operand" "c")
9598 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9599 (clobber (reg:CC FLAGS_REG))]
9600 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9601 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9602 == GET_MODE_BITSIZE (<MODE>mode)-1"
9603 "#"
9604 "&& 1"
9605 [(parallel [(set (match_dup 0)
9606 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9607 (clobber (reg:CC FLAGS_REG))])]
9608 {
9609 if (can_create_pseudo_p ())
9610 operands [2] = force_reg (SImode, operands[2]);
9611
9612 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9613 }
9614 [(set_attr "type" "ishift")
9615 (set_attr "mode" "<MODE>")])
9616
9617 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9618 [(set (match_operand:DWI 0 "register_operand" "=r")
9619 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9620 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9621 (clobber (reg:CC FLAGS_REG))]
9622 ""
9623 "#"
9624 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9625 [(const_int 0)]
9626 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9627 [(set_attr "type" "multi")])
9628
9629 ;; By default we don't ask for a scratch register, because when DWImode
9630 ;; values are manipulated, registers are already at a premium. But if
9631 ;; we have one handy, we won't turn it away.
9632
9633 (define_peephole2
9634 [(match_scratch:DWIH 3 "r")
9635 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9636 (any_shiftrt:<DWI>
9637 (match_operand:<DWI> 1 "register_operand" "")
9638 (match_operand:QI 2 "nonmemory_operand" "")))
9639 (clobber (reg:CC FLAGS_REG))])
9640 (match_dup 3)]
9641 "TARGET_CMOVE"
9642 [(const_int 0)]
9643 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9644
9645 (define_insn "x86_64_shrd"
9646 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9647 (ior:DI (ashiftrt:DI (match_dup 0)
9648 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9649 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9650 (minus:QI (const_int 64) (match_dup 2)))))
9651 (clobber (reg:CC FLAGS_REG))]
9652 "TARGET_64BIT"
9653 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9654 [(set_attr "type" "ishift")
9655 (set_attr "prefix_0f" "1")
9656 (set_attr "mode" "DI")
9657 (set_attr "athlon_decode" "vector")
9658 (set_attr "amdfam10_decode" "vector")
9659 (set_attr "bdver1_decode" "vector")])
9660
9661 (define_insn "x86_shrd"
9662 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9663 (ior:SI (ashiftrt:SI (match_dup 0)
9664 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9665 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9666 (minus:QI (const_int 32) (match_dup 2)))))
9667 (clobber (reg:CC FLAGS_REG))]
9668 ""
9669 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9670 [(set_attr "type" "ishift")
9671 (set_attr "prefix_0f" "1")
9672 (set_attr "mode" "SI")
9673 (set_attr "pent_pair" "np")
9674 (set_attr "athlon_decode" "vector")
9675 (set_attr "amdfam10_decode" "vector")
9676 (set_attr "bdver1_decode" "vector")])
9677
9678 (define_insn "ashrdi3_cvt"
9679 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9680 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9681 (match_operand:QI 2 "const_int_operand" "")))
9682 (clobber (reg:CC FLAGS_REG))]
9683 "TARGET_64BIT && INTVAL (operands[2]) == 63
9684 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9685 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9686 "@
9687 {cqto|cqo}
9688 sar{q}\t{%2, %0|%0, %2}"
9689 [(set_attr "type" "imovx,ishift")
9690 (set_attr "prefix_0f" "0,*")
9691 (set_attr "length_immediate" "0,*")
9692 (set_attr "modrm" "0,1")
9693 (set_attr "mode" "DI")])
9694
9695 (define_insn "ashrsi3_cvt"
9696 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9697 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9698 (match_operand:QI 2 "const_int_operand" "")))
9699 (clobber (reg:CC FLAGS_REG))]
9700 "INTVAL (operands[2]) == 31
9701 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9702 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9703 "@
9704 {cltd|cdq}
9705 sar{l}\t{%2, %0|%0, %2}"
9706 [(set_attr "type" "imovx,ishift")
9707 (set_attr "prefix_0f" "0,*")
9708 (set_attr "length_immediate" "0,*")
9709 (set_attr "modrm" "0,1")
9710 (set_attr "mode" "SI")])
9711
9712 (define_insn "*ashrsi3_cvt_zext"
9713 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9714 (zero_extend:DI
9715 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9716 (match_operand:QI 2 "const_int_operand" ""))))
9717 (clobber (reg:CC FLAGS_REG))]
9718 "TARGET_64BIT && INTVAL (operands[2]) == 31
9719 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9720 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9721 "@
9722 {cltd|cdq}
9723 sar{l}\t{%2, %k0|%k0, %2}"
9724 [(set_attr "type" "imovx,ishift")
9725 (set_attr "prefix_0f" "0,*")
9726 (set_attr "length_immediate" "0,*")
9727 (set_attr "modrm" "0,1")
9728 (set_attr "mode" "SI")])
9729
9730 (define_expand "x86_shift<mode>_adj_3"
9731 [(use (match_operand:SWI48 0 "register_operand" ""))
9732 (use (match_operand:SWI48 1 "register_operand" ""))
9733 (use (match_operand:QI 2 "register_operand" ""))]
9734 ""
9735 {
9736 rtx label = gen_label_rtx ();
9737 rtx tmp;
9738
9739 emit_insn (gen_testqi_ccz_1 (operands[2],
9740 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9741
9742 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9743 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9744 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9745 gen_rtx_LABEL_REF (VOIDmode, label),
9746 pc_rtx);
9747 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9748 JUMP_LABEL (tmp) = label;
9749
9750 emit_move_insn (operands[0], operands[1]);
9751 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9752 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9753 emit_label (label);
9754 LABEL_NUSES (label) = 1;
9755
9756 DONE;
9757 })
9758
9759 (define_insn "*bmi2_<shift_insn><mode>3_1"
9760 [(set (match_operand:SWI48 0 "register_operand" "=r")
9761 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9762 (match_operand:SWI48 2 "register_operand" "r")))]
9763 "TARGET_BMI2"
9764 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9765 [(set_attr "type" "ishiftx")
9766 (set_attr "mode" "<MODE>")])
9767
9768 (define_insn "*<shift_insn><mode>3_1"
9769 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9770 (any_shiftrt:SWI48
9771 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9772 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9773 (clobber (reg:CC FLAGS_REG))]
9774 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9775 {
9776 switch (get_attr_type (insn))
9777 {
9778 case TYPE_ISHIFTX:
9779 return "#";
9780
9781 default:
9782 if (operands[2] == const1_rtx
9783 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9784 return "<shift>{<imodesuffix>}\t%0";
9785 else
9786 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9787 }
9788 }
9789 [(set_attr "isa" "*,bmi2")
9790 (set_attr "type" "ishift,ishiftx")
9791 (set (attr "length_immediate")
9792 (if_then_else
9793 (and (match_operand 2 "const1_operand" "")
9794 (ior (match_test "TARGET_SHIFT1")
9795 (match_test "optimize_function_for_size_p (cfun)")))
9796 (const_string "0")
9797 (const_string "*")))
9798 (set_attr "mode" "<MODE>")])
9799
9800 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9801 (define_split
9802 [(set (match_operand:SWI48 0 "register_operand" "")
9803 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9804 (match_operand:QI 2 "register_operand" "")))
9805 (clobber (reg:CC FLAGS_REG))]
9806 "TARGET_BMI2 && reload_completed"
9807 [(set (match_dup 0)
9808 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9809 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9810
9811 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9812 [(set (match_operand:DI 0 "register_operand" "=r")
9813 (zero_extend:DI
9814 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9815 (match_operand:SI 2 "register_operand" "r"))))]
9816 "TARGET_64BIT && TARGET_BMI2"
9817 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9818 [(set_attr "type" "ishiftx")
9819 (set_attr "mode" "SI")])
9820
9821 (define_insn "*<shift_insn>si3_1_zext"
9822 [(set (match_operand:DI 0 "register_operand" "=r,r")
9823 (zero_extend:DI
9824 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9825 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9826 (clobber (reg:CC FLAGS_REG))]
9827 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9828 {
9829 switch (get_attr_type (insn))
9830 {
9831 case TYPE_ISHIFTX:
9832 return "#";
9833
9834 default:
9835 if (operands[2] == const1_rtx
9836 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9837 return "<shift>{l}\t%k0";
9838 else
9839 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9840 }
9841 }
9842 [(set_attr "isa" "*,bmi2")
9843 (set_attr "type" "ishift,ishiftx")
9844 (set (attr "length_immediate")
9845 (if_then_else
9846 (and (match_operand 2 "const1_operand" "")
9847 (ior (match_test "TARGET_SHIFT1")
9848 (match_test "optimize_function_for_size_p (cfun)")))
9849 (const_string "0")
9850 (const_string "*")))
9851 (set_attr "mode" "SI")])
9852
9853 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9854 (define_split
9855 [(set (match_operand:DI 0 "register_operand" "")
9856 (zero_extend:DI
9857 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9858 (match_operand:QI 2 "register_operand" ""))))
9859 (clobber (reg:CC FLAGS_REG))]
9860 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9861 [(set (match_dup 0)
9862 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9863 "operands[2] = gen_lowpart (SImode, operands[2]);")
9864
9865 (define_insn "*<shift_insn><mode>3_1"
9866 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9867 (any_shiftrt:SWI12
9868 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9869 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9870 (clobber (reg:CC FLAGS_REG))]
9871 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9872 {
9873 if (operands[2] == const1_rtx
9874 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9875 return "<shift>{<imodesuffix>}\t%0";
9876 else
9877 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9878 }
9879 [(set_attr "type" "ishift")
9880 (set (attr "length_immediate")
9881 (if_then_else
9882 (and (match_operand 2 "const1_operand" "")
9883 (ior (match_test "TARGET_SHIFT1")
9884 (match_test "optimize_function_for_size_p (cfun)")))
9885 (const_string "0")
9886 (const_string "*")))
9887 (set_attr "mode" "<MODE>")])
9888
9889 (define_insn "*<shift_insn>qi3_1_slp"
9890 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9891 (any_shiftrt:QI (match_dup 0)
9892 (match_operand:QI 1 "nonmemory_operand" "cI")))
9893 (clobber (reg:CC FLAGS_REG))]
9894 "(optimize_function_for_size_p (cfun)
9895 || !TARGET_PARTIAL_REG_STALL
9896 || (operands[1] == const1_rtx
9897 && TARGET_SHIFT1))"
9898 {
9899 if (operands[1] == const1_rtx
9900 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9901 return "<shift>{b}\t%0";
9902 else
9903 return "<shift>{b}\t{%1, %0|%0, %1}";
9904 }
9905 [(set_attr "type" "ishift1")
9906 (set (attr "length_immediate")
9907 (if_then_else
9908 (and (match_operand 1 "const1_operand" "")
9909 (ior (match_test "TARGET_SHIFT1")
9910 (match_test "optimize_function_for_size_p (cfun)")))
9911 (const_string "0")
9912 (const_string "*")))
9913 (set_attr "mode" "QI")])
9914
9915 ;; This pattern can't accept a variable shift count, since shifts by
9916 ;; zero don't affect the flags. We assume that shifts by constant
9917 ;; zero are optimized away.
9918 (define_insn "*<shift_insn><mode>3_cmp"
9919 [(set (reg FLAGS_REG)
9920 (compare
9921 (any_shiftrt:SWI
9922 (match_operand:SWI 1 "nonimmediate_operand" "0")
9923 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9924 (const_int 0)))
9925 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9926 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9927 "(optimize_function_for_size_p (cfun)
9928 || !TARGET_PARTIAL_FLAG_REG_STALL
9929 || (operands[2] == const1_rtx
9930 && TARGET_SHIFT1))
9931 && ix86_match_ccmode (insn, CCGOCmode)
9932 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9933 {
9934 if (operands[2] == const1_rtx
9935 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9936 return "<shift>{<imodesuffix>}\t%0";
9937 else
9938 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9939 }
9940 [(set_attr "type" "ishift")
9941 (set (attr "length_immediate")
9942 (if_then_else
9943 (and (match_operand 2 "const1_operand" "")
9944 (ior (match_test "TARGET_SHIFT1")
9945 (match_test "optimize_function_for_size_p (cfun)")))
9946 (const_string "0")
9947 (const_string "*")))
9948 (set_attr "mode" "<MODE>")])
9949
9950 (define_insn "*<shift_insn>si3_cmp_zext"
9951 [(set (reg FLAGS_REG)
9952 (compare
9953 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9954 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9955 (const_int 0)))
9956 (set (match_operand:DI 0 "register_operand" "=r")
9957 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9958 "TARGET_64BIT
9959 && (optimize_function_for_size_p (cfun)
9960 || !TARGET_PARTIAL_FLAG_REG_STALL
9961 || (operands[2] == const1_rtx
9962 && TARGET_SHIFT1))
9963 && ix86_match_ccmode (insn, CCGOCmode)
9964 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9965 {
9966 if (operands[2] == const1_rtx
9967 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9968 return "<shift>{l}\t%k0";
9969 else
9970 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9971 }
9972 [(set_attr "type" "ishift")
9973 (set (attr "length_immediate")
9974 (if_then_else
9975 (and (match_operand 2 "const1_operand" "")
9976 (ior (match_test "TARGET_SHIFT1")
9977 (match_test "optimize_function_for_size_p (cfun)")))
9978 (const_string "0")
9979 (const_string "*")))
9980 (set_attr "mode" "SI")])
9981
9982 (define_insn "*<shift_insn><mode>3_cconly"
9983 [(set (reg FLAGS_REG)
9984 (compare
9985 (any_shiftrt:SWI
9986 (match_operand:SWI 1 "register_operand" "0")
9987 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9988 (const_int 0)))
9989 (clobber (match_scratch:SWI 0 "=<r>"))]
9990 "(optimize_function_for_size_p (cfun)
9991 || !TARGET_PARTIAL_FLAG_REG_STALL
9992 || (operands[2] == const1_rtx
9993 && TARGET_SHIFT1))
9994 && ix86_match_ccmode (insn, CCGOCmode)"
9995 {
9996 if (operands[2] == const1_rtx
9997 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9998 return "<shift>{<imodesuffix>}\t%0";
9999 else
10000 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10001 }
10002 [(set_attr "type" "ishift")
10003 (set (attr "length_immediate")
10004 (if_then_else
10005 (and (match_operand 2 "const1_operand" "")
10006 (ior (match_test "TARGET_SHIFT1")
10007 (match_test "optimize_function_for_size_p (cfun)")))
10008 (const_string "0")
10009 (const_string "*")))
10010 (set_attr "mode" "<MODE>")])
10011 \f
10012 ;; Rotate instructions
10013
10014 (define_expand "<rotate_insn>ti3"
10015 [(set (match_operand:TI 0 "register_operand" "")
10016 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10017 (match_operand:QI 2 "nonmemory_operand" "")))]
10018 "TARGET_64BIT"
10019 {
10020 if (const_1_to_63_operand (operands[2], VOIDmode))
10021 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10022 (operands[0], operands[1], operands[2]));
10023 else
10024 FAIL;
10025
10026 DONE;
10027 })
10028
10029 (define_expand "<rotate_insn>di3"
10030 [(set (match_operand:DI 0 "shiftdi_operand" "")
10031 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10032 (match_operand:QI 2 "nonmemory_operand" "")))]
10033 ""
10034 {
10035 if (TARGET_64BIT)
10036 ix86_expand_binary_operator (<CODE>, DImode, operands);
10037 else if (const_1_to_31_operand (operands[2], VOIDmode))
10038 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10039 (operands[0], operands[1], operands[2]));
10040 else
10041 FAIL;
10042
10043 DONE;
10044 })
10045
10046 (define_expand "<rotate_insn><mode>3"
10047 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10048 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10049 (match_operand:QI 2 "nonmemory_operand" "")))]
10050 ""
10051 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10052
10053 ;; Avoid useless masking of count operand.
10054 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10055 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10056 (any_rotate:SWI48
10057 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10058 (subreg:QI
10059 (and:SI
10060 (match_operand:SI 2 "nonimmediate_operand" "c")
10061 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10062 (clobber (reg:CC FLAGS_REG))]
10063 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10064 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10065 == GET_MODE_BITSIZE (<MODE>mode)-1"
10066 "#"
10067 "&& 1"
10068 [(parallel [(set (match_dup 0)
10069 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10070 (clobber (reg:CC FLAGS_REG))])]
10071 {
10072 if (can_create_pseudo_p ())
10073 operands [2] = force_reg (SImode, operands[2]);
10074
10075 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10076 }
10077 [(set_attr "type" "rotate")
10078 (set_attr "mode" "<MODE>")])
10079
10080 ;; Implement rotation using two double-precision
10081 ;; shift instructions and a scratch register.
10082
10083 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10084 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10085 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10086 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10087 (clobber (reg:CC FLAGS_REG))
10088 (clobber (match_scratch:DWIH 3 "=&r"))]
10089 ""
10090 "#"
10091 "reload_completed"
10092 [(set (match_dup 3) (match_dup 4))
10093 (parallel
10094 [(set (match_dup 4)
10095 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10096 (lshiftrt:DWIH (match_dup 5)
10097 (minus:QI (match_dup 6) (match_dup 2)))))
10098 (clobber (reg:CC FLAGS_REG))])
10099 (parallel
10100 [(set (match_dup 5)
10101 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10102 (lshiftrt:DWIH (match_dup 3)
10103 (minus:QI (match_dup 6) (match_dup 2)))))
10104 (clobber (reg:CC FLAGS_REG))])]
10105 {
10106 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10107
10108 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10109 })
10110
10111 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10112 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10113 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10114 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10115 (clobber (reg:CC FLAGS_REG))
10116 (clobber (match_scratch:DWIH 3 "=&r"))]
10117 ""
10118 "#"
10119 "reload_completed"
10120 [(set (match_dup 3) (match_dup 4))
10121 (parallel
10122 [(set (match_dup 4)
10123 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10124 (ashift:DWIH (match_dup 5)
10125 (minus:QI (match_dup 6) (match_dup 2)))))
10126 (clobber (reg:CC FLAGS_REG))])
10127 (parallel
10128 [(set (match_dup 5)
10129 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10130 (ashift:DWIH (match_dup 3)
10131 (minus:QI (match_dup 6) (match_dup 2)))))
10132 (clobber (reg:CC FLAGS_REG))])]
10133 {
10134 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10135
10136 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10137 })
10138
10139 (define_insn "*bmi2_rorx<mode>3_1"
10140 [(set (match_operand:SWI48 0 "register_operand" "=r")
10141 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10142 (match_operand:QI 2 "immediate_operand" "<S>")))]
10143 "TARGET_BMI2"
10144 "rorx\t{%2, %1, %0|%0, %1, %2}"
10145 [(set_attr "type" "rotatex")
10146 (set_attr "mode" "<MODE>")])
10147
10148 (define_insn "*<rotate_insn><mode>3_1"
10149 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10150 (any_rotate:SWI48
10151 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10152 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10153 (clobber (reg:CC FLAGS_REG))]
10154 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10155 {
10156 switch (get_attr_type (insn))
10157 {
10158 case TYPE_ROTATEX:
10159 return "#";
10160
10161 default:
10162 if (operands[2] == const1_rtx
10163 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10164 return "<rotate>{<imodesuffix>}\t%0";
10165 else
10166 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10167 }
10168 }
10169 [(set_attr "isa" "*,bmi2")
10170 (set_attr "type" "rotate,rotatex")
10171 (set (attr "length_immediate")
10172 (if_then_else
10173 (and (eq_attr "type" "rotate")
10174 (and (match_operand 2 "const1_operand" "")
10175 (ior (match_test "TARGET_SHIFT1")
10176 (match_test "optimize_function_for_size_p (cfun)"))))
10177 (const_string "0")
10178 (const_string "*")))
10179 (set_attr "mode" "<MODE>")])
10180
10181 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10182 (define_split
10183 [(set (match_operand:SWI48 0 "register_operand" "")
10184 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10185 (match_operand:QI 2 "immediate_operand" "")))
10186 (clobber (reg:CC FLAGS_REG))]
10187 "TARGET_BMI2 && reload_completed"
10188 [(set (match_dup 0)
10189 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10190 {
10191 operands[2]
10192 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10193 })
10194
10195 (define_split
10196 [(set (match_operand:SWI48 0 "register_operand" "")
10197 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10198 (match_operand:QI 2 "immediate_operand" "")))
10199 (clobber (reg:CC FLAGS_REG))]
10200 "TARGET_BMI2 && reload_completed"
10201 [(set (match_dup 0)
10202 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10203
10204 (define_insn "*bmi2_rorxsi3_1_zext"
10205 [(set (match_operand:DI 0 "register_operand" "=r")
10206 (zero_extend:DI
10207 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10208 (match_operand:QI 2 "immediate_operand" "I"))))]
10209 "TARGET_64BIT && TARGET_BMI2"
10210 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10211 [(set_attr "type" "rotatex")
10212 (set_attr "mode" "SI")])
10213
10214 (define_insn "*<rotate_insn>si3_1_zext"
10215 [(set (match_operand:DI 0 "register_operand" "=r,r")
10216 (zero_extend:DI
10217 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10218 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10219 (clobber (reg:CC FLAGS_REG))]
10220 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10221 {
10222 switch (get_attr_type (insn))
10223 {
10224 case TYPE_ROTATEX:
10225 return "#";
10226
10227 default:
10228 if (operands[2] == const1_rtx
10229 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10230 return "<rotate>{l}\t%k0";
10231 else
10232 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10233 }
10234 }
10235 [(set_attr "isa" "*,bmi2")
10236 (set_attr "type" "rotate,rotatex")
10237 (set (attr "length_immediate")
10238 (if_then_else
10239 (and (eq_attr "type" "rotate")
10240 (and (match_operand 2 "const1_operand" "")
10241 (ior (match_test "TARGET_SHIFT1")
10242 (match_test "optimize_function_for_size_p (cfun)"))))
10243 (const_string "0")
10244 (const_string "*")))
10245 (set_attr "mode" "SI")])
10246
10247 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10248 (define_split
10249 [(set (match_operand:DI 0 "register_operand" "")
10250 (zero_extend:DI
10251 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10252 (match_operand:QI 2 "immediate_operand" ""))))
10253 (clobber (reg:CC FLAGS_REG))]
10254 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10255 [(set (match_dup 0)
10256 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10257 {
10258 operands[2]
10259 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10260 })
10261
10262 (define_split
10263 [(set (match_operand:DI 0 "register_operand" "")
10264 (zero_extend:DI
10265 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10266 (match_operand:QI 2 "immediate_operand" ""))))
10267 (clobber (reg:CC FLAGS_REG))]
10268 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10269 [(set (match_dup 0)
10270 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10271
10272 (define_insn "*<rotate_insn><mode>3_1"
10273 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10274 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10275 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10276 (clobber (reg:CC FLAGS_REG))]
10277 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10278 {
10279 if (operands[2] == const1_rtx
10280 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10281 return "<rotate>{<imodesuffix>}\t%0";
10282 else
10283 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10284 }
10285 [(set_attr "type" "rotate")
10286 (set (attr "length_immediate")
10287 (if_then_else
10288 (and (match_operand 2 "const1_operand" "")
10289 (ior (match_test "TARGET_SHIFT1")
10290 (match_test "optimize_function_for_size_p (cfun)")))
10291 (const_string "0")
10292 (const_string "*")))
10293 (set_attr "mode" "<MODE>")])
10294
10295 (define_insn "*<rotate_insn>qi3_1_slp"
10296 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10297 (any_rotate:QI (match_dup 0)
10298 (match_operand:QI 1 "nonmemory_operand" "cI")))
10299 (clobber (reg:CC FLAGS_REG))]
10300 "(optimize_function_for_size_p (cfun)
10301 || !TARGET_PARTIAL_REG_STALL
10302 || (operands[1] == const1_rtx
10303 && TARGET_SHIFT1))"
10304 {
10305 if (operands[1] == const1_rtx
10306 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10307 return "<rotate>{b}\t%0";
10308 else
10309 return "<rotate>{b}\t{%1, %0|%0, %1}";
10310 }
10311 [(set_attr "type" "rotate1")
10312 (set (attr "length_immediate")
10313 (if_then_else
10314 (and (match_operand 1 "const1_operand" "")
10315 (ior (match_test "TARGET_SHIFT1")
10316 (match_test "optimize_function_for_size_p (cfun)")))
10317 (const_string "0")
10318 (const_string "*")))
10319 (set_attr "mode" "QI")])
10320
10321 (define_split
10322 [(set (match_operand:HI 0 "register_operand" "")
10323 (any_rotate:HI (match_dup 0) (const_int 8)))
10324 (clobber (reg:CC FLAGS_REG))]
10325 "reload_completed
10326 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10327 [(parallel [(set (strict_low_part (match_dup 0))
10328 (bswap:HI (match_dup 0)))
10329 (clobber (reg:CC FLAGS_REG))])])
10330 \f
10331 ;; Bit set / bit test instructions
10332
10333 (define_expand "extv"
10334 [(set (match_operand:SI 0 "register_operand" "")
10335 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10336 (match_operand:SI 2 "const8_operand" "")
10337 (match_operand:SI 3 "const8_operand" "")))]
10338 ""
10339 {
10340 /* Handle extractions from %ah et al. */
10341 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10342 FAIL;
10343
10344 /* From mips.md: extract_bit_field doesn't verify that our source
10345 matches the predicate, so check it again here. */
10346 if (! ext_register_operand (operands[1], VOIDmode))
10347 FAIL;
10348 })
10349
10350 (define_expand "extzv"
10351 [(set (match_operand:SI 0 "register_operand" "")
10352 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10353 (match_operand:SI 2 "const8_operand" "")
10354 (match_operand:SI 3 "const8_operand" "")))]
10355 ""
10356 {
10357 /* Handle extractions from %ah et al. */
10358 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10359 FAIL;
10360
10361 /* From mips.md: extract_bit_field doesn't verify that our source
10362 matches the predicate, so check it again here. */
10363 if (! ext_register_operand (operands[1], VOIDmode))
10364 FAIL;
10365 })
10366
10367 (define_expand "insv"
10368 [(set (zero_extract (match_operand 0 "register_operand" "")
10369 (match_operand 1 "const_int_operand" "")
10370 (match_operand 2 "const_int_operand" ""))
10371 (match_operand 3 "register_operand" ""))]
10372 ""
10373 {
10374 rtx (*gen_mov_insv_1) (rtx, rtx);
10375
10376 if (ix86_expand_pinsr (operands))
10377 DONE;
10378
10379 /* Handle insertions to %ah et al. */
10380 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10381 FAIL;
10382
10383 /* From mips.md: insert_bit_field doesn't verify that our source
10384 matches the predicate, so check it again here. */
10385 if (! ext_register_operand (operands[0], VOIDmode))
10386 FAIL;
10387
10388 gen_mov_insv_1 = (TARGET_64BIT
10389 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10390
10391 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10392 DONE;
10393 })
10394
10395 ;; %%% bts, btr, btc, bt.
10396 ;; In general these instructions are *slow* when applied to memory,
10397 ;; since they enforce atomic operation. When applied to registers,
10398 ;; it depends on the cpu implementation. They're never faster than
10399 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10400 ;; no point. But in 64-bit, we can't hold the relevant immediates
10401 ;; within the instruction itself, so operating on bits in the high
10402 ;; 32-bits of a register becomes easier.
10403 ;;
10404 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10405 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10406 ;; negdf respectively, so they can never be disabled entirely.
10407
10408 (define_insn "*btsq"
10409 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10410 (const_int 1)
10411 (match_operand:DI 1 "const_0_to_63_operand" ""))
10412 (const_int 1))
10413 (clobber (reg:CC FLAGS_REG))]
10414 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10415 "bts{q}\t{%1, %0|%0, %1}"
10416 [(set_attr "type" "alu1")
10417 (set_attr "prefix_0f" "1")
10418 (set_attr "mode" "DI")])
10419
10420 (define_insn "*btrq"
10421 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10422 (const_int 1)
10423 (match_operand:DI 1 "const_0_to_63_operand" ""))
10424 (const_int 0))
10425 (clobber (reg:CC FLAGS_REG))]
10426 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10427 "btr{q}\t{%1, %0|%0, %1}"
10428 [(set_attr "type" "alu1")
10429 (set_attr "prefix_0f" "1")
10430 (set_attr "mode" "DI")])
10431
10432 (define_insn "*btcq"
10433 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10434 (const_int 1)
10435 (match_operand:DI 1 "const_0_to_63_operand" ""))
10436 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10437 (clobber (reg:CC FLAGS_REG))]
10438 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10439 "btc{q}\t{%1, %0|%0, %1}"
10440 [(set_attr "type" "alu1")
10441 (set_attr "prefix_0f" "1")
10442 (set_attr "mode" "DI")])
10443
10444 ;; Allow Nocona to avoid these instructions if a register is available.
10445
10446 (define_peephole2
10447 [(match_scratch:DI 2 "r")
10448 (parallel [(set (zero_extract:DI
10449 (match_operand:DI 0 "register_operand" "")
10450 (const_int 1)
10451 (match_operand:DI 1 "const_0_to_63_operand" ""))
10452 (const_int 1))
10453 (clobber (reg:CC FLAGS_REG))])]
10454 "TARGET_64BIT && !TARGET_USE_BT"
10455 [(const_int 0)]
10456 {
10457 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10458 rtx op1;
10459
10460 if (HOST_BITS_PER_WIDE_INT >= 64)
10461 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10462 else if (i < HOST_BITS_PER_WIDE_INT)
10463 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10464 else
10465 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10466
10467 op1 = immed_double_const (lo, hi, DImode);
10468 if (i >= 31)
10469 {
10470 emit_move_insn (operands[2], op1);
10471 op1 = operands[2];
10472 }
10473
10474 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10475 DONE;
10476 })
10477
10478 (define_peephole2
10479 [(match_scratch:DI 2 "r")
10480 (parallel [(set (zero_extract:DI
10481 (match_operand:DI 0 "register_operand" "")
10482 (const_int 1)
10483 (match_operand:DI 1 "const_0_to_63_operand" ""))
10484 (const_int 0))
10485 (clobber (reg:CC FLAGS_REG))])]
10486 "TARGET_64BIT && !TARGET_USE_BT"
10487 [(const_int 0)]
10488 {
10489 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10490 rtx op1;
10491
10492 if (HOST_BITS_PER_WIDE_INT >= 64)
10493 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10494 else if (i < HOST_BITS_PER_WIDE_INT)
10495 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10496 else
10497 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10498
10499 op1 = immed_double_const (~lo, ~hi, DImode);
10500 if (i >= 32)
10501 {
10502 emit_move_insn (operands[2], op1);
10503 op1 = operands[2];
10504 }
10505
10506 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10507 DONE;
10508 })
10509
10510 (define_peephole2
10511 [(match_scratch:DI 2 "r")
10512 (parallel [(set (zero_extract:DI
10513 (match_operand:DI 0 "register_operand" "")
10514 (const_int 1)
10515 (match_operand:DI 1 "const_0_to_63_operand" ""))
10516 (not:DI (zero_extract:DI
10517 (match_dup 0) (const_int 1) (match_dup 1))))
10518 (clobber (reg:CC FLAGS_REG))])]
10519 "TARGET_64BIT && !TARGET_USE_BT"
10520 [(const_int 0)]
10521 {
10522 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10523 rtx op1;
10524
10525 if (HOST_BITS_PER_WIDE_INT >= 64)
10526 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10527 else if (i < HOST_BITS_PER_WIDE_INT)
10528 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10529 else
10530 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10531
10532 op1 = immed_double_const (lo, hi, DImode);
10533 if (i >= 31)
10534 {
10535 emit_move_insn (operands[2], op1);
10536 op1 = operands[2];
10537 }
10538
10539 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10540 DONE;
10541 })
10542
10543 (define_insn "*bt<mode>"
10544 [(set (reg:CCC FLAGS_REG)
10545 (compare:CCC
10546 (zero_extract:SWI48
10547 (match_operand:SWI48 0 "register_operand" "r")
10548 (const_int 1)
10549 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10550 (const_int 0)))]
10551 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10552 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10553 [(set_attr "type" "alu1")
10554 (set_attr "prefix_0f" "1")
10555 (set_attr "mode" "<MODE>")])
10556 \f
10557 ;; Store-flag instructions.
10558
10559 ;; For all sCOND expanders, also expand the compare or test insn that
10560 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10561
10562 (define_insn_and_split "*setcc_di_1"
10563 [(set (match_operand:DI 0 "register_operand" "=q")
10564 (match_operator:DI 1 "ix86_comparison_operator"
10565 [(reg FLAGS_REG) (const_int 0)]))]
10566 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10567 "#"
10568 "&& reload_completed"
10569 [(set (match_dup 2) (match_dup 1))
10570 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10571 {
10572 PUT_MODE (operands[1], QImode);
10573 operands[2] = gen_lowpart (QImode, operands[0]);
10574 })
10575
10576 (define_insn_and_split "*setcc_si_1_and"
10577 [(set (match_operand:SI 0 "register_operand" "=q")
10578 (match_operator:SI 1 "ix86_comparison_operator"
10579 [(reg FLAGS_REG) (const_int 0)]))
10580 (clobber (reg:CC FLAGS_REG))]
10581 "!TARGET_PARTIAL_REG_STALL
10582 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10583 "#"
10584 "&& reload_completed"
10585 [(set (match_dup 2) (match_dup 1))
10586 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10587 (clobber (reg:CC FLAGS_REG))])]
10588 {
10589 PUT_MODE (operands[1], QImode);
10590 operands[2] = gen_lowpart (QImode, operands[0]);
10591 })
10592
10593 (define_insn_and_split "*setcc_si_1_movzbl"
10594 [(set (match_operand:SI 0 "register_operand" "=q")
10595 (match_operator:SI 1 "ix86_comparison_operator"
10596 [(reg FLAGS_REG) (const_int 0)]))]
10597 "!TARGET_PARTIAL_REG_STALL
10598 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10599 "#"
10600 "&& reload_completed"
10601 [(set (match_dup 2) (match_dup 1))
10602 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10603 {
10604 PUT_MODE (operands[1], QImode);
10605 operands[2] = gen_lowpart (QImode, operands[0]);
10606 })
10607
10608 (define_insn "*setcc_qi"
10609 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10610 (match_operator:QI 1 "ix86_comparison_operator"
10611 [(reg FLAGS_REG) (const_int 0)]))]
10612 ""
10613 "set%C1\t%0"
10614 [(set_attr "type" "setcc")
10615 (set_attr "mode" "QI")])
10616
10617 (define_insn "*setcc_qi_slp"
10618 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10619 (match_operator:QI 1 "ix86_comparison_operator"
10620 [(reg FLAGS_REG) (const_int 0)]))]
10621 ""
10622 "set%C1\t%0"
10623 [(set_attr "type" "setcc")
10624 (set_attr "mode" "QI")])
10625
10626 ;; In general it is not safe to assume too much about CCmode registers,
10627 ;; so simplify-rtx stops when it sees a second one. Under certain
10628 ;; conditions this is safe on x86, so help combine not create
10629 ;;
10630 ;; seta %al
10631 ;; testb %al, %al
10632 ;; sete %al
10633
10634 (define_split
10635 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10636 (ne:QI (match_operator 1 "ix86_comparison_operator"
10637 [(reg FLAGS_REG) (const_int 0)])
10638 (const_int 0)))]
10639 ""
10640 [(set (match_dup 0) (match_dup 1))]
10641 "PUT_MODE (operands[1], QImode);")
10642
10643 (define_split
10644 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10645 (ne:QI (match_operator 1 "ix86_comparison_operator"
10646 [(reg FLAGS_REG) (const_int 0)])
10647 (const_int 0)))]
10648 ""
10649 [(set (match_dup 0) (match_dup 1))]
10650 "PUT_MODE (operands[1], QImode);")
10651
10652 (define_split
10653 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10654 (eq:QI (match_operator 1 "ix86_comparison_operator"
10655 [(reg FLAGS_REG) (const_int 0)])
10656 (const_int 0)))]
10657 ""
10658 [(set (match_dup 0) (match_dup 1))]
10659 {
10660 rtx new_op1 = copy_rtx (operands[1]);
10661 operands[1] = new_op1;
10662 PUT_MODE (new_op1, QImode);
10663 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10664 GET_MODE (XEXP (new_op1, 0))));
10665
10666 /* Make sure that (a) the CCmode we have for the flags is strong
10667 enough for the reversed compare or (b) we have a valid FP compare. */
10668 if (! ix86_comparison_operator (new_op1, VOIDmode))
10669 FAIL;
10670 })
10671
10672 (define_split
10673 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10674 (eq:QI (match_operator 1 "ix86_comparison_operator"
10675 [(reg FLAGS_REG) (const_int 0)])
10676 (const_int 0)))]
10677 ""
10678 [(set (match_dup 0) (match_dup 1))]
10679 {
10680 rtx new_op1 = copy_rtx (operands[1]);
10681 operands[1] = new_op1;
10682 PUT_MODE (new_op1, QImode);
10683 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10684 GET_MODE (XEXP (new_op1, 0))));
10685
10686 /* Make sure that (a) the CCmode we have for the flags is strong
10687 enough for the reversed compare or (b) we have a valid FP compare. */
10688 if (! ix86_comparison_operator (new_op1, VOIDmode))
10689 FAIL;
10690 })
10691
10692 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10693 ;; subsequent logical operations are used to imitate conditional moves.
10694 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10695 ;; it directly.
10696
10697 (define_insn "setcc_<mode>_sse"
10698 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10699 (match_operator:MODEF 3 "sse_comparison_operator"
10700 [(match_operand:MODEF 1 "register_operand" "0,x")
10701 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10702 "SSE_FLOAT_MODE_P (<MODE>mode)"
10703 "@
10704 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10705 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10706 [(set_attr "isa" "noavx,avx")
10707 (set_attr "type" "ssecmp")
10708 (set_attr "length_immediate" "1")
10709 (set_attr "prefix" "orig,vex")
10710 (set_attr "mode" "<MODE>")])
10711 \f
10712 ;; Basic conditional jump instructions.
10713 ;; We ignore the overflow flag for signed branch instructions.
10714
10715 (define_insn "*jcc_1"
10716 [(set (pc)
10717 (if_then_else (match_operator 1 "ix86_comparison_operator"
10718 [(reg FLAGS_REG) (const_int 0)])
10719 (label_ref (match_operand 0 "" ""))
10720 (pc)))]
10721 ""
10722 "%+j%C1\t%l0"
10723 [(set_attr "type" "ibr")
10724 (set_attr "modrm" "0")
10725 (set (attr "length")
10726 (if_then_else (and (ge (minus (match_dup 0) (pc))
10727 (const_int -126))
10728 (lt (minus (match_dup 0) (pc))
10729 (const_int 128)))
10730 (const_int 2)
10731 (const_int 6)))])
10732
10733 (define_insn "*jcc_2"
10734 [(set (pc)
10735 (if_then_else (match_operator 1 "ix86_comparison_operator"
10736 [(reg FLAGS_REG) (const_int 0)])
10737 (pc)
10738 (label_ref (match_operand 0 "" ""))))]
10739 ""
10740 "%+j%c1\t%l0"
10741 [(set_attr "type" "ibr")
10742 (set_attr "modrm" "0")
10743 (set (attr "length")
10744 (if_then_else (and (ge (minus (match_dup 0) (pc))
10745 (const_int -126))
10746 (lt (minus (match_dup 0) (pc))
10747 (const_int 128)))
10748 (const_int 2)
10749 (const_int 6)))])
10750
10751 ;; In general it is not safe to assume too much about CCmode registers,
10752 ;; so simplify-rtx stops when it sees a second one. Under certain
10753 ;; conditions this is safe on x86, so help combine not create
10754 ;;
10755 ;; seta %al
10756 ;; testb %al, %al
10757 ;; je Lfoo
10758
10759 (define_split
10760 [(set (pc)
10761 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10762 [(reg FLAGS_REG) (const_int 0)])
10763 (const_int 0))
10764 (label_ref (match_operand 1 "" ""))
10765 (pc)))]
10766 ""
10767 [(set (pc)
10768 (if_then_else (match_dup 0)
10769 (label_ref (match_dup 1))
10770 (pc)))]
10771 "PUT_MODE (operands[0], VOIDmode);")
10772
10773 (define_split
10774 [(set (pc)
10775 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10776 [(reg FLAGS_REG) (const_int 0)])
10777 (const_int 0))
10778 (label_ref (match_operand 1 "" ""))
10779 (pc)))]
10780 ""
10781 [(set (pc)
10782 (if_then_else (match_dup 0)
10783 (label_ref (match_dup 1))
10784 (pc)))]
10785 {
10786 rtx new_op0 = copy_rtx (operands[0]);
10787 operands[0] = new_op0;
10788 PUT_MODE (new_op0, VOIDmode);
10789 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10790 GET_MODE (XEXP (new_op0, 0))));
10791
10792 /* Make sure that (a) the CCmode we have for the flags is strong
10793 enough for the reversed compare or (b) we have a valid FP compare. */
10794 if (! ix86_comparison_operator (new_op0, VOIDmode))
10795 FAIL;
10796 })
10797
10798 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10799 ;; pass generates from shift insn with QImode operand. Actually, the mode
10800 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10801 ;; appropriate modulo of the bit offset value.
10802
10803 (define_insn_and_split "*jcc_bt<mode>"
10804 [(set (pc)
10805 (if_then_else (match_operator 0 "bt_comparison_operator"
10806 [(zero_extract:SWI48
10807 (match_operand:SWI48 1 "register_operand" "r")
10808 (const_int 1)
10809 (zero_extend:SI
10810 (match_operand:QI 2 "register_operand" "r")))
10811 (const_int 0)])
10812 (label_ref (match_operand 3 "" ""))
10813 (pc)))
10814 (clobber (reg:CC FLAGS_REG))]
10815 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10816 "#"
10817 "&& 1"
10818 [(set (reg:CCC FLAGS_REG)
10819 (compare:CCC
10820 (zero_extract:SWI48
10821 (match_dup 1)
10822 (const_int 1)
10823 (match_dup 2))
10824 (const_int 0)))
10825 (set (pc)
10826 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10827 (label_ref (match_dup 3))
10828 (pc)))]
10829 {
10830 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10831
10832 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10833 })
10834
10835 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10836 ;; also for DImode, this is what combine produces.
10837 (define_insn_and_split "*jcc_bt<mode>_mask"
10838 [(set (pc)
10839 (if_then_else (match_operator 0 "bt_comparison_operator"
10840 [(zero_extract:SWI48
10841 (match_operand:SWI48 1 "register_operand" "r")
10842 (const_int 1)
10843 (and:SI
10844 (match_operand:SI 2 "register_operand" "r")
10845 (match_operand:SI 3 "const_int_operand" "n")))])
10846 (label_ref (match_operand 4 "" ""))
10847 (pc)))
10848 (clobber (reg:CC FLAGS_REG))]
10849 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10850 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10851 == GET_MODE_BITSIZE (<MODE>mode)-1"
10852 "#"
10853 "&& 1"
10854 [(set (reg:CCC FLAGS_REG)
10855 (compare:CCC
10856 (zero_extract:SWI48
10857 (match_dup 1)
10858 (const_int 1)
10859 (match_dup 2))
10860 (const_int 0)))
10861 (set (pc)
10862 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10863 (label_ref (match_dup 4))
10864 (pc)))]
10865 {
10866 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10867
10868 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10869 })
10870
10871 (define_insn_and_split "*jcc_btsi_1"
10872 [(set (pc)
10873 (if_then_else (match_operator 0 "bt_comparison_operator"
10874 [(and:SI
10875 (lshiftrt:SI
10876 (match_operand:SI 1 "register_operand" "r")
10877 (match_operand:QI 2 "register_operand" "r"))
10878 (const_int 1))
10879 (const_int 0)])
10880 (label_ref (match_operand 3 "" ""))
10881 (pc)))
10882 (clobber (reg:CC FLAGS_REG))]
10883 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10884 "#"
10885 "&& 1"
10886 [(set (reg:CCC FLAGS_REG)
10887 (compare:CCC
10888 (zero_extract:SI
10889 (match_dup 1)
10890 (const_int 1)
10891 (match_dup 2))
10892 (const_int 0)))
10893 (set (pc)
10894 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10895 (label_ref (match_dup 3))
10896 (pc)))]
10897 {
10898 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10899
10900 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10901 })
10902
10903 ;; avoid useless masking of bit offset operand
10904 (define_insn_and_split "*jcc_btsi_mask_1"
10905 [(set (pc)
10906 (if_then_else
10907 (match_operator 0 "bt_comparison_operator"
10908 [(and:SI
10909 (lshiftrt:SI
10910 (match_operand:SI 1 "register_operand" "r")
10911 (subreg:QI
10912 (and:SI
10913 (match_operand:SI 2 "register_operand" "r")
10914 (match_operand:SI 3 "const_int_operand" "n")) 0))
10915 (const_int 1))
10916 (const_int 0)])
10917 (label_ref (match_operand 4 "" ""))
10918 (pc)))
10919 (clobber (reg:CC FLAGS_REG))]
10920 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10921 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10922 "#"
10923 "&& 1"
10924 [(set (reg:CCC FLAGS_REG)
10925 (compare:CCC
10926 (zero_extract:SI
10927 (match_dup 1)
10928 (const_int 1)
10929 (match_dup 2))
10930 (const_int 0)))
10931 (set (pc)
10932 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10933 (label_ref (match_dup 4))
10934 (pc)))]
10935 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10936
10937 ;; Define combination compare-and-branch fp compare instructions to help
10938 ;; combine.
10939
10940 (define_insn "*fp_jcc_1_387"
10941 [(set (pc)
10942 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10943 [(match_operand 1 "register_operand" "f")
10944 (match_operand 2 "nonimmediate_operand" "fm")])
10945 (label_ref (match_operand 3 "" ""))
10946 (pc)))
10947 (clobber (reg:CCFP FPSR_REG))
10948 (clobber (reg:CCFP FLAGS_REG))
10949 (clobber (match_scratch:HI 4 "=a"))]
10950 "TARGET_80387
10951 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10952 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10953 && SELECT_CC_MODE (GET_CODE (operands[0]),
10954 operands[1], operands[2]) == CCFPmode
10955 && !TARGET_CMOVE"
10956 "#")
10957
10958 (define_insn "*fp_jcc_1r_387"
10959 [(set (pc)
10960 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10961 [(match_operand 1 "register_operand" "f")
10962 (match_operand 2 "nonimmediate_operand" "fm")])
10963 (pc)
10964 (label_ref (match_operand 3 "" ""))))
10965 (clobber (reg:CCFP FPSR_REG))
10966 (clobber (reg:CCFP FLAGS_REG))
10967 (clobber (match_scratch:HI 4 "=a"))]
10968 "TARGET_80387
10969 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10970 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10971 && SELECT_CC_MODE (GET_CODE (operands[0]),
10972 operands[1], operands[2]) == CCFPmode
10973 && !TARGET_CMOVE"
10974 "#")
10975
10976 (define_insn "*fp_jcc_2_387"
10977 [(set (pc)
10978 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10979 [(match_operand 1 "register_operand" "f")
10980 (match_operand 2 "register_operand" "f")])
10981 (label_ref (match_operand 3 "" ""))
10982 (pc)))
10983 (clobber (reg:CCFP FPSR_REG))
10984 (clobber (reg:CCFP FLAGS_REG))
10985 (clobber (match_scratch:HI 4 "=a"))]
10986 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10987 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10988 && !TARGET_CMOVE"
10989 "#")
10990
10991 (define_insn "*fp_jcc_2r_387"
10992 [(set (pc)
10993 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10994 [(match_operand 1 "register_operand" "f")
10995 (match_operand 2 "register_operand" "f")])
10996 (pc)
10997 (label_ref (match_operand 3 "" ""))))
10998 (clobber (reg:CCFP FPSR_REG))
10999 (clobber (reg:CCFP FLAGS_REG))
11000 (clobber (match_scratch:HI 4 "=a"))]
11001 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11002 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11003 && !TARGET_CMOVE"
11004 "#")
11005
11006 (define_insn "*fp_jcc_3_387"
11007 [(set (pc)
11008 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11009 [(match_operand 1 "register_operand" "f")
11010 (match_operand 2 "const0_operand" "")])
11011 (label_ref (match_operand 3 "" ""))
11012 (pc)))
11013 (clobber (reg:CCFP FPSR_REG))
11014 (clobber (reg:CCFP FLAGS_REG))
11015 (clobber (match_scratch:HI 4 "=a"))]
11016 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11017 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11018 && SELECT_CC_MODE (GET_CODE (operands[0]),
11019 operands[1], operands[2]) == CCFPmode
11020 && !TARGET_CMOVE"
11021 "#")
11022
11023 (define_split
11024 [(set (pc)
11025 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11026 [(match_operand 1 "register_operand" "")
11027 (match_operand 2 "nonimmediate_operand" "")])
11028 (match_operand 3 "" "")
11029 (match_operand 4 "" "")))
11030 (clobber (reg:CCFP FPSR_REG))
11031 (clobber (reg:CCFP FLAGS_REG))]
11032 "reload_completed"
11033 [(const_int 0)]
11034 {
11035 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11036 operands[3], operands[4], NULL_RTX, NULL_RTX);
11037 DONE;
11038 })
11039
11040 (define_split
11041 [(set (pc)
11042 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11043 [(match_operand 1 "register_operand" "")
11044 (match_operand 2 "general_operand" "")])
11045 (match_operand 3 "" "")
11046 (match_operand 4 "" "")))
11047 (clobber (reg:CCFP FPSR_REG))
11048 (clobber (reg:CCFP FLAGS_REG))
11049 (clobber (match_scratch:HI 5 "=a"))]
11050 "reload_completed"
11051 [(const_int 0)]
11052 {
11053 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11054 operands[3], operands[4], operands[5], NULL_RTX);
11055 DONE;
11056 })
11057
11058 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11059 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11060 ;; with a precedence over other operators and is always put in the first
11061 ;; place. Swap condition and operands to match ficom instruction.
11062
11063 (define_insn "*fp_jcc_4_<mode>_387"
11064 [(set (pc)
11065 (if_then_else
11066 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11067 [(match_operator 1 "float_operator"
11068 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11069 (match_operand 3 "register_operand" "f,f")])
11070 (label_ref (match_operand 4 "" ""))
11071 (pc)))
11072 (clobber (reg:CCFP FPSR_REG))
11073 (clobber (reg:CCFP FLAGS_REG))
11074 (clobber (match_scratch:HI 5 "=a,a"))]
11075 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11076 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11077 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11078 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11079 && !TARGET_CMOVE"
11080 "#")
11081
11082 (define_split
11083 [(set (pc)
11084 (if_then_else
11085 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11086 [(match_operator 1 "float_operator"
11087 [(match_operand:SWI24 2 "memory_operand" "")])
11088 (match_operand 3 "register_operand" "")])
11089 (match_operand 4 "" "")
11090 (match_operand 5 "" "")))
11091 (clobber (reg:CCFP FPSR_REG))
11092 (clobber (reg:CCFP FLAGS_REG))
11093 (clobber (match_scratch:HI 6 "=a"))]
11094 "reload_completed"
11095 [(const_int 0)]
11096 {
11097 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11098
11099 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11100 operands[3], operands[7],
11101 operands[4], operands[5], operands[6], NULL_RTX);
11102 DONE;
11103 })
11104
11105 ;; %%% Kill this when reload knows how to do it.
11106 (define_split
11107 [(set (pc)
11108 (if_then_else
11109 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11110 [(match_operator 1 "float_operator"
11111 [(match_operand:SWI24 2 "register_operand" "")])
11112 (match_operand 3 "register_operand" "")])
11113 (match_operand 4 "" "")
11114 (match_operand 5 "" "")))
11115 (clobber (reg:CCFP FPSR_REG))
11116 (clobber (reg:CCFP FLAGS_REG))
11117 (clobber (match_scratch:HI 6 "=a"))]
11118 "reload_completed"
11119 [(const_int 0)]
11120 {
11121 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11122 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11123
11124 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11125 operands[3], operands[7],
11126 operands[4], operands[5], operands[6], operands[2]);
11127 DONE;
11128 })
11129 \f
11130 ;; Unconditional and other jump instructions
11131
11132 (define_insn "jump"
11133 [(set (pc)
11134 (label_ref (match_operand 0 "" "")))]
11135 ""
11136 "jmp\t%l0"
11137 [(set_attr "type" "ibr")
11138 (set (attr "length")
11139 (if_then_else (and (ge (minus (match_dup 0) (pc))
11140 (const_int -126))
11141 (lt (minus (match_dup 0) (pc))
11142 (const_int 128)))
11143 (const_int 2)
11144 (const_int 5)))
11145 (set_attr "modrm" "0")])
11146
11147 (define_expand "indirect_jump"
11148 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11149
11150 (define_insn "*indirect_jump"
11151 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11152 ""
11153 "jmp\t%A0"
11154 [(set_attr "type" "ibr")
11155 (set_attr "length_immediate" "0")])
11156
11157 (define_expand "tablejump"
11158 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11159 (use (label_ref (match_operand 1 "" "")))])]
11160 ""
11161 {
11162 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11163 relative. Convert the relative address to an absolute address. */
11164 if (flag_pic)
11165 {
11166 rtx op0, op1;
11167 enum rtx_code code;
11168
11169 /* We can't use @GOTOFF for text labels on VxWorks;
11170 see gotoff_operand. */
11171 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11172 {
11173 code = PLUS;
11174 op0 = operands[0];
11175 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11176 }
11177 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11178 {
11179 code = PLUS;
11180 op0 = operands[0];
11181 op1 = pic_offset_table_rtx;
11182 }
11183 else
11184 {
11185 code = MINUS;
11186 op0 = pic_offset_table_rtx;
11187 op1 = operands[0];
11188 }
11189
11190 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11191 OPTAB_DIRECT);
11192 }
11193 else if (TARGET_X32)
11194 operands[0] = convert_memory_address (Pmode, operands[0]);
11195 })
11196
11197 (define_insn "*tablejump_1"
11198 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11199 (use (label_ref (match_operand 1 "" "")))]
11200 ""
11201 "jmp\t%A0"
11202 [(set_attr "type" "ibr")
11203 (set_attr "length_immediate" "0")])
11204 \f
11205 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11206
11207 (define_peephole2
11208 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11209 (set (match_operand:QI 1 "register_operand" "")
11210 (match_operator:QI 2 "ix86_comparison_operator"
11211 [(reg FLAGS_REG) (const_int 0)]))
11212 (set (match_operand 3 "q_regs_operand" "")
11213 (zero_extend (match_dup 1)))]
11214 "(peep2_reg_dead_p (3, operands[1])
11215 || operands_match_p (operands[1], operands[3]))
11216 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11217 [(set (match_dup 4) (match_dup 0))
11218 (set (strict_low_part (match_dup 5))
11219 (match_dup 2))]
11220 {
11221 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11222 operands[5] = gen_lowpart (QImode, operands[3]);
11223 ix86_expand_clear (operands[3]);
11224 })
11225
11226 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11227
11228 (define_peephole2
11229 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11230 (set (match_operand:QI 1 "register_operand" "")
11231 (match_operator:QI 2 "ix86_comparison_operator"
11232 [(reg FLAGS_REG) (const_int 0)]))
11233 (parallel [(set (match_operand 3 "q_regs_operand" "")
11234 (zero_extend (match_dup 1)))
11235 (clobber (reg:CC FLAGS_REG))])]
11236 "(peep2_reg_dead_p (3, operands[1])
11237 || operands_match_p (operands[1], operands[3]))
11238 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11239 [(set (match_dup 4) (match_dup 0))
11240 (set (strict_low_part (match_dup 5))
11241 (match_dup 2))]
11242 {
11243 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11244 operands[5] = gen_lowpart (QImode, operands[3]);
11245 ix86_expand_clear (operands[3]);
11246 })
11247 \f
11248 ;; Call instructions.
11249
11250 ;; The predicates normally associated with named expanders are not properly
11251 ;; checked for calls. This is a bug in the generic code, but it isn't that
11252 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11253
11254 ;; P6 processors will jump to the address after the decrement when %esp
11255 ;; is used as a call operand, so they will execute return address as a code.
11256 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11257
11258 ;; Register constraint for call instruction.
11259 (define_mode_attr c [(SI "l") (DI "r")])
11260
11261 ;; Call subroutine returning no value.
11262
11263 (define_expand "call"
11264 [(call (match_operand:QI 0 "" "")
11265 (match_operand 1 "" ""))
11266 (use (match_operand 2 "" ""))]
11267 ""
11268 {
11269 ix86_expand_call (NULL, operands[0], operands[1],
11270 operands[2], NULL, false);
11271 DONE;
11272 })
11273
11274 (define_expand "sibcall"
11275 [(call (match_operand:QI 0 "" "")
11276 (match_operand 1 "" ""))
11277 (use (match_operand 2 "" ""))]
11278 ""
11279 {
11280 ix86_expand_call (NULL, operands[0], operands[1],
11281 operands[2], NULL, true);
11282 DONE;
11283 })
11284
11285 (define_insn_and_split "*call_vzeroupper"
11286 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11287 (match_operand 1 "" ""))
11288 (unspec [(match_operand 2 "const_int_operand" "")]
11289 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11290 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11291 "#"
11292 "&& reload_completed"
11293 [(const_int 0)]
11294 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11295 [(set_attr "type" "call")])
11296
11297 (define_insn "*call"
11298 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11299 (match_operand 1 "" ""))]
11300 "!SIBLING_CALL_P (insn)"
11301 "* return ix86_output_call_insn (insn, operands[0]);"
11302 [(set_attr "type" "call")])
11303
11304 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11305 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11306 (match_operand 1 "" ""))
11307 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11308 (clobber (reg:TI XMM6_REG))
11309 (clobber (reg:TI XMM7_REG))
11310 (clobber (reg:TI XMM8_REG))
11311 (clobber (reg:TI XMM9_REG))
11312 (clobber (reg:TI XMM10_REG))
11313 (clobber (reg:TI XMM11_REG))
11314 (clobber (reg:TI XMM12_REG))
11315 (clobber (reg:TI XMM13_REG))
11316 (clobber (reg:TI XMM14_REG))
11317 (clobber (reg:TI XMM15_REG))
11318 (clobber (reg:DI SI_REG))
11319 (clobber (reg:DI DI_REG))
11320 (unspec [(match_operand 2 "const_int_operand" "")]
11321 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11322 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11323 "#"
11324 "&& reload_completed"
11325 [(const_int 0)]
11326 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11327 [(set_attr "type" "call")])
11328
11329 (define_insn "*call_rex64_ms_sysv"
11330 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11331 (match_operand 1 "" ""))
11332 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11333 (clobber (reg:TI XMM6_REG))
11334 (clobber (reg:TI XMM7_REG))
11335 (clobber (reg:TI XMM8_REG))
11336 (clobber (reg:TI XMM9_REG))
11337 (clobber (reg:TI XMM10_REG))
11338 (clobber (reg:TI XMM11_REG))
11339 (clobber (reg:TI XMM12_REG))
11340 (clobber (reg:TI XMM13_REG))
11341 (clobber (reg:TI XMM14_REG))
11342 (clobber (reg:TI XMM15_REG))
11343 (clobber (reg:DI SI_REG))
11344 (clobber (reg:DI DI_REG))]
11345 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11346 "* return ix86_output_call_insn (insn, operands[0]);"
11347 [(set_attr "type" "call")])
11348
11349 (define_insn_and_split "*sibcall_vzeroupper"
11350 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11351 (match_operand 1 "" ""))
11352 (unspec [(match_operand 2 "const_int_operand" "")]
11353 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11354 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11355 "#"
11356 "&& reload_completed"
11357 [(const_int 0)]
11358 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11359 [(set_attr "type" "call")])
11360
11361 (define_insn "*sibcall"
11362 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11363 (match_operand 1 "" ""))]
11364 "SIBLING_CALL_P (insn)"
11365 "* return ix86_output_call_insn (insn, operands[0]);"
11366 [(set_attr "type" "call")])
11367
11368 (define_expand "call_pop"
11369 [(parallel [(call (match_operand:QI 0 "" "")
11370 (match_operand:SI 1 "" ""))
11371 (set (reg:SI SP_REG)
11372 (plus:SI (reg:SI SP_REG)
11373 (match_operand:SI 3 "" "")))])]
11374 "!TARGET_64BIT"
11375 {
11376 ix86_expand_call (NULL, operands[0], operands[1],
11377 operands[2], operands[3], false);
11378 DONE;
11379 })
11380
11381 (define_insn_and_split "*call_pop_vzeroupper"
11382 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11383 (match_operand:SI 1 "" ""))
11384 (set (reg:SI SP_REG)
11385 (plus:SI (reg:SI SP_REG)
11386 (match_operand:SI 2 "immediate_operand" "i")))
11387 (unspec [(match_operand 3 "const_int_operand" "")]
11388 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11389 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11390 "#"
11391 "&& reload_completed"
11392 [(const_int 0)]
11393 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11394 [(set_attr "type" "call")])
11395
11396 (define_insn "*call_pop"
11397 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11398 (match_operand 1 "" ""))
11399 (set (reg:SI SP_REG)
11400 (plus:SI (reg:SI SP_REG)
11401 (match_operand:SI 2 "immediate_operand" "i")))]
11402 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11403 "* return ix86_output_call_insn (insn, operands[0]);"
11404 [(set_attr "type" "call")])
11405
11406 (define_insn_and_split "*sibcall_pop_vzeroupper"
11407 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11408 (match_operand 1 "" ""))
11409 (set (reg:SI SP_REG)
11410 (plus:SI (reg:SI SP_REG)
11411 (match_operand:SI 2 "immediate_operand" "i")))
11412 (unspec [(match_operand 3 "const_int_operand" "")]
11413 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11414 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11415 "#"
11416 "&& reload_completed"
11417 [(const_int 0)]
11418 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11419 [(set_attr "type" "call")])
11420
11421 (define_insn "*sibcall_pop"
11422 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11423 (match_operand 1 "" ""))
11424 (set (reg:SI SP_REG)
11425 (plus:SI (reg:SI SP_REG)
11426 (match_operand:SI 2 "immediate_operand" "i")))]
11427 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11428 "* return ix86_output_call_insn (insn, operands[0]);"
11429 [(set_attr "type" "call")])
11430
11431 ;; Call subroutine, returning value in operand 0
11432
11433 (define_expand "call_value"
11434 [(set (match_operand 0 "" "")
11435 (call (match_operand:QI 1 "" "")
11436 (match_operand 2 "" "")))
11437 (use (match_operand 3 "" ""))]
11438 ""
11439 {
11440 ix86_expand_call (operands[0], operands[1], operands[2],
11441 operands[3], NULL, false);
11442 DONE;
11443 })
11444
11445 (define_expand "sibcall_value"
11446 [(set (match_operand 0 "" "")
11447 (call (match_operand:QI 1 "" "")
11448 (match_operand 2 "" "")))
11449 (use (match_operand 3 "" ""))]
11450 ""
11451 {
11452 ix86_expand_call (operands[0], operands[1], operands[2],
11453 operands[3], NULL, true);
11454 DONE;
11455 })
11456
11457 (define_insn_and_split "*call_value_vzeroupper"
11458 [(set (match_operand 0 "" "")
11459 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11460 (match_operand 2 "" "")))
11461 (unspec [(match_operand 3 "const_int_operand" "")]
11462 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11463 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11464 "#"
11465 "&& reload_completed"
11466 [(const_int 0)]
11467 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11468 [(set_attr "type" "callv")])
11469
11470 (define_insn "*call_value"
11471 [(set (match_operand 0 "" "")
11472 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11473 (match_operand 2 "" "")))]
11474 "!SIBLING_CALL_P (insn)"
11475 "* return ix86_output_call_insn (insn, operands[1]);"
11476 [(set_attr "type" "callv")])
11477
11478 (define_insn_and_split "*sibcall_value_vzeroupper"
11479 [(set (match_operand 0 "" "")
11480 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11481 (match_operand 2 "" "")))
11482 (unspec [(match_operand 3 "const_int_operand" "")]
11483 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11484 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11485 "#"
11486 "&& reload_completed"
11487 [(const_int 0)]
11488 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11489 [(set_attr "type" "callv")])
11490
11491 (define_insn "*sibcall_value"
11492 [(set (match_operand 0 "" "")
11493 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11494 (match_operand 2 "" "")))]
11495 "SIBLING_CALL_P (insn)"
11496 "* return ix86_output_call_insn (insn, operands[1]);"
11497 [(set_attr "type" "callv")])
11498
11499 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11500 [(set (match_operand 0 "" "")
11501 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11502 (match_operand 2 "" "")))
11503 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11504 (clobber (reg:TI XMM6_REG))
11505 (clobber (reg:TI XMM7_REG))
11506 (clobber (reg:TI XMM8_REG))
11507 (clobber (reg:TI XMM9_REG))
11508 (clobber (reg:TI XMM10_REG))
11509 (clobber (reg:TI XMM11_REG))
11510 (clobber (reg:TI XMM12_REG))
11511 (clobber (reg:TI XMM13_REG))
11512 (clobber (reg:TI XMM14_REG))
11513 (clobber (reg:TI XMM15_REG))
11514 (clobber (reg:DI SI_REG))
11515 (clobber (reg:DI DI_REG))
11516 (unspec [(match_operand 3 "const_int_operand" "")]
11517 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11518 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11519 "#"
11520 "&& reload_completed"
11521 [(const_int 0)]
11522 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11523 [(set_attr "type" "callv")])
11524
11525 (define_insn "*call_value_rex64_ms_sysv"
11526 [(set (match_operand 0 "" "")
11527 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11528 (match_operand 2 "" "")))
11529 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11530 (clobber (reg:TI XMM6_REG))
11531 (clobber (reg:TI XMM7_REG))
11532 (clobber (reg:TI XMM8_REG))
11533 (clobber (reg:TI XMM9_REG))
11534 (clobber (reg:TI XMM10_REG))
11535 (clobber (reg:TI XMM11_REG))
11536 (clobber (reg:TI XMM12_REG))
11537 (clobber (reg:TI XMM13_REG))
11538 (clobber (reg:TI XMM14_REG))
11539 (clobber (reg:TI XMM15_REG))
11540 (clobber (reg:DI SI_REG))
11541 (clobber (reg:DI DI_REG))]
11542 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11543 "* return ix86_output_call_insn (insn, operands[1]);"
11544 [(set_attr "type" "callv")])
11545
11546 (define_expand "call_value_pop"
11547 [(parallel [(set (match_operand 0 "" "")
11548 (call (match_operand:QI 1 "" "")
11549 (match_operand:SI 2 "" "")))
11550 (set (reg:SI SP_REG)
11551 (plus:SI (reg:SI SP_REG)
11552 (match_operand:SI 4 "" "")))])]
11553 "!TARGET_64BIT"
11554 {
11555 ix86_expand_call (operands[0], operands[1], operands[2],
11556 operands[3], operands[4], false);
11557 DONE;
11558 })
11559
11560 (define_insn_and_split "*call_value_pop_vzeroupper"
11561 [(set (match_operand 0 "" "")
11562 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11563 (match_operand 2 "" "")))
11564 (set (reg:SI SP_REG)
11565 (plus:SI (reg:SI SP_REG)
11566 (match_operand:SI 3 "immediate_operand" "i")))
11567 (unspec [(match_operand 4 "const_int_operand" "")]
11568 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11569 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11570 "#"
11571 "&& reload_completed"
11572 [(const_int 0)]
11573 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11574 [(set_attr "type" "callv")])
11575
11576 (define_insn "*call_value_pop"
11577 [(set (match_operand 0 "" "")
11578 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11579 (match_operand 2 "" "")))
11580 (set (reg:SI SP_REG)
11581 (plus:SI (reg:SI SP_REG)
11582 (match_operand:SI 3 "immediate_operand" "i")))]
11583 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11584 "* return ix86_output_call_insn (insn, operands[1]);"
11585 [(set_attr "type" "callv")])
11586
11587 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11588 [(set (match_operand 0 "" "")
11589 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11590 (match_operand 2 "" "")))
11591 (set (reg:SI SP_REG)
11592 (plus:SI (reg:SI SP_REG)
11593 (match_operand:SI 3 "immediate_operand" "i")))
11594 (unspec [(match_operand 4 "const_int_operand" "")]
11595 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11596 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11597 "#"
11598 "&& reload_completed"
11599 [(const_int 0)]
11600 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11601 [(set_attr "type" "callv")])
11602
11603 (define_insn "*sibcall_value_pop"
11604 [(set (match_operand 0 "" "")
11605 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11606 (match_operand 2 "" "")))
11607 (set (reg:SI SP_REG)
11608 (plus:SI (reg:SI SP_REG)
11609 (match_operand:SI 3 "immediate_operand" "i")))]
11610 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11611 "* return ix86_output_call_insn (insn, operands[1]);"
11612 [(set_attr "type" "callv")])
11613
11614 ;; Call subroutine returning any type.
11615
11616 (define_expand "untyped_call"
11617 [(parallel [(call (match_operand 0 "" "")
11618 (const_int 0))
11619 (match_operand 1 "" "")
11620 (match_operand 2 "" "")])]
11621 ""
11622 {
11623 int i;
11624
11625 /* In order to give reg-stack an easier job in validating two
11626 coprocessor registers as containing a possible return value,
11627 simply pretend the untyped call returns a complex long double
11628 value.
11629
11630 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11631 and should have the default ABI. */
11632
11633 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11634 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11635 operands[0], const0_rtx,
11636 GEN_INT ((TARGET_64BIT
11637 ? (ix86_abi == SYSV_ABI
11638 ? X86_64_SSE_REGPARM_MAX
11639 : X86_64_MS_SSE_REGPARM_MAX)
11640 : X86_32_SSE_REGPARM_MAX)
11641 - 1),
11642 NULL, false);
11643
11644 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11645 {
11646 rtx set = XVECEXP (operands[2], 0, i);
11647 emit_move_insn (SET_DEST (set), SET_SRC (set));
11648 }
11649
11650 /* The optimizer does not know that the call sets the function value
11651 registers we stored in the result block. We avoid problems by
11652 claiming that all hard registers are used and clobbered at this
11653 point. */
11654 emit_insn (gen_blockage ());
11655
11656 DONE;
11657 })
11658 \f
11659 ;; Prologue and epilogue instructions
11660
11661 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11662 ;; all of memory. This blocks insns from being moved across this point.
11663
11664 (define_insn "blockage"
11665 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11666 ""
11667 ""
11668 [(set_attr "length" "0")])
11669
11670 ;; Do not schedule instructions accessing memory across this point.
11671
11672 (define_expand "memory_blockage"
11673 [(set (match_dup 0)
11674 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11675 ""
11676 {
11677 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11678 MEM_VOLATILE_P (operands[0]) = 1;
11679 })
11680
11681 (define_insn "*memory_blockage"
11682 [(set (match_operand:BLK 0 "" "")
11683 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11684 ""
11685 ""
11686 [(set_attr "length" "0")])
11687
11688 ;; As USE insns aren't meaningful after reload, this is used instead
11689 ;; to prevent deleting instructions setting registers for PIC code
11690 (define_insn "prologue_use"
11691 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11692 ""
11693 ""
11694 [(set_attr "length" "0")])
11695
11696 ;; Insn emitted into the body of a function to return from a function.
11697 ;; This is only done if the function's epilogue is known to be simple.
11698 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11699
11700 (define_expand "return"
11701 [(simple_return)]
11702 "ix86_can_use_return_insn_p ()"
11703 {
11704 if (crtl->args.pops_args)
11705 {
11706 rtx popc = GEN_INT (crtl->args.pops_args);
11707 emit_jump_insn (gen_simple_return_pop_internal (popc));
11708 DONE;
11709 }
11710 })
11711
11712 ;; We need to disable this for TARGET_SEH, as otherwise
11713 ;; shrink-wrapped prologue gets enabled too. This might exceed
11714 ;; the maximum size of prologue in unwind information.
11715
11716 (define_expand "simple_return"
11717 [(simple_return)]
11718 "!TARGET_SEH"
11719 {
11720 if (crtl->args.pops_args)
11721 {
11722 rtx popc = GEN_INT (crtl->args.pops_args);
11723 emit_jump_insn (gen_simple_return_pop_internal (popc));
11724 DONE;
11725 }
11726 })
11727
11728 (define_insn "simple_return_internal"
11729 [(simple_return)]
11730 "reload_completed"
11731 "ret"
11732 [(set_attr "length" "1")
11733 (set_attr "atom_unit" "jeu")
11734 (set_attr "length_immediate" "0")
11735 (set_attr "modrm" "0")])
11736
11737 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11738 ;; instruction Athlon and K8 have.
11739
11740 (define_insn "simple_return_internal_long"
11741 [(simple_return)
11742 (unspec [(const_int 0)] UNSPEC_REP)]
11743 "reload_completed"
11744 "rep\;ret"
11745 [(set_attr "length" "2")
11746 (set_attr "atom_unit" "jeu")
11747 (set_attr "length_immediate" "0")
11748 (set_attr "prefix_rep" "1")
11749 (set_attr "modrm" "0")])
11750
11751 (define_insn "simple_return_pop_internal"
11752 [(simple_return)
11753 (use (match_operand:SI 0 "const_int_operand" ""))]
11754 "reload_completed"
11755 "ret\t%0"
11756 [(set_attr "length" "3")
11757 (set_attr "atom_unit" "jeu")
11758 (set_attr "length_immediate" "2")
11759 (set_attr "modrm" "0")])
11760
11761 (define_insn "simple_return_indirect_internal"
11762 [(simple_return)
11763 (use (match_operand:SI 0 "register_operand" "r"))]
11764 "reload_completed"
11765 "jmp\t%A0"
11766 [(set_attr "type" "ibr")
11767 (set_attr "length_immediate" "0")])
11768
11769 (define_insn "nop"
11770 [(const_int 0)]
11771 ""
11772 "nop"
11773 [(set_attr "length" "1")
11774 (set_attr "length_immediate" "0")
11775 (set_attr "modrm" "0")])
11776
11777 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11778 (define_insn "nops"
11779 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11780 UNSPECV_NOPS)]
11781 "reload_completed"
11782 {
11783 int num = INTVAL (operands[0]);
11784
11785 gcc_assert (num >= 1 && num <= 8);
11786
11787 while (num--)
11788 fputs ("\tnop\n", asm_out_file);
11789
11790 return "";
11791 }
11792 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11793 (set_attr "length_immediate" "0")
11794 (set_attr "modrm" "0")])
11795
11796 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11797 ;; branch prediction penalty for the third jump in a 16-byte
11798 ;; block on K8.
11799
11800 (define_insn "pad"
11801 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11802 ""
11803 {
11804 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11805 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11806 #else
11807 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11808 The align insn is used to avoid 3 jump instructions in the row to improve
11809 branch prediction and the benefits hardly outweigh the cost of extra 8
11810 nops on the average inserted by full alignment pseudo operation. */
11811 #endif
11812 return "";
11813 }
11814 [(set_attr "length" "16")])
11815
11816 (define_expand "prologue"
11817 [(const_int 0)]
11818 ""
11819 "ix86_expand_prologue (); DONE;")
11820
11821 (define_insn "set_got"
11822 [(set (match_operand:SI 0 "register_operand" "=r")
11823 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11824 (clobber (reg:CC FLAGS_REG))]
11825 "!TARGET_64BIT"
11826 "* return output_set_got (operands[0], NULL_RTX);"
11827 [(set_attr "type" "multi")
11828 (set_attr "length" "12")])
11829
11830 (define_insn "set_got_labelled"
11831 [(set (match_operand:SI 0 "register_operand" "=r")
11832 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11833 UNSPEC_SET_GOT))
11834 (clobber (reg:CC FLAGS_REG))]
11835 "!TARGET_64BIT"
11836 "* return output_set_got (operands[0], operands[1]);"
11837 [(set_attr "type" "multi")
11838 (set_attr "length" "12")])
11839
11840 (define_insn "set_got_rex64"
11841 [(set (match_operand:DI 0 "register_operand" "=r")
11842 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11843 "TARGET_64BIT"
11844 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11845 [(set_attr "type" "lea")
11846 (set_attr "length_address" "4")
11847 (set_attr "mode" "DI")])
11848
11849 (define_insn "set_rip_rex64"
11850 [(set (match_operand:DI 0 "register_operand" "=r")
11851 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11852 "TARGET_64BIT"
11853 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11854 [(set_attr "type" "lea")
11855 (set_attr "length_address" "4")
11856 (set_attr "mode" "DI")])
11857
11858 (define_insn "set_got_offset_rex64"
11859 [(set (match_operand:DI 0 "register_operand" "=r")
11860 (unspec:DI
11861 [(label_ref (match_operand 1 "" ""))]
11862 UNSPEC_SET_GOT_OFFSET))]
11863 "TARGET_LP64"
11864 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11865 [(set_attr "type" "imov")
11866 (set_attr "length_immediate" "0")
11867 (set_attr "length_address" "8")
11868 (set_attr "mode" "DI")])
11869
11870 (define_expand "epilogue"
11871 [(const_int 0)]
11872 ""
11873 "ix86_expand_epilogue (1); DONE;")
11874
11875 (define_expand "sibcall_epilogue"
11876 [(const_int 0)]
11877 ""
11878 "ix86_expand_epilogue (0); DONE;")
11879
11880 (define_expand "eh_return"
11881 [(use (match_operand 0 "register_operand" ""))]
11882 ""
11883 {
11884 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11885
11886 /* Tricky bit: we write the address of the handler to which we will
11887 be returning into someone else's stack frame, one word below the
11888 stack address we wish to restore. */
11889 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11890 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11891 tmp = gen_rtx_MEM (Pmode, tmp);
11892 emit_move_insn (tmp, ra);
11893
11894 emit_jump_insn (gen_eh_return_internal ());
11895 emit_barrier ();
11896 DONE;
11897 })
11898
11899 (define_insn_and_split "eh_return_internal"
11900 [(eh_return)]
11901 ""
11902 "#"
11903 "epilogue_completed"
11904 [(const_int 0)]
11905 "ix86_expand_epilogue (2); DONE;")
11906
11907 (define_insn "leave"
11908 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11909 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11910 (clobber (mem:BLK (scratch)))]
11911 "!TARGET_64BIT"
11912 "leave"
11913 [(set_attr "type" "leave")])
11914
11915 (define_insn "leave_rex64"
11916 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11917 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11918 (clobber (mem:BLK (scratch)))]
11919 "TARGET_64BIT"
11920 "leave"
11921 [(set_attr "type" "leave")])
11922 \f
11923 ;; Handle -fsplit-stack.
11924
11925 (define_expand "split_stack_prologue"
11926 [(const_int 0)]
11927 ""
11928 {
11929 ix86_expand_split_stack_prologue ();
11930 DONE;
11931 })
11932
11933 ;; In order to support the call/return predictor, we use a return
11934 ;; instruction which the middle-end doesn't see.
11935 (define_insn "split_stack_return"
11936 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11937 UNSPECV_SPLIT_STACK_RETURN)]
11938 ""
11939 {
11940 if (operands[0] == const0_rtx)
11941 return "ret";
11942 else
11943 return "ret\t%0";
11944 }
11945 [(set_attr "atom_unit" "jeu")
11946 (set_attr "modrm" "0")
11947 (set (attr "length")
11948 (if_then_else (match_operand:SI 0 "const0_operand" "")
11949 (const_int 1)
11950 (const_int 3)))
11951 (set (attr "length_immediate")
11952 (if_then_else (match_operand:SI 0 "const0_operand" "")
11953 (const_int 0)
11954 (const_int 2)))])
11955
11956 ;; If there are operand 0 bytes available on the stack, jump to
11957 ;; operand 1.
11958
11959 (define_expand "split_stack_space_check"
11960 [(set (pc) (if_then_else
11961 (ltu (minus (reg SP_REG)
11962 (match_operand 0 "register_operand" ""))
11963 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11964 (label_ref (match_operand 1 "" ""))
11965 (pc)))]
11966 ""
11967 {
11968 rtx reg, size, limit;
11969
11970 reg = gen_reg_rtx (Pmode);
11971 size = force_reg (Pmode, operands[0]);
11972 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11973 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11974 UNSPEC_STACK_CHECK);
11975 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11976 ix86_expand_branch (GEU, reg, limit, operands[1]);
11977
11978 DONE;
11979 })
11980 \f
11981 ;; Bit manipulation instructions.
11982
11983 (define_expand "ffs<mode>2"
11984 [(set (match_dup 2) (const_int -1))
11985 (parallel [(set (reg:CCZ FLAGS_REG)
11986 (compare:CCZ
11987 (match_operand:SWI48 1 "nonimmediate_operand" "")
11988 (const_int 0)))
11989 (set (match_operand:SWI48 0 "register_operand" "")
11990 (ctz:SWI48 (match_dup 1)))])
11991 (set (match_dup 0) (if_then_else:SWI48
11992 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11993 (match_dup 2)
11994 (match_dup 0)))
11995 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11996 (clobber (reg:CC FLAGS_REG))])]
11997 ""
11998 {
11999 if (<MODE>mode == SImode && !TARGET_CMOVE)
12000 {
12001 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12002 DONE;
12003 }
12004 operands[2] = gen_reg_rtx (<MODE>mode);
12005 })
12006
12007 (define_insn_and_split "ffssi2_no_cmove"
12008 [(set (match_operand:SI 0 "register_operand" "=r")
12009 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12010 (clobber (match_scratch:SI 2 "=&q"))
12011 (clobber (reg:CC FLAGS_REG))]
12012 "!TARGET_CMOVE"
12013 "#"
12014 "&& reload_completed"
12015 [(parallel [(set (reg:CCZ FLAGS_REG)
12016 (compare:CCZ (match_dup 1) (const_int 0)))
12017 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12018 (set (strict_low_part (match_dup 3))
12019 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12020 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12021 (clobber (reg:CC FLAGS_REG))])
12022 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12023 (clobber (reg:CC FLAGS_REG))])
12024 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12025 (clobber (reg:CC FLAGS_REG))])]
12026 {
12027 operands[3] = gen_lowpart (QImode, operands[2]);
12028 ix86_expand_clear (operands[2]);
12029 })
12030
12031 (define_insn "*ffs<mode>_1"
12032 [(set (reg:CCZ FLAGS_REG)
12033 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12034 (const_int 0)))
12035 (set (match_operand:SWI48 0 "register_operand" "=r")
12036 (ctz:SWI48 (match_dup 1)))]
12037 ""
12038 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12039 [(set_attr "type" "alu1")
12040 (set_attr "prefix_0f" "1")
12041 (set_attr "mode" "<MODE>")])
12042
12043 (define_insn "ctz<mode>2"
12044 [(set (match_operand:SWI248 0 "register_operand" "=r")
12045 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12046 (clobber (reg:CC FLAGS_REG))]
12047 ""
12048 {
12049 if (TARGET_BMI)
12050 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12051 else
12052 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12053 }
12054 [(set_attr "type" "alu1")
12055 (set_attr "prefix_0f" "1")
12056 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12057 (set_attr "mode" "<MODE>")])
12058
12059 (define_expand "clz<mode>2"
12060 [(parallel
12061 [(set (match_operand:SWI248 0 "register_operand" "")
12062 (minus:SWI248
12063 (match_dup 2)
12064 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12065 (clobber (reg:CC FLAGS_REG))])
12066 (parallel
12067 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12068 (clobber (reg:CC FLAGS_REG))])]
12069 ""
12070 {
12071 if (TARGET_LZCNT)
12072 {
12073 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12074 DONE;
12075 }
12076 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12077 })
12078
12079 (define_insn "clz<mode>2_lzcnt"
12080 [(set (match_operand:SWI248 0 "register_operand" "=r")
12081 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12082 (clobber (reg:CC FLAGS_REG))]
12083 "TARGET_LZCNT"
12084 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12085 [(set_attr "prefix_rep" "1")
12086 (set_attr "type" "bitmanip")
12087 (set_attr "mode" "<MODE>")])
12088
12089 ;; BMI instructions.
12090 (define_insn "*bmi_andn_<mode>"
12091 [(set (match_operand:SWI48 0 "register_operand" "=r")
12092 (and:SWI48
12093 (not:SWI48
12094 (match_operand:SWI48 1 "register_operand" "r"))
12095 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12096 (clobber (reg:CC FLAGS_REG))]
12097 "TARGET_BMI"
12098 "andn\t{%2, %1, %0|%0, %1, %2}"
12099 [(set_attr "type" "bitmanip")
12100 (set_attr "mode" "<MODE>")])
12101
12102 (define_insn "bmi_bextr_<mode>"
12103 [(set (match_operand:SWI48 0 "register_operand" "=r")
12104 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12105 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12106 UNSPEC_BEXTR))
12107 (clobber (reg:CC FLAGS_REG))]
12108 "TARGET_BMI"
12109 "bextr\t{%2, %1, %0|%0, %1, %2}"
12110 [(set_attr "type" "bitmanip")
12111 (set_attr "mode" "<MODE>")])
12112
12113 (define_insn "*bmi_blsi_<mode>"
12114 [(set (match_operand:SWI48 0 "register_operand" "=r")
12115 (and:SWI48
12116 (neg:SWI48
12117 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12118 (match_dup 1)))
12119 (clobber (reg:CC FLAGS_REG))]
12120 "TARGET_BMI"
12121 "blsi\t{%1, %0|%0, %1}"
12122 [(set_attr "type" "bitmanip")
12123 (set_attr "mode" "<MODE>")])
12124
12125 (define_insn "*bmi_blsmsk_<mode>"
12126 [(set (match_operand:SWI48 0 "register_operand" "=r")
12127 (xor:SWI48
12128 (plus:SWI48
12129 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12130 (const_int -1))
12131 (match_dup 1)))
12132 (clobber (reg:CC FLAGS_REG))]
12133 "TARGET_BMI"
12134 "blsmsk\t{%1, %0|%0, %1}"
12135 [(set_attr "type" "bitmanip")
12136 (set_attr "mode" "<MODE>")])
12137
12138 (define_insn "*bmi_blsr_<mode>"
12139 [(set (match_operand:SWI48 0 "register_operand" "=r")
12140 (and:SWI48
12141 (plus:SWI48
12142 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12143 (const_int -1))
12144 (match_dup 1)))
12145 (clobber (reg:CC FLAGS_REG))]
12146 "TARGET_BMI"
12147 "blsr\t{%1, %0|%0, %1}"
12148 [(set_attr "type" "bitmanip")
12149 (set_attr "mode" "<MODE>")])
12150
12151 ;; BMI2 instructions.
12152 (define_insn "bmi2_bzhi_<mode>3"
12153 [(set (match_operand:SWI48 0 "register_operand" "=r")
12154 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12155 (lshiftrt:SWI48 (const_int -1)
12156 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12157 (clobber (reg:CC FLAGS_REG))]
12158 "TARGET_BMI2"
12159 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12160 [(set_attr "type" "bitmanip")
12161 (set_attr "prefix" "vex")
12162 (set_attr "mode" "<MODE>")])
12163
12164 (define_insn "bmi2_pdep_<mode>3"
12165 [(set (match_operand:SWI48 0 "register_operand" "=r")
12166 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12167 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12168 UNSPEC_PDEP))]
12169 "TARGET_BMI2"
12170 "pdep\t{%2, %1, %0|%0, %1, %2}"
12171 [(set_attr "type" "bitmanip")
12172 (set_attr "prefix" "vex")
12173 (set_attr "mode" "<MODE>")])
12174
12175 (define_insn "bmi2_pext_<mode>3"
12176 [(set (match_operand:SWI48 0 "register_operand" "=r")
12177 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12178 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12179 UNSPEC_PEXT))]
12180 "TARGET_BMI2"
12181 "pext\t{%2, %1, %0|%0, %1, %2}"
12182 [(set_attr "type" "bitmanip")
12183 (set_attr "prefix" "vex")
12184 (set_attr "mode" "<MODE>")])
12185
12186 ;; TBM instructions.
12187 (define_insn "tbm_bextri_<mode>"
12188 [(set (match_operand:SWI48 0 "register_operand" "=r")
12189 (zero_extract:SWI48
12190 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12191 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12192 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12193 (clobber (reg:CC FLAGS_REG))]
12194 "TARGET_TBM"
12195 {
12196 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12197 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12198 }
12199 [(set_attr "type" "bitmanip")
12200 (set_attr "mode" "<MODE>")])
12201
12202 (define_insn "*tbm_blcfill_<mode>"
12203 [(set (match_operand:SWI48 0 "register_operand" "=r")
12204 (and:SWI48
12205 (plus:SWI48
12206 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12207 (const_int 1))
12208 (match_dup 1)))
12209 (clobber (reg:CC FLAGS_REG))]
12210 "TARGET_TBM"
12211 "blcfill\t{%1, %0|%0, %1}"
12212 [(set_attr "type" "bitmanip")
12213 (set_attr "mode" "<MODE>")])
12214
12215 (define_insn "*tbm_blci_<mode>"
12216 [(set (match_operand:SWI48 0 "register_operand" "=r")
12217 (ior:SWI48
12218 (not:SWI48
12219 (plus:SWI48
12220 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12221 (const_int 1)))
12222 (match_dup 1)))
12223 (clobber (reg:CC FLAGS_REG))]
12224 "TARGET_TBM"
12225 "blci\t{%1, %0|%0, %1}"
12226 [(set_attr "type" "bitmanip")
12227 (set_attr "mode" "<MODE>")])
12228
12229 (define_insn "*tbm_blcic_<mode>"
12230 [(set (match_operand:SWI48 0 "register_operand" "=r")
12231 (and:SWI48
12232 (plus:SWI48
12233 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12234 (const_int 1))
12235 (not:SWI48
12236 (match_dup 1))))
12237 (clobber (reg:CC FLAGS_REG))]
12238 "TARGET_TBM"
12239 "blcic\t{%1, %0|%0, %1}"
12240 [(set_attr "type" "bitmanip")
12241 (set_attr "mode" "<MODE>")])
12242
12243 (define_insn "*tbm_blcmsk_<mode>"
12244 [(set (match_operand:SWI48 0 "register_operand" "=r")
12245 (xor:SWI48
12246 (plus:SWI48
12247 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12248 (const_int 1))
12249 (match_dup 1)))
12250 (clobber (reg:CC FLAGS_REG))]
12251 "TARGET_TBM"
12252 "blcmsk\t{%1, %0|%0, %1}"
12253 [(set_attr "type" "bitmanip")
12254 (set_attr "mode" "<MODE>")])
12255
12256 (define_insn "*tbm_blcs_<mode>"
12257 [(set (match_operand:SWI48 0 "register_operand" "=r")
12258 (ior:SWI48
12259 (plus:SWI48
12260 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12261 (const_int 1))
12262 (match_dup 1)))
12263 (clobber (reg:CC FLAGS_REG))]
12264 "TARGET_TBM"
12265 "blcs\t{%1, %0|%0, %1}"
12266 [(set_attr "type" "bitmanip")
12267 (set_attr "mode" "<MODE>")])
12268
12269 (define_insn "*tbm_blsfill_<mode>"
12270 [(set (match_operand:SWI48 0 "register_operand" "=r")
12271 (ior:SWI48
12272 (plus:SWI48
12273 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12274 (const_int -1))
12275 (match_dup 1)))
12276 (clobber (reg:CC FLAGS_REG))]
12277 "TARGET_TBM"
12278 "blsfill\t{%1, %0|%0, %1}"
12279 [(set_attr "type" "bitmanip")
12280 (set_attr "mode" "<MODE>")])
12281
12282 (define_insn "*tbm_blsic_<mode>"
12283 [(set (match_operand:SWI48 0 "register_operand" "=r")
12284 (ior:SWI48
12285 (plus:SWI48
12286 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12287 (const_int -1))
12288 (not:SWI48
12289 (match_dup 1))))
12290 (clobber (reg:CC FLAGS_REG))]
12291 "TARGET_TBM"
12292 "blsic\t{%1, %0|%0, %1}"
12293 [(set_attr "type" "bitmanip")
12294 (set_attr "mode" "<MODE>")])
12295
12296 (define_insn "*tbm_t1mskc_<mode>"
12297 [(set (match_operand:SWI48 0 "register_operand" "=r")
12298 (ior:SWI48
12299 (plus:SWI48
12300 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12301 (const_int 1))
12302 (not:SWI48
12303 (match_dup 1))))
12304 (clobber (reg:CC FLAGS_REG))]
12305 "TARGET_TBM"
12306 "t1mskc\t{%1, %0|%0, %1}"
12307 [(set_attr "type" "bitmanip")
12308 (set_attr "mode" "<MODE>")])
12309
12310 (define_insn "*tbm_tzmsk_<mode>"
12311 [(set (match_operand:SWI48 0 "register_operand" "=r")
12312 (and:SWI48
12313 (plus:SWI48
12314 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12315 (const_int -1))
12316 (not:SWI48
12317 (match_dup 1))))
12318 (clobber (reg:CC FLAGS_REG))]
12319 "TARGET_TBM"
12320 "tzmsk\t{%1, %0|%0, %1}"
12321 [(set_attr "type" "bitmanip")
12322 (set_attr "mode" "<MODE>")])
12323
12324 (define_insn "bsr_rex64"
12325 [(set (match_operand:DI 0 "register_operand" "=r")
12326 (minus:DI (const_int 63)
12327 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12328 (clobber (reg:CC FLAGS_REG))]
12329 "TARGET_64BIT"
12330 "bsr{q}\t{%1, %0|%0, %1}"
12331 [(set_attr "type" "alu1")
12332 (set_attr "prefix_0f" "1")
12333 (set_attr "mode" "DI")])
12334
12335 (define_insn "bsr"
12336 [(set (match_operand:SI 0 "register_operand" "=r")
12337 (minus:SI (const_int 31)
12338 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12339 (clobber (reg:CC FLAGS_REG))]
12340 ""
12341 "bsr{l}\t{%1, %0|%0, %1}"
12342 [(set_attr "type" "alu1")
12343 (set_attr "prefix_0f" "1")
12344 (set_attr "mode" "SI")])
12345
12346 (define_insn "*bsrhi"
12347 [(set (match_operand:HI 0 "register_operand" "=r")
12348 (minus:HI (const_int 15)
12349 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12350 (clobber (reg:CC FLAGS_REG))]
12351 ""
12352 "bsr{w}\t{%1, %0|%0, %1}"
12353 [(set_attr "type" "alu1")
12354 (set_attr "prefix_0f" "1")
12355 (set_attr "mode" "HI")])
12356
12357 (define_insn "popcount<mode>2"
12358 [(set (match_operand:SWI248 0 "register_operand" "=r")
12359 (popcount:SWI248
12360 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12361 (clobber (reg:CC FLAGS_REG))]
12362 "TARGET_POPCNT"
12363 {
12364 #if TARGET_MACHO
12365 return "popcnt\t{%1, %0|%0, %1}";
12366 #else
12367 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12368 #endif
12369 }
12370 [(set_attr "prefix_rep" "1")
12371 (set_attr "type" "bitmanip")
12372 (set_attr "mode" "<MODE>")])
12373
12374 (define_insn "*popcount<mode>2_cmp"
12375 [(set (reg FLAGS_REG)
12376 (compare
12377 (popcount:SWI248
12378 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12379 (const_int 0)))
12380 (set (match_operand:SWI248 0 "register_operand" "=r")
12381 (popcount:SWI248 (match_dup 1)))]
12382 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12383 {
12384 #if TARGET_MACHO
12385 return "popcnt\t{%1, %0|%0, %1}";
12386 #else
12387 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12388 #endif
12389 }
12390 [(set_attr "prefix_rep" "1")
12391 (set_attr "type" "bitmanip")
12392 (set_attr "mode" "<MODE>")])
12393
12394 (define_insn "*popcountsi2_cmp_zext"
12395 [(set (reg FLAGS_REG)
12396 (compare
12397 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12398 (const_int 0)))
12399 (set (match_operand:DI 0 "register_operand" "=r")
12400 (zero_extend:DI(popcount:SI (match_dup 1))))]
12401 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12402 {
12403 #if TARGET_MACHO
12404 return "popcnt\t{%1, %0|%0, %1}";
12405 #else
12406 return "popcnt{l}\t{%1, %0|%0, %1}";
12407 #endif
12408 }
12409 [(set_attr "prefix_rep" "1")
12410 (set_attr "type" "bitmanip")
12411 (set_attr "mode" "SI")])
12412
12413 (define_expand "bswap<mode>2"
12414 [(set (match_operand:SWI48 0 "register_operand" "")
12415 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12416 ""
12417 {
12418 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12419 {
12420 rtx x = operands[0];
12421
12422 emit_move_insn (x, operands[1]);
12423 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12424 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12425 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12426 DONE;
12427 }
12428 })
12429
12430 (define_insn "*bswap<mode>2_movbe"
12431 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12432 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12433 "TARGET_MOVBE
12434 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12435 "@
12436 bswap\t%0
12437 movbe\t{%1, %0|%0, %1}
12438 movbe\t{%1, %0|%0, %1}"
12439 [(set_attr "type" "bitmanip,imov,imov")
12440 (set_attr "modrm" "0,1,1")
12441 (set_attr "prefix_0f" "*,1,1")
12442 (set_attr "prefix_extra" "*,1,1")
12443 (set_attr "mode" "<MODE>")])
12444
12445 (define_insn "*bswap<mode>2_1"
12446 [(set (match_operand:SWI48 0 "register_operand" "=r")
12447 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12448 "TARGET_BSWAP"
12449 "bswap\t%0"
12450 [(set_attr "type" "bitmanip")
12451 (set_attr "modrm" "0")
12452 (set_attr "mode" "<MODE>")])
12453
12454 (define_insn "*bswaphi_lowpart_1"
12455 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12456 (bswap:HI (match_dup 0)))
12457 (clobber (reg:CC FLAGS_REG))]
12458 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12459 "@
12460 xchg{b}\t{%h0, %b0|%b0, %h0}
12461 rol{w}\t{$8, %0|%0, 8}"
12462 [(set_attr "length" "2,4")
12463 (set_attr "mode" "QI,HI")])
12464
12465 (define_insn "bswaphi_lowpart"
12466 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12467 (bswap:HI (match_dup 0)))
12468 (clobber (reg:CC FLAGS_REG))]
12469 ""
12470 "rol{w}\t{$8, %0|%0, 8}"
12471 [(set_attr "length" "4")
12472 (set_attr "mode" "HI")])
12473
12474 (define_expand "paritydi2"
12475 [(set (match_operand:DI 0 "register_operand" "")
12476 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12477 "! TARGET_POPCNT"
12478 {
12479 rtx scratch = gen_reg_rtx (QImode);
12480 rtx cond;
12481
12482 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12483 NULL_RTX, operands[1]));
12484
12485 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12486 gen_rtx_REG (CCmode, FLAGS_REG),
12487 const0_rtx);
12488 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12489
12490 if (TARGET_64BIT)
12491 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12492 else
12493 {
12494 rtx tmp = gen_reg_rtx (SImode);
12495
12496 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12497 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12498 }
12499 DONE;
12500 })
12501
12502 (define_expand "paritysi2"
12503 [(set (match_operand:SI 0 "register_operand" "")
12504 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12505 "! TARGET_POPCNT"
12506 {
12507 rtx scratch = gen_reg_rtx (QImode);
12508 rtx cond;
12509
12510 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12511
12512 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12513 gen_rtx_REG (CCmode, FLAGS_REG),
12514 const0_rtx);
12515 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12516
12517 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12518 DONE;
12519 })
12520
12521 (define_insn_and_split "paritydi2_cmp"
12522 [(set (reg:CC FLAGS_REG)
12523 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12524 UNSPEC_PARITY))
12525 (clobber (match_scratch:DI 0 "=r"))
12526 (clobber (match_scratch:SI 1 "=&r"))
12527 (clobber (match_scratch:HI 2 "=Q"))]
12528 "! TARGET_POPCNT"
12529 "#"
12530 "&& reload_completed"
12531 [(parallel
12532 [(set (match_dup 1)
12533 (xor:SI (match_dup 1) (match_dup 4)))
12534 (clobber (reg:CC FLAGS_REG))])
12535 (parallel
12536 [(set (reg:CC FLAGS_REG)
12537 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12538 (clobber (match_dup 1))
12539 (clobber (match_dup 2))])]
12540 {
12541 operands[4] = gen_lowpart (SImode, operands[3]);
12542
12543 if (TARGET_64BIT)
12544 {
12545 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12546 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12547 }
12548 else
12549 operands[1] = gen_highpart (SImode, operands[3]);
12550 })
12551
12552 (define_insn_and_split "paritysi2_cmp"
12553 [(set (reg:CC FLAGS_REG)
12554 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12555 UNSPEC_PARITY))
12556 (clobber (match_scratch:SI 0 "=r"))
12557 (clobber (match_scratch:HI 1 "=&Q"))]
12558 "! TARGET_POPCNT"
12559 "#"
12560 "&& reload_completed"
12561 [(parallel
12562 [(set (match_dup 1)
12563 (xor:HI (match_dup 1) (match_dup 3)))
12564 (clobber (reg:CC FLAGS_REG))])
12565 (parallel
12566 [(set (reg:CC FLAGS_REG)
12567 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12568 (clobber (match_dup 1))])]
12569 {
12570 operands[3] = gen_lowpart (HImode, operands[2]);
12571
12572 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12573 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12574 })
12575
12576 (define_insn "*parityhi2_cmp"
12577 [(set (reg:CC FLAGS_REG)
12578 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12579 UNSPEC_PARITY))
12580 (clobber (match_scratch:HI 0 "=Q"))]
12581 "! TARGET_POPCNT"
12582 "xor{b}\t{%h0, %b0|%b0, %h0}"
12583 [(set_attr "length" "2")
12584 (set_attr "mode" "HI")])
12585
12586 \f
12587 ;; Thread-local storage patterns for ELF.
12588 ;;
12589 ;; Note that these code sequences must appear exactly as shown
12590 ;; in order to allow linker relaxation.
12591
12592 (define_insn "*tls_global_dynamic_32_gnu"
12593 [(set (match_operand:SI 0 "register_operand" "=a")
12594 (unspec:SI
12595 [(match_operand:SI 1 "register_operand" "b")
12596 (match_operand:SI 2 "tls_symbolic_operand" "")
12597 (match_operand:SI 3 "constant_call_address_operand" "z")]
12598 UNSPEC_TLS_GD))
12599 (clobber (match_scratch:SI 4 "=d"))
12600 (clobber (match_scratch:SI 5 "=c"))
12601 (clobber (reg:CC FLAGS_REG))]
12602 "!TARGET_64BIT && TARGET_GNU_TLS"
12603 {
12604 output_asm_insn
12605 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12606 if (TARGET_SUN_TLS)
12607 #ifdef HAVE_AS_IX86_TLSGDPLT
12608 return "call\t%a2@tlsgdplt";
12609 #else
12610 return "call\t%p3@plt";
12611 #endif
12612 return "call\t%P3";
12613 }
12614 [(set_attr "type" "multi")
12615 (set_attr "length" "12")])
12616
12617 (define_expand "tls_global_dynamic_32"
12618 [(parallel
12619 [(set (match_operand:SI 0 "register_operand" "")
12620 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12621 (match_operand:SI 1 "tls_symbolic_operand" "")
12622 (match_operand:SI 3 "constant_call_address_operand" "")]
12623 UNSPEC_TLS_GD))
12624 (clobber (match_scratch:SI 4 ""))
12625 (clobber (match_scratch:SI 5 ""))
12626 (clobber (reg:CC FLAGS_REG))])])
12627
12628 (define_insn "*tls_global_dynamic_64"
12629 [(set (match_operand:DI 0 "register_operand" "=a")
12630 (call:DI
12631 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12632 (match_operand:DI 3 "" "")))
12633 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12634 UNSPEC_TLS_GD)]
12635 "TARGET_64BIT"
12636 {
12637 if (!TARGET_X32)
12638 fputs (ASM_BYTE "0x66\n", asm_out_file);
12639 output_asm_insn
12640 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12641 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12642 fputs ("\trex64\n", asm_out_file);
12643 if (TARGET_SUN_TLS)
12644 return "call\t%p2@plt";
12645 return "call\t%P2";
12646 }
12647 [(set_attr "type" "multi")
12648 (set (attr "length")
12649 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12650
12651 (define_expand "tls_global_dynamic_64"
12652 [(parallel
12653 [(set (match_operand:DI 0 "register_operand" "")
12654 (call:DI
12655 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12656 (const_int 0)))
12657 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12658 UNSPEC_TLS_GD)])])
12659
12660 (define_insn "*tls_local_dynamic_base_32_gnu"
12661 [(set (match_operand:SI 0 "register_operand" "=a")
12662 (unspec:SI
12663 [(match_operand:SI 1 "register_operand" "b")
12664 (match_operand:SI 2 "constant_call_address_operand" "z")]
12665 UNSPEC_TLS_LD_BASE))
12666 (clobber (match_scratch:SI 3 "=d"))
12667 (clobber (match_scratch:SI 4 "=c"))
12668 (clobber (reg:CC FLAGS_REG))]
12669 "!TARGET_64BIT && TARGET_GNU_TLS"
12670 {
12671 output_asm_insn
12672 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12673 if (TARGET_SUN_TLS)
12674 #ifdef HAVE_AS_IX86_TLSLDMPLT
12675 return "call\t%&@tlsldmplt";
12676 #else
12677 return "call\t%p2@plt";
12678 #endif
12679 return "call\t%P2";
12680 }
12681 [(set_attr "type" "multi")
12682 (set_attr "length" "11")])
12683
12684 (define_expand "tls_local_dynamic_base_32"
12685 [(parallel
12686 [(set (match_operand:SI 0 "register_operand" "")
12687 (unspec:SI
12688 [(match_operand:SI 1 "register_operand" "")
12689 (match_operand:SI 2 "constant_call_address_operand" "")]
12690 UNSPEC_TLS_LD_BASE))
12691 (clobber (match_scratch:SI 3 ""))
12692 (clobber (match_scratch:SI 4 ""))
12693 (clobber (reg:CC FLAGS_REG))])])
12694
12695 (define_insn "*tls_local_dynamic_base_64"
12696 [(set (match_operand:DI 0 "register_operand" "=a")
12697 (call:DI
12698 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12699 (match_operand:DI 2 "" "")))
12700 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12701 "TARGET_64BIT"
12702 {
12703 output_asm_insn
12704 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12705 if (TARGET_SUN_TLS)
12706 return "call\t%p1@plt";
12707 return "call\t%P1";
12708 }
12709 [(set_attr "type" "multi")
12710 (set_attr "length" "12")])
12711
12712 (define_expand "tls_local_dynamic_base_64"
12713 [(parallel
12714 [(set (match_operand:DI 0 "register_operand" "")
12715 (call:DI
12716 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12717 (const_int 0)))
12718 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12719
12720 ;; Local dynamic of a single variable is a lose. Show combine how
12721 ;; to convert that back to global dynamic.
12722
12723 (define_insn_and_split "*tls_local_dynamic_32_once"
12724 [(set (match_operand:SI 0 "register_operand" "=a")
12725 (plus:SI
12726 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12727 (match_operand:SI 2 "constant_call_address_operand" "z")]
12728 UNSPEC_TLS_LD_BASE)
12729 (const:SI (unspec:SI
12730 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12731 UNSPEC_DTPOFF))))
12732 (clobber (match_scratch:SI 4 "=d"))
12733 (clobber (match_scratch:SI 5 "=c"))
12734 (clobber (reg:CC FLAGS_REG))]
12735 ""
12736 "#"
12737 ""
12738 [(parallel
12739 [(set (match_dup 0)
12740 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12741 UNSPEC_TLS_GD))
12742 (clobber (match_dup 4))
12743 (clobber (match_dup 5))
12744 (clobber (reg:CC FLAGS_REG))])])
12745
12746 ;; Segment register for the thread base ptr load
12747 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12748
12749 ;; Load and add the thread base pointer from %<tp_seg>:0.
12750 (define_insn "*load_tp_x32"
12751 [(set (match_operand:SI 0 "register_operand" "=r")
12752 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12753 "TARGET_X32"
12754 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12755 [(set_attr "type" "imov")
12756 (set_attr "modrm" "0")
12757 (set_attr "length" "7")
12758 (set_attr "memory" "load")
12759 (set_attr "imm_disp" "false")])
12760
12761 (define_insn "*load_tp_x32_zext"
12762 [(set (match_operand:DI 0 "register_operand" "=r")
12763 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12764 "TARGET_X32"
12765 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12766 [(set_attr "type" "imov")
12767 (set_attr "modrm" "0")
12768 (set_attr "length" "7")
12769 (set_attr "memory" "load")
12770 (set_attr "imm_disp" "false")])
12771
12772 (define_insn "*load_tp_<mode>"
12773 [(set (match_operand:P 0 "register_operand" "=r")
12774 (unspec:P [(const_int 0)] UNSPEC_TP))]
12775 "!TARGET_X32"
12776 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12777 [(set_attr "type" "imov")
12778 (set_attr "modrm" "0")
12779 (set_attr "length" "7")
12780 (set_attr "memory" "load")
12781 (set_attr "imm_disp" "false")])
12782
12783 (define_insn "*add_tp_x32"
12784 [(set (match_operand:SI 0 "register_operand" "=r")
12785 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12786 (match_operand:SI 1 "register_operand" "0")))
12787 (clobber (reg:CC FLAGS_REG))]
12788 "TARGET_X32"
12789 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12790 [(set_attr "type" "alu")
12791 (set_attr "modrm" "0")
12792 (set_attr "length" "7")
12793 (set_attr "memory" "load")
12794 (set_attr "imm_disp" "false")])
12795
12796 (define_insn "*add_tp_x32_zext"
12797 [(set (match_operand:DI 0 "register_operand" "=r")
12798 (zero_extend:DI
12799 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12800 (match_operand:SI 1 "register_operand" "0"))))
12801 (clobber (reg:CC FLAGS_REG))]
12802 "TARGET_X32"
12803 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12804 [(set_attr "type" "alu")
12805 (set_attr "modrm" "0")
12806 (set_attr "length" "7")
12807 (set_attr "memory" "load")
12808 (set_attr "imm_disp" "false")])
12809
12810 (define_insn "*add_tp_<mode>"
12811 [(set (match_operand:P 0 "register_operand" "=r")
12812 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12813 (match_operand:P 1 "register_operand" "0")))
12814 (clobber (reg:CC FLAGS_REG))]
12815 "!TARGET_X32"
12816 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12817 [(set_attr "type" "alu")
12818 (set_attr "modrm" "0")
12819 (set_attr "length" "7")
12820 (set_attr "memory" "load")
12821 (set_attr "imm_disp" "false")])
12822
12823 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12824 ;; %rax as destination of the initial executable code sequence.
12825 (define_insn "tls_initial_exec_64_sun"
12826 [(set (match_operand:DI 0 "register_operand" "=a")
12827 (unspec:DI
12828 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12829 UNSPEC_TLS_IE_SUN))
12830 (clobber (reg:CC FLAGS_REG))]
12831 "TARGET_64BIT && TARGET_SUN_TLS"
12832 {
12833 output_asm_insn
12834 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12835 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12836 }
12837 [(set_attr "type" "multi")])
12838
12839 ;; GNU2 TLS patterns can be split.
12840
12841 (define_expand "tls_dynamic_gnu2_32"
12842 [(set (match_dup 3)
12843 (plus:SI (match_operand:SI 2 "register_operand" "")
12844 (const:SI
12845 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12846 UNSPEC_TLSDESC))))
12847 (parallel
12848 [(set (match_operand:SI 0 "register_operand" "")
12849 (unspec:SI [(match_dup 1) (match_dup 3)
12850 (match_dup 2) (reg:SI SP_REG)]
12851 UNSPEC_TLSDESC))
12852 (clobber (reg:CC FLAGS_REG))])]
12853 "!TARGET_64BIT && TARGET_GNU2_TLS"
12854 {
12855 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12856 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12857 })
12858
12859 (define_insn "*tls_dynamic_gnu2_lea_32"
12860 [(set (match_operand:SI 0 "register_operand" "=r")
12861 (plus:SI (match_operand:SI 1 "register_operand" "b")
12862 (const:SI
12863 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12864 UNSPEC_TLSDESC))))]
12865 "!TARGET_64BIT && TARGET_GNU2_TLS"
12866 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12867 [(set_attr "type" "lea")
12868 (set_attr "mode" "SI")
12869 (set_attr "length" "6")
12870 (set_attr "length_address" "4")])
12871
12872 (define_insn "*tls_dynamic_gnu2_call_32"
12873 [(set (match_operand:SI 0 "register_operand" "=a")
12874 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12875 (match_operand:SI 2 "register_operand" "0")
12876 ;; we have to make sure %ebx still points to the GOT
12877 (match_operand:SI 3 "register_operand" "b")
12878 (reg:SI SP_REG)]
12879 UNSPEC_TLSDESC))
12880 (clobber (reg:CC FLAGS_REG))]
12881 "!TARGET_64BIT && TARGET_GNU2_TLS"
12882 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12883 [(set_attr "type" "call")
12884 (set_attr "length" "2")
12885 (set_attr "length_address" "0")])
12886
12887 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12888 [(set (match_operand:SI 0 "register_operand" "=&a")
12889 (plus:SI
12890 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12891 (match_operand:SI 4 "" "")
12892 (match_operand:SI 2 "register_operand" "b")
12893 (reg:SI SP_REG)]
12894 UNSPEC_TLSDESC)
12895 (const:SI (unspec:SI
12896 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12897 UNSPEC_DTPOFF))))
12898 (clobber (reg:CC FLAGS_REG))]
12899 "!TARGET_64BIT && TARGET_GNU2_TLS"
12900 "#"
12901 ""
12902 [(set (match_dup 0) (match_dup 5))]
12903 {
12904 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12905 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12906 })
12907
12908 (define_expand "tls_dynamic_gnu2_64"
12909 [(set (match_dup 2)
12910 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12911 UNSPEC_TLSDESC))
12912 (parallel
12913 [(set (match_operand:DI 0 "register_operand" "")
12914 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12915 UNSPEC_TLSDESC))
12916 (clobber (reg:CC FLAGS_REG))])]
12917 "TARGET_64BIT && TARGET_GNU2_TLS"
12918 {
12919 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12920 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12921 })
12922
12923 (define_insn "*tls_dynamic_gnu2_lea_64"
12924 [(set (match_operand:DI 0 "register_operand" "=r")
12925 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12926 UNSPEC_TLSDESC))]
12927 "TARGET_64BIT && TARGET_GNU2_TLS"
12928 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12929 [(set_attr "type" "lea")
12930 (set_attr "mode" "DI")
12931 (set_attr "length" "7")
12932 (set_attr "length_address" "4")])
12933
12934 (define_insn "*tls_dynamic_gnu2_call_64"
12935 [(set (match_operand:DI 0 "register_operand" "=a")
12936 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12937 (match_operand:DI 2 "register_operand" "0")
12938 (reg:DI SP_REG)]
12939 UNSPEC_TLSDESC))
12940 (clobber (reg:CC FLAGS_REG))]
12941 "TARGET_64BIT && TARGET_GNU2_TLS"
12942 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12943 [(set_attr "type" "call")
12944 (set_attr "length" "2")
12945 (set_attr "length_address" "0")])
12946
12947 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12948 [(set (match_operand:DI 0 "register_operand" "=&a")
12949 (plus:DI
12950 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12951 (match_operand:DI 3 "" "")
12952 (reg:DI SP_REG)]
12953 UNSPEC_TLSDESC)
12954 (const:DI (unspec:DI
12955 [(match_operand 1 "tls_symbolic_operand" "")]
12956 UNSPEC_DTPOFF))))
12957 (clobber (reg:CC FLAGS_REG))]
12958 "TARGET_64BIT && TARGET_GNU2_TLS"
12959 "#"
12960 ""
12961 [(set (match_dup 0) (match_dup 4))]
12962 {
12963 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12964 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12965 })
12966 \f
12967 ;; These patterns match the binary 387 instructions for addM3, subM3,
12968 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12969 ;; SFmode. The first is the normal insn, the second the same insn but
12970 ;; with one operand a conversion, and the third the same insn but with
12971 ;; the other operand a conversion. The conversion may be SFmode or
12972 ;; SImode if the target mode DFmode, but only SImode if the target mode
12973 ;; is SFmode.
12974
12975 ;; Gcc is slightly more smart about handling normal two address instructions
12976 ;; so use special patterns for add and mull.
12977
12978 (define_insn "*fop_<mode>_comm_mixed"
12979 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12980 (match_operator:MODEF 3 "binary_fp_operator"
12981 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12982 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12983 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12984 && COMMUTATIVE_ARITH_P (operands[3])
12985 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12986 "* return output_387_binary_op (insn, operands);"
12987 [(set (attr "type")
12988 (if_then_else (eq_attr "alternative" "1,2")
12989 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12990 (const_string "ssemul")
12991 (const_string "sseadd"))
12992 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12993 (const_string "fmul")
12994 (const_string "fop"))))
12995 (set_attr "isa" "*,noavx,avx")
12996 (set_attr "prefix" "orig,orig,vex")
12997 (set_attr "mode" "<MODE>")])
12998
12999 (define_insn "*fop_<mode>_comm_sse"
13000 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13001 (match_operator:MODEF 3 "binary_fp_operator"
13002 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13003 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13004 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13005 && COMMUTATIVE_ARITH_P (operands[3])
13006 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13007 "* return output_387_binary_op (insn, operands);"
13008 [(set (attr "type")
13009 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13010 (const_string "ssemul")
13011 (const_string "sseadd")))
13012 (set_attr "isa" "noavx,avx")
13013 (set_attr "prefix" "orig,vex")
13014 (set_attr "mode" "<MODE>")])
13015
13016 (define_insn "*fop_<mode>_comm_i387"
13017 [(set (match_operand:MODEF 0 "register_operand" "=f")
13018 (match_operator:MODEF 3 "binary_fp_operator"
13019 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13020 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13021 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13022 && COMMUTATIVE_ARITH_P (operands[3])
13023 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13024 "* return output_387_binary_op (insn, operands);"
13025 [(set (attr "type")
13026 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13027 (const_string "fmul")
13028 (const_string "fop")))
13029 (set_attr "mode" "<MODE>")])
13030
13031 (define_insn "*fop_<mode>_1_mixed"
13032 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13033 (match_operator:MODEF 3 "binary_fp_operator"
13034 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13035 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13036 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13037 && !COMMUTATIVE_ARITH_P (operands[3])
13038 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13039 "* return output_387_binary_op (insn, operands);"
13040 [(set (attr "type")
13041 (cond [(and (eq_attr "alternative" "2,3")
13042 (match_operand:MODEF 3 "mult_operator" ""))
13043 (const_string "ssemul")
13044 (and (eq_attr "alternative" "2,3")
13045 (match_operand:MODEF 3 "div_operator" ""))
13046 (const_string "ssediv")
13047 (eq_attr "alternative" "2,3")
13048 (const_string "sseadd")
13049 (match_operand:MODEF 3 "mult_operator" "")
13050 (const_string "fmul")
13051 (match_operand:MODEF 3 "div_operator" "")
13052 (const_string "fdiv")
13053 ]
13054 (const_string "fop")))
13055 (set_attr "isa" "*,*,noavx,avx")
13056 (set_attr "prefix" "orig,orig,orig,vex")
13057 (set_attr "mode" "<MODE>")])
13058
13059 (define_insn "*rcpsf2_sse"
13060 [(set (match_operand:SF 0 "register_operand" "=x")
13061 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13062 UNSPEC_RCP))]
13063 "TARGET_SSE_MATH"
13064 "%vrcpss\t{%1, %d0|%d0, %1}"
13065 [(set_attr "type" "sse")
13066 (set_attr "atom_sse_attr" "rcp")
13067 (set_attr "prefix" "maybe_vex")
13068 (set_attr "mode" "SF")])
13069
13070 (define_insn "*fop_<mode>_1_sse"
13071 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13072 (match_operator:MODEF 3 "binary_fp_operator"
13073 [(match_operand:MODEF 1 "register_operand" "0,x")
13074 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13075 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13076 && !COMMUTATIVE_ARITH_P (operands[3])"
13077 "* return output_387_binary_op (insn, operands);"
13078 [(set (attr "type")
13079 (cond [(match_operand:MODEF 3 "mult_operator" "")
13080 (const_string "ssemul")
13081 (match_operand:MODEF 3 "div_operator" "")
13082 (const_string "ssediv")
13083 ]
13084 (const_string "sseadd")))
13085 (set_attr "isa" "noavx,avx")
13086 (set_attr "prefix" "orig,vex")
13087 (set_attr "mode" "<MODE>")])
13088
13089 ;; This pattern is not fully shadowed by the pattern above.
13090 (define_insn "*fop_<mode>_1_i387"
13091 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13092 (match_operator:MODEF 3 "binary_fp_operator"
13093 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13094 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13095 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13096 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13097 && !COMMUTATIVE_ARITH_P (operands[3])
13098 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13099 "* return output_387_binary_op (insn, operands);"
13100 [(set (attr "type")
13101 (cond [(match_operand:MODEF 3 "mult_operator" "")
13102 (const_string "fmul")
13103 (match_operand:MODEF 3 "div_operator" "")
13104 (const_string "fdiv")
13105 ]
13106 (const_string "fop")))
13107 (set_attr "mode" "<MODE>")])
13108
13109 ;; ??? Add SSE splitters for these!
13110 (define_insn "*fop_<MODEF:mode>_2_i387"
13111 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13112 (match_operator:MODEF 3 "binary_fp_operator"
13113 [(float:MODEF
13114 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13115 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13116 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13117 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13118 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13119 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13120 [(set (attr "type")
13121 (cond [(match_operand:MODEF 3 "mult_operator" "")
13122 (const_string "fmul")
13123 (match_operand:MODEF 3 "div_operator" "")
13124 (const_string "fdiv")
13125 ]
13126 (const_string "fop")))
13127 (set_attr "fp_int_src" "true")
13128 (set_attr "mode" "<SWI24:MODE>")])
13129
13130 (define_insn "*fop_<MODEF:mode>_3_i387"
13131 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13132 (match_operator:MODEF 3 "binary_fp_operator"
13133 [(match_operand:MODEF 1 "register_operand" "0,0")
13134 (float:MODEF
13135 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13136 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13137 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13138 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13139 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13140 [(set (attr "type")
13141 (cond [(match_operand:MODEF 3 "mult_operator" "")
13142 (const_string "fmul")
13143 (match_operand:MODEF 3 "div_operator" "")
13144 (const_string "fdiv")
13145 ]
13146 (const_string "fop")))
13147 (set_attr "fp_int_src" "true")
13148 (set_attr "mode" "<MODE>")])
13149
13150 (define_insn "*fop_df_4_i387"
13151 [(set (match_operand:DF 0 "register_operand" "=f,f")
13152 (match_operator:DF 3 "binary_fp_operator"
13153 [(float_extend:DF
13154 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13155 (match_operand:DF 2 "register_operand" "0,f")]))]
13156 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13157 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13158 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13159 "* return output_387_binary_op (insn, operands);"
13160 [(set (attr "type")
13161 (cond [(match_operand:DF 3 "mult_operator" "")
13162 (const_string "fmul")
13163 (match_operand:DF 3 "div_operator" "")
13164 (const_string "fdiv")
13165 ]
13166 (const_string "fop")))
13167 (set_attr "mode" "SF")])
13168
13169 (define_insn "*fop_df_5_i387"
13170 [(set (match_operand:DF 0 "register_operand" "=f,f")
13171 (match_operator:DF 3 "binary_fp_operator"
13172 [(match_operand:DF 1 "register_operand" "0,f")
13173 (float_extend:DF
13174 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13175 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13176 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13177 "* return output_387_binary_op (insn, operands);"
13178 [(set (attr "type")
13179 (cond [(match_operand:DF 3 "mult_operator" "")
13180 (const_string "fmul")
13181 (match_operand:DF 3 "div_operator" "")
13182 (const_string "fdiv")
13183 ]
13184 (const_string "fop")))
13185 (set_attr "mode" "SF")])
13186
13187 (define_insn "*fop_df_6_i387"
13188 [(set (match_operand:DF 0 "register_operand" "=f,f")
13189 (match_operator:DF 3 "binary_fp_operator"
13190 [(float_extend:DF
13191 (match_operand:SF 1 "register_operand" "0,f"))
13192 (float_extend:DF
13193 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13194 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13195 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13196 "* return output_387_binary_op (insn, operands);"
13197 [(set (attr "type")
13198 (cond [(match_operand:DF 3 "mult_operator" "")
13199 (const_string "fmul")
13200 (match_operand:DF 3 "div_operator" "")
13201 (const_string "fdiv")
13202 ]
13203 (const_string "fop")))
13204 (set_attr "mode" "SF")])
13205
13206 (define_insn "*fop_xf_comm_i387"
13207 [(set (match_operand:XF 0 "register_operand" "=f")
13208 (match_operator:XF 3 "binary_fp_operator"
13209 [(match_operand:XF 1 "register_operand" "%0")
13210 (match_operand:XF 2 "register_operand" "f")]))]
13211 "TARGET_80387
13212 && COMMUTATIVE_ARITH_P (operands[3])"
13213 "* return output_387_binary_op (insn, operands);"
13214 [(set (attr "type")
13215 (if_then_else (match_operand:XF 3 "mult_operator" "")
13216 (const_string "fmul")
13217 (const_string "fop")))
13218 (set_attr "mode" "XF")])
13219
13220 (define_insn "*fop_xf_1_i387"
13221 [(set (match_operand:XF 0 "register_operand" "=f,f")
13222 (match_operator:XF 3 "binary_fp_operator"
13223 [(match_operand:XF 1 "register_operand" "0,f")
13224 (match_operand:XF 2 "register_operand" "f,0")]))]
13225 "TARGET_80387
13226 && !COMMUTATIVE_ARITH_P (operands[3])"
13227 "* return output_387_binary_op (insn, operands);"
13228 [(set (attr "type")
13229 (cond [(match_operand:XF 3 "mult_operator" "")
13230 (const_string "fmul")
13231 (match_operand:XF 3 "div_operator" "")
13232 (const_string "fdiv")
13233 ]
13234 (const_string "fop")))
13235 (set_attr "mode" "XF")])
13236
13237 (define_insn "*fop_xf_2_i387"
13238 [(set (match_operand:XF 0 "register_operand" "=f,f")
13239 (match_operator:XF 3 "binary_fp_operator"
13240 [(float:XF
13241 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13242 (match_operand:XF 2 "register_operand" "0,0")]))]
13243 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13244 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13245 [(set (attr "type")
13246 (cond [(match_operand:XF 3 "mult_operator" "")
13247 (const_string "fmul")
13248 (match_operand:XF 3 "div_operator" "")
13249 (const_string "fdiv")
13250 ]
13251 (const_string "fop")))
13252 (set_attr "fp_int_src" "true")
13253 (set_attr "mode" "<MODE>")])
13254
13255 (define_insn "*fop_xf_3_i387"
13256 [(set (match_operand:XF 0 "register_operand" "=f,f")
13257 (match_operator:XF 3 "binary_fp_operator"
13258 [(match_operand:XF 1 "register_operand" "0,0")
13259 (float:XF
13260 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13261 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13262 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13263 [(set (attr "type")
13264 (cond [(match_operand:XF 3 "mult_operator" "")
13265 (const_string "fmul")
13266 (match_operand:XF 3 "div_operator" "")
13267 (const_string "fdiv")
13268 ]
13269 (const_string "fop")))
13270 (set_attr "fp_int_src" "true")
13271 (set_attr "mode" "<MODE>")])
13272
13273 (define_insn "*fop_xf_4_i387"
13274 [(set (match_operand:XF 0 "register_operand" "=f,f")
13275 (match_operator:XF 3 "binary_fp_operator"
13276 [(float_extend:XF
13277 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13278 (match_operand:XF 2 "register_operand" "0,f")]))]
13279 "TARGET_80387"
13280 "* return output_387_binary_op (insn, operands);"
13281 [(set (attr "type")
13282 (cond [(match_operand:XF 3 "mult_operator" "")
13283 (const_string "fmul")
13284 (match_operand:XF 3 "div_operator" "")
13285 (const_string "fdiv")
13286 ]
13287 (const_string "fop")))
13288 (set_attr "mode" "<MODE>")])
13289
13290 (define_insn "*fop_xf_5_i387"
13291 [(set (match_operand:XF 0 "register_operand" "=f,f")
13292 (match_operator:XF 3 "binary_fp_operator"
13293 [(match_operand:XF 1 "register_operand" "0,f")
13294 (float_extend:XF
13295 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13296 "TARGET_80387"
13297 "* return output_387_binary_op (insn, operands);"
13298 [(set (attr "type")
13299 (cond [(match_operand:XF 3 "mult_operator" "")
13300 (const_string "fmul")
13301 (match_operand:XF 3 "div_operator" "")
13302 (const_string "fdiv")
13303 ]
13304 (const_string "fop")))
13305 (set_attr "mode" "<MODE>")])
13306
13307 (define_insn "*fop_xf_6_i387"
13308 [(set (match_operand:XF 0 "register_operand" "=f,f")
13309 (match_operator:XF 3 "binary_fp_operator"
13310 [(float_extend:XF
13311 (match_operand:MODEF 1 "register_operand" "0,f"))
13312 (float_extend:XF
13313 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13314 "TARGET_80387"
13315 "* return output_387_binary_op (insn, operands);"
13316 [(set (attr "type")
13317 (cond [(match_operand:XF 3 "mult_operator" "")
13318 (const_string "fmul")
13319 (match_operand:XF 3 "div_operator" "")
13320 (const_string "fdiv")
13321 ]
13322 (const_string "fop")))
13323 (set_attr "mode" "<MODE>")])
13324
13325 (define_split
13326 [(set (match_operand 0 "register_operand" "")
13327 (match_operator 3 "binary_fp_operator"
13328 [(float (match_operand:SWI24 1 "register_operand" ""))
13329 (match_operand 2 "register_operand" "")]))]
13330 "reload_completed
13331 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13332 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13333 [(const_int 0)]
13334 {
13335 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13336 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13337 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13338 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13339 GET_MODE (operands[3]),
13340 operands[4],
13341 operands[2])));
13342 ix86_free_from_memory (GET_MODE (operands[1]));
13343 DONE;
13344 })
13345
13346 (define_split
13347 [(set (match_operand 0 "register_operand" "")
13348 (match_operator 3 "binary_fp_operator"
13349 [(match_operand 1 "register_operand" "")
13350 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13351 "reload_completed
13352 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13353 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13354 [(const_int 0)]
13355 {
13356 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13357 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13358 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13359 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13360 GET_MODE (operands[3]),
13361 operands[1],
13362 operands[4])));
13363 ix86_free_from_memory (GET_MODE (operands[2]));
13364 DONE;
13365 })
13366 \f
13367 ;; FPU special functions.
13368
13369 ;; This pattern implements a no-op XFmode truncation for
13370 ;; all fancy i386 XFmode math functions.
13371
13372 (define_insn "truncxf<mode>2_i387_noop_unspec"
13373 [(set (match_operand:MODEF 0 "register_operand" "=f")
13374 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13375 UNSPEC_TRUNC_NOOP))]
13376 "TARGET_USE_FANCY_MATH_387"
13377 "* return output_387_reg_move (insn, operands);"
13378 [(set_attr "type" "fmov")
13379 (set_attr "mode" "<MODE>")])
13380
13381 (define_insn "sqrtxf2"
13382 [(set (match_operand:XF 0 "register_operand" "=f")
13383 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13384 "TARGET_USE_FANCY_MATH_387"
13385 "fsqrt"
13386 [(set_attr "type" "fpspc")
13387 (set_attr "mode" "XF")
13388 (set_attr "athlon_decode" "direct")
13389 (set_attr "amdfam10_decode" "direct")
13390 (set_attr "bdver1_decode" "direct")])
13391
13392 (define_insn "sqrt_extend<mode>xf2_i387"
13393 [(set (match_operand:XF 0 "register_operand" "=f")
13394 (sqrt:XF
13395 (float_extend:XF
13396 (match_operand:MODEF 1 "register_operand" "0"))))]
13397 "TARGET_USE_FANCY_MATH_387"
13398 "fsqrt"
13399 [(set_attr "type" "fpspc")
13400 (set_attr "mode" "XF")
13401 (set_attr "athlon_decode" "direct")
13402 (set_attr "amdfam10_decode" "direct")
13403 (set_attr "bdver1_decode" "direct")])
13404
13405 (define_insn "*rsqrtsf2_sse"
13406 [(set (match_operand:SF 0 "register_operand" "=x")
13407 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13408 UNSPEC_RSQRT))]
13409 "TARGET_SSE_MATH"
13410 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13411 [(set_attr "type" "sse")
13412 (set_attr "atom_sse_attr" "rcp")
13413 (set_attr "prefix" "maybe_vex")
13414 (set_attr "mode" "SF")])
13415
13416 (define_expand "rsqrtsf2"
13417 [(set (match_operand:SF 0 "register_operand" "")
13418 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13419 UNSPEC_RSQRT))]
13420 "TARGET_SSE_MATH"
13421 {
13422 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13423 DONE;
13424 })
13425
13426 (define_insn "*sqrt<mode>2_sse"
13427 [(set (match_operand:MODEF 0 "register_operand" "=x")
13428 (sqrt:MODEF
13429 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13430 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13431 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13432 [(set_attr "type" "sse")
13433 (set_attr "atom_sse_attr" "sqrt")
13434 (set_attr "prefix" "maybe_vex")
13435 (set_attr "mode" "<MODE>")
13436 (set_attr "athlon_decode" "*")
13437 (set_attr "amdfam10_decode" "*")
13438 (set_attr "bdver1_decode" "*")])
13439
13440 (define_expand "sqrt<mode>2"
13441 [(set (match_operand:MODEF 0 "register_operand" "")
13442 (sqrt:MODEF
13443 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13444 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13445 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13446 {
13447 if (<MODE>mode == SFmode
13448 && TARGET_SSE_MATH
13449 && TARGET_RECIP_SQRT
13450 && !optimize_function_for_size_p (cfun)
13451 && flag_finite_math_only && !flag_trapping_math
13452 && flag_unsafe_math_optimizations)
13453 {
13454 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13455 DONE;
13456 }
13457
13458 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13459 {
13460 rtx op0 = gen_reg_rtx (XFmode);
13461 rtx op1 = force_reg (<MODE>mode, operands[1]);
13462
13463 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13464 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13465 DONE;
13466 }
13467 })
13468
13469 (define_insn "fpremxf4_i387"
13470 [(set (match_operand:XF 0 "register_operand" "=f")
13471 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13472 (match_operand:XF 3 "register_operand" "1")]
13473 UNSPEC_FPREM_F))
13474 (set (match_operand:XF 1 "register_operand" "=u")
13475 (unspec:XF [(match_dup 2) (match_dup 3)]
13476 UNSPEC_FPREM_U))
13477 (set (reg:CCFP FPSR_REG)
13478 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13479 UNSPEC_C2_FLAG))]
13480 "TARGET_USE_FANCY_MATH_387"
13481 "fprem"
13482 [(set_attr "type" "fpspc")
13483 (set_attr "mode" "XF")])
13484
13485 (define_expand "fmodxf3"
13486 [(use (match_operand:XF 0 "register_operand" ""))
13487 (use (match_operand:XF 1 "general_operand" ""))
13488 (use (match_operand:XF 2 "general_operand" ""))]
13489 "TARGET_USE_FANCY_MATH_387"
13490 {
13491 rtx label = gen_label_rtx ();
13492
13493 rtx op1 = gen_reg_rtx (XFmode);
13494 rtx op2 = gen_reg_rtx (XFmode);
13495
13496 emit_move_insn (op2, operands[2]);
13497 emit_move_insn (op1, operands[1]);
13498
13499 emit_label (label);
13500 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13501 ix86_emit_fp_unordered_jump (label);
13502 LABEL_NUSES (label) = 1;
13503
13504 emit_move_insn (operands[0], op1);
13505 DONE;
13506 })
13507
13508 (define_expand "fmod<mode>3"
13509 [(use (match_operand:MODEF 0 "register_operand" ""))
13510 (use (match_operand:MODEF 1 "general_operand" ""))
13511 (use (match_operand:MODEF 2 "general_operand" ""))]
13512 "TARGET_USE_FANCY_MATH_387"
13513 {
13514 rtx (*gen_truncxf) (rtx, rtx);
13515
13516 rtx label = gen_label_rtx ();
13517
13518 rtx op1 = gen_reg_rtx (XFmode);
13519 rtx op2 = gen_reg_rtx (XFmode);
13520
13521 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13522 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13523
13524 emit_label (label);
13525 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13526 ix86_emit_fp_unordered_jump (label);
13527 LABEL_NUSES (label) = 1;
13528
13529 /* Truncate the result properly for strict SSE math. */
13530 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13531 && !TARGET_MIX_SSE_I387)
13532 gen_truncxf = gen_truncxf<mode>2;
13533 else
13534 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13535
13536 emit_insn (gen_truncxf (operands[0], op1));
13537 DONE;
13538 })
13539
13540 (define_insn "fprem1xf4_i387"
13541 [(set (match_operand:XF 0 "register_operand" "=f")
13542 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13543 (match_operand:XF 3 "register_operand" "1")]
13544 UNSPEC_FPREM1_F))
13545 (set (match_operand:XF 1 "register_operand" "=u")
13546 (unspec:XF [(match_dup 2) (match_dup 3)]
13547 UNSPEC_FPREM1_U))
13548 (set (reg:CCFP FPSR_REG)
13549 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13550 UNSPEC_C2_FLAG))]
13551 "TARGET_USE_FANCY_MATH_387"
13552 "fprem1"
13553 [(set_attr "type" "fpspc")
13554 (set_attr "mode" "XF")])
13555
13556 (define_expand "remainderxf3"
13557 [(use (match_operand:XF 0 "register_operand" ""))
13558 (use (match_operand:XF 1 "general_operand" ""))
13559 (use (match_operand:XF 2 "general_operand" ""))]
13560 "TARGET_USE_FANCY_MATH_387"
13561 {
13562 rtx label = gen_label_rtx ();
13563
13564 rtx op1 = gen_reg_rtx (XFmode);
13565 rtx op2 = gen_reg_rtx (XFmode);
13566
13567 emit_move_insn (op2, operands[2]);
13568 emit_move_insn (op1, operands[1]);
13569
13570 emit_label (label);
13571 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13572 ix86_emit_fp_unordered_jump (label);
13573 LABEL_NUSES (label) = 1;
13574
13575 emit_move_insn (operands[0], op1);
13576 DONE;
13577 })
13578
13579 (define_expand "remainder<mode>3"
13580 [(use (match_operand:MODEF 0 "register_operand" ""))
13581 (use (match_operand:MODEF 1 "general_operand" ""))
13582 (use (match_operand:MODEF 2 "general_operand" ""))]
13583 "TARGET_USE_FANCY_MATH_387"
13584 {
13585 rtx (*gen_truncxf) (rtx, rtx);
13586
13587 rtx label = gen_label_rtx ();
13588
13589 rtx op1 = gen_reg_rtx (XFmode);
13590 rtx op2 = gen_reg_rtx (XFmode);
13591
13592 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13593 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13594
13595 emit_label (label);
13596
13597 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13598 ix86_emit_fp_unordered_jump (label);
13599 LABEL_NUSES (label) = 1;
13600
13601 /* Truncate the result properly for strict SSE math. */
13602 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13603 && !TARGET_MIX_SSE_I387)
13604 gen_truncxf = gen_truncxf<mode>2;
13605 else
13606 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13607
13608 emit_insn (gen_truncxf (operands[0], op1));
13609 DONE;
13610 })
13611
13612 (define_insn "*sinxf2_i387"
13613 [(set (match_operand:XF 0 "register_operand" "=f")
13614 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13615 "TARGET_USE_FANCY_MATH_387
13616 && flag_unsafe_math_optimizations"
13617 "fsin"
13618 [(set_attr "type" "fpspc")
13619 (set_attr "mode" "XF")])
13620
13621 (define_insn "*sin_extend<mode>xf2_i387"
13622 [(set (match_operand:XF 0 "register_operand" "=f")
13623 (unspec:XF [(float_extend:XF
13624 (match_operand:MODEF 1 "register_operand" "0"))]
13625 UNSPEC_SIN))]
13626 "TARGET_USE_FANCY_MATH_387
13627 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13628 || TARGET_MIX_SSE_I387)
13629 && flag_unsafe_math_optimizations"
13630 "fsin"
13631 [(set_attr "type" "fpspc")
13632 (set_attr "mode" "XF")])
13633
13634 (define_insn "*cosxf2_i387"
13635 [(set (match_operand:XF 0 "register_operand" "=f")
13636 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13637 "TARGET_USE_FANCY_MATH_387
13638 && flag_unsafe_math_optimizations"
13639 "fcos"
13640 [(set_attr "type" "fpspc")
13641 (set_attr "mode" "XF")])
13642
13643 (define_insn "*cos_extend<mode>xf2_i387"
13644 [(set (match_operand:XF 0 "register_operand" "=f")
13645 (unspec:XF [(float_extend:XF
13646 (match_operand:MODEF 1 "register_operand" "0"))]
13647 UNSPEC_COS))]
13648 "TARGET_USE_FANCY_MATH_387
13649 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13650 || TARGET_MIX_SSE_I387)
13651 && flag_unsafe_math_optimizations"
13652 "fcos"
13653 [(set_attr "type" "fpspc")
13654 (set_attr "mode" "XF")])
13655
13656 ;; When sincos pattern is defined, sin and cos builtin functions will be
13657 ;; expanded to sincos pattern with one of its outputs left unused.
13658 ;; CSE pass will figure out if two sincos patterns can be combined,
13659 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13660 ;; depending on the unused output.
13661
13662 (define_insn "sincosxf3"
13663 [(set (match_operand:XF 0 "register_operand" "=f")
13664 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13665 UNSPEC_SINCOS_COS))
13666 (set (match_operand:XF 1 "register_operand" "=u")
13667 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13668 "TARGET_USE_FANCY_MATH_387
13669 && flag_unsafe_math_optimizations"
13670 "fsincos"
13671 [(set_attr "type" "fpspc")
13672 (set_attr "mode" "XF")])
13673
13674 (define_split
13675 [(set (match_operand:XF 0 "register_operand" "")
13676 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13677 UNSPEC_SINCOS_COS))
13678 (set (match_operand:XF 1 "register_operand" "")
13679 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13680 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13681 && can_create_pseudo_p ()"
13682 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13683
13684 (define_split
13685 [(set (match_operand:XF 0 "register_operand" "")
13686 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13687 UNSPEC_SINCOS_COS))
13688 (set (match_operand:XF 1 "register_operand" "")
13689 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13690 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13691 && can_create_pseudo_p ()"
13692 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13693
13694 (define_insn "sincos_extend<mode>xf3_i387"
13695 [(set (match_operand:XF 0 "register_operand" "=f")
13696 (unspec:XF [(float_extend:XF
13697 (match_operand:MODEF 2 "register_operand" "0"))]
13698 UNSPEC_SINCOS_COS))
13699 (set (match_operand:XF 1 "register_operand" "=u")
13700 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13701 "TARGET_USE_FANCY_MATH_387
13702 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13703 || TARGET_MIX_SSE_I387)
13704 && flag_unsafe_math_optimizations"
13705 "fsincos"
13706 [(set_attr "type" "fpspc")
13707 (set_attr "mode" "XF")])
13708
13709 (define_split
13710 [(set (match_operand:XF 0 "register_operand" "")
13711 (unspec:XF [(float_extend:XF
13712 (match_operand:MODEF 2 "register_operand" ""))]
13713 UNSPEC_SINCOS_COS))
13714 (set (match_operand:XF 1 "register_operand" "")
13715 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13716 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13717 && can_create_pseudo_p ()"
13718 [(set (match_dup 1)
13719 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13720
13721 (define_split
13722 [(set (match_operand:XF 0 "register_operand" "")
13723 (unspec:XF [(float_extend:XF
13724 (match_operand:MODEF 2 "register_operand" ""))]
13725 UNSPEC_SINCOS_COS))
13726 (set (match_operand:XF 1 "register_operand" "")
13727 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13728 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13729 && can_create_pseudo_p ()"
13730 [(set (match_dup 0)
13731 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13732
13733 (define_expand "sincos<mode>3"
13734 [(use (match_operand:MODEF 0 "register_operand" ""))
13735 (use (match_operand:MODEF 1 "register_operand" ""))
13736 (use (match_operand:MODEF 2 "register_operand" ""))]
13737 "TARGET_USE_FANCY_MATH_387
13738 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13739 || TARGET_MIX_SSE_I387)
13740 && flag_unsafe_math_optimizations"
13741 {
13742 rtx op0 = gen_reg_rtx (XFmode);
13743 rtx op1 = gen_reg_rtx (XFmode);
13744
13745 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13746 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13747 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13748 DONE;
13749 })
13750
13751 (define_insn "fptanxf4_i387"
13752 [(set (match_operand:XF 0 "register_operand" "=f")
13753 (match_operand:XF 3 "const_double_operand" "F"))
13754 (set (match_operand:XF 1 "register_operand" "=u")
13755 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13756 UNSPEC_TAN))]
13757 "TARGET_USE_FANCY_MATH_387
13758 && flag_unsafe_math_optimizations
13759 && standard_80387_constant_p (operands[3]) == 2"
13760 "fptan"
13761 [(set_attr "type" "fpspc")
13762 (set_attr "mode" "XF")])
13763
13764 (define_insn "fptan_extend<mode>xf4_i387"
13765 [(set (match_operand:MODEF 0 "register_operand" "=f")
13766 (match_operand:MODEF 3 "const_double_operand" "F"))
13767 (set (match_operand:XF 1 "register_operand" "=u")
13768 (unspec:XF [(float_extend:XF
13769 (match_operand:MODEF 2 "register_operand" "0"))]
13770 UNSPEC_TAN))]
13771 "TARGET_USE_FANCY_MATH_387
13772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13773 || TARGET_MIX_SSE_I387)
13774 && flag_unsafe_math_optimizations
13775 && standard_80387_constant_p (operands[3]) == 2"
13776 "fptan"
13777 [(set_attr "type" "fpspc")
13778 (set_attr "mode" "XF")])
13779
13780 (define_expand "tanxf2"
13781 [(use (match_operand:XF 0 "register_operand" ""))
13782 (use (match_operand:XF 1 "register_operand" ""))]
13783 "TARGET_USE_FANCY_MATH_387
13784 && flag_unsafe_math_optimizations"
13785 {
13786 rtx one = gen_reg_rtx (XFmode);
13787 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13788
13789 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13790 DONE;
13791 })
13792
13793 (define_expand "tan<mode>2"
13794 [(use (match_operand:MODEF 0 "register_operand" ""))
13795 (use (match_operand:MODEF 1 "register_operand" ""))]
13796 "TARGET_USE_FANCY_MATH_387
13797 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13798 || TARGET_MIX_SSE_I387)
13799 && flag_unsafe_math_optimizations"
13800 {
13801 rtx op0 = gen_reg_rtx (XFmode);
13802
13803 rtx one = gen_reg_rtx (<MODE>mode);
13804 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13805
13806 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13807 operands[1], op2));
13808 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13809 DONE;
13810 })
13811
13812 (define_insn "*fpatanxf3_i387"
13813 [(set (match_operand:XF 0 "register_operand" "=f")
13814 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13815 (match_operand:XF 2 "register_operand" "u")]
13816 UNSPEC_FPATAN))
13817 (clobber (match_scratch:XF 3 "=2"))]
13818 "TARGET_USE_FANCY_MATH_387
13819 && flag_unsafe_math_optimizations"
13820 "fpatan"
13821 [(set_attr "type" "fpspc")
13822 (set_attr "mode" "XF")])
13823
13824 (define_insn "fpatan_extend<mode>xf3_i387"
13825 [(set (match_operand:XF 0 "register_operand" "=f")
13826 (unspec:XF [(float_extend:XF
13827 (match_operand:MODEF 1 "register_operand" "0"))
13828 (float_extend:XF
13829 (match_operand:MODEF 2 "register_operand" "u"))]
13830 UNSPEC_FPATAN))
13831 (clobber (match_scratch:XF 3 "=2"))]
13832 "TARGET_USE_FANCY_MATH_387
13833 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13834 || TARGET_MIX_SSE_I387)
13835 && flag_unsafe_math_optimizations"
13836 "fpatan"
13837 [(set_attr "type" "fpspc")
13838 (set_attr "mode" "XF")])
13839
13840 (define_expand "atan2xf3"
13841 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13842 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13843 (match_operand:XF 1 "register_operand" "")]
13844 UNSPEC_FPATAN))
13845 (clobber (match_scratch:XF 3 ""))])]
13846 "TARGET_USE_FANCY_MATH_387
13847 && flag_unsafe_math_optimizations")
13848
13849 (define_expand "atan2<mode>3"
13850 [(use (match_operand:MODEF 0 "register_operand" ""))
13851 (use (match_operand:MODEF 1 "register_operand" ""))
13852 (use (match_operand:MODEF 2 "register_operand" ""))]
13853 "TARGET_USE_FANCY_MATH_387
13854 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13855 || TARGET_MIX_SSE_I387)
13856 && flag_unsafe_math_optimizations"
13857 {
13858 rtx op0 = gen_reg_rtx (XFmode);
13859
13860 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13861 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13862 DONE;
13863 })
13864
13865 (define_expand "atanxf2"
13866 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13867 (unspec:XF [(match_dup 2)
13868 (match_operand:XF 1 "register_operand" "")]
13869 UNSPEC_FPATAN))
13870 (clobber (match_scratch:XF 3 ""))])]
13871 "TARGET_USE_FANCY_MATH_387
13872 && flag_unsafe_math_optimizations"
13873 {
13874 operands[2] = gen_reg_rtx (XFmode);
13875 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13876 })
13877
13878 (define_expand "atan<mode>2"
13879 [(use (match_operand:MODEF 0 "register_operand" ""))
13880 (use (match_operand:MODEF 1 "register_operand" ""))]
13881 "TARGET_USE_FANCY_MATH_387
13882 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13883 || TARGET_MIX_SSE_I387)
13884 && flag_unsafe_math_optimizations"
13885 {
13886 rtx op0 = gen_reg_rtx (XFmode);
13887
13888 rtx op2 = gen_reg_rtx (<MODE>mode);
13889 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13890
13891 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13892 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13893 DONE;
13894 })
13895
13896 (define_expand "asinxf2"
13897 [(set (match_dup 2)
13898 (mult:XF (match_operand:XF 1 "register_operand" "")
13899 (match_dup 1)))
13900 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13901 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13902 (parallel [(set (match_operand:XF 0 "register_operand" "")
13903 (unspec:XF [(match_dup 5) (match_dup 1)]
13904 UNSPEC_FPATAN))
13905 (clobber (match_scratch:XF 6 ""))])]
13906 "TARGET_USE_FANCY_MATH_387
13907 && flag_unsafe_math_optimizations"
13908 {
13909 int i;
13910
13911 if (optimize_insn_for_size_p ())
13912 FAIL;
13913
13914 for (i = 2; i < 6; i++)
13915 operands[i] = gen_reg_rtx (XFmode);
13916
13917 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13918 })
13919
13920 (define_expand "asin<mode>2"
13921 [(use (match_operand:MODEF 0 "register_operand" ""))
13922 (use (match_operand:MODEF 1 "general_operand" ""))]
13923 "TARGET_USE_FANCY_MATH_387
13924 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13925 || TARGET_MIX_SSE_I387)
13926 && flag_unsafe_math_optimizations"
13927 {
13928 rtx op0 = gen_reg_rtx (XFmode);
13929 rtx op1 = gen_reg_rtx (XFmode);
13930
13931 if (optimize_insn_for_size_p ())
13932 FAIL;
13933
13934 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13935 emit_insn (gen_asinxf2 (op0, op1));
13936 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13937 DONE;
13938 })
13939
13940 (define_expand "acosxf2"
13941 [(set (match_dup 2)
13942 (mult:XF (match_operand:XF 1 "register_operand" "")
13943 (match_dup 1)))
13944 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13945 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13946 (parallel [(set (match_operand:XF 0 "register_operand" "")
13947 (unspec:XF [(match_dup 1) (match_dup 5)]
13948 UNSPEC_FPATAN))
13949 (clobber (match_scratch:XF 6 ""))])]
13950 "TARGET_USE_FANCY_MATH_387
13951 && flag_unsafe_math_optimizations"
13952 {
13953 int i;
13954
13955 if (optimize_insn_for_size_p ())
13956 FAIL;
13957
13958 for (i = 2; i < 6; i++)
13959 operands[i] = gen_reg_rtx (XFmode);
13960
13961 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13962 })
13963
13964 (define_expand "acos<mode>2"
13965 [(use (match_operand:MODEF 0 "register_operand" ""))
13966 (use (match_operand:MODEF 1 "general_operand" ""))]
13967 "TARGET_USE_FANCY_MATH_387
13968 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13969 || TARGET_MIX_SSE_I387)
13970 && flag_unsafe_math_optimizations"
13971 {
13972 rtx op0 = gen_reg_rtx (XFmode);
13973 rtx op1 = gen_reg_rtx (XFmode);
13974
13975 if (optimize_insn_for_size_p ())
13976 FAIL;
13977
13978 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13979 emit_insn (gen_acosxf2 (op0, op1));
13980 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13981 DONE;
13982 })
13983
13984 (define_insn "fyl2xxf3_i387"
13985 [(set (match_operand:XF 0 "register_operand" "=f")
13986 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13987 (match_operand:XF 2 "register_operand" "u")]
13988 UNSPEC_FYL2X))
13989 (clobber (match_scratch:XF 3 "=2"))]
13990 "TARGET_USE_FANCY_MATH_387
13991 && flag_unsafe_math_optimizations"
13992 "fyl2x"
13993 [(set_attr "type" "fpspc")
13994 (set_attr "mode" "XF")])
13995
13996 (define_insn "fyl2x_extend<mode>xf3_i387"
13997 [(set (match_operand:XF 0 "register_operand" "=f")
13998 (unspec:XF [(float_extend:XF
13999 (match_operand:MODEF 1 "register_operand" "0"))
14000 (match_operand:XF 2 "register_operand" "u")]
14001 UNSPEC_FYL2X))
14002 (clobber (match_scratch:XF 3 "=2"))]
14003 "TARGET_USE_FANCY_MATH_387
14004 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14005 || TARGET_MIX_SSE_I387)
14006 && flag_unsafe_math_optimizations"
14007 "fyl2x"
14008 [(set_attr "type" "fpspc")
14009 (set_attr "mode" "XF")])
14010
14011 (define_expand "logxf2"
14012 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14013 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14014 (match_dup 2)] UNSPEC_FYL2X))
14015 (clobber (match_scratch:XF 3 ""))])]
14016 "TARGET_USE_FANCY_MATH_387
14017 && flag_unsafe_math_optimizations"
14018 {
14019 operands[2] = gen_reg_rtx (XFmode);
14020 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14021 })
14022
14023 (define_expand "log<mode>2"
14024 [(use (match_operand:MODEF 0 "register_operand" ""))
14025 (use (match_operand:MODEF 1 "register_operand" ""))]
14026 "TARGET_USE_FANCY_MATH_387
14027 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14028 || TARGET_MIX_SSE_I387)
14029 && flag_unsafe_math_optimizations"
14030 {
14031 rtx op0 = gen_reg_rtx (XFmode);
14032
14033 rtx op2 = gen_reg_rtx (XFmode);
14034 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14035
14036 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14037 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14038 DONE;
14039 })
14040
14041 (define_expand "log10xf2"
14042 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14043 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14044 (match_dup 2)] UNSPEC_FYL2X))
14045 (clobber (match_scratch:XF 3 ""))])]
14046 "TARGET_USE_FANCY_MATH_387
14047 && flag_unsafe_math_optimizations"
14048 {
14049 operands[2] = gen_reg_rtx (XFmode);
14050 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14051 })
14052
14053 (define_expand "log10<mode>2"
14054 [(use (match_operand:MODEF 0 "register_operand" ""))
14055 (use (match_operand:MODEF 1 "register_operand" ""))]
14056 "TARGET_USE_FANCY_MATH_387
14057 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14058 || TARGET_MIX_SSE_I387)
14059 && flag_unsafe_math_optimizations"
14060 {
14061 rtx op0 = gen_reg_rtx (XFmode);
14062
14063 rtx op2 = gen_reg_rtx (XFmode);
14064 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14065
14066 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14067 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14068 DONE;
14069 })
14070
14071 (define_expand "log2xf2"
14072 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14073 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14074 (match_dup 2)] UNSPEC_FYL2X))
14075 (clobber (match_scratch:XF 3 ""))])]
14076 "TARGET_USE_FANCY_MATH_387
14077 && flag_unsafe_math_optimizations"
14078 {
14079 operands[2] = gen_reg_rtx (XFmode);
14080 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14081 })
14082
14083 (define_expand "log2<mode>2"
14084 [(use (match_operand:MODEF 0 "register_operand" ""))
14085 (use (match_operand:MODEF 1 "register_operand" ""))]
14086 "TARGET_USE_FANCY_MATH_387
14087 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14088 || TARGET_MIX_SSE_I387)
14089 && flag_unsafe_math_optimizations"
14090 {
14091 rtx op0 = gen_reg_rtx (XFmode);
14092
14093 rtx op2 = gen_reg_rtx (XFmode);
14094 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14095
14096 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14097 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14098 DONE;
14099 })
14100
14101 (define_insn "fyl2xp1xf3_i387"
14102 [(set (match_operand:XF 0 "register_operand" "=f")
14103 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14104 (match_operand:XF 2 "register_operand" "u")]
14105 UNSPEC_FYL2XP1))
14106 (clobber (match_scratch:XF 3 "=2"))]
14107 "TARGET_USE_FANCY_MATH_387
14108 && flag_unsafe_math_optimizations"
14109 "fyl2xp1"
14110 [(set_attr "type" "fpspc")
14111 (set_attr "mode" "XF")])
14112
14113 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14114 [(set (match_operand:XF 0 "register_operand" "=f")
14115 (unspec:XF [(float_extend:XF
14116 (match_operand:MODEF 1 "register_operand" "0"))
14117 (match_operand:XF 2 "register_operand" "u")]
14118 UNSPEC_FYL2XP1))
14119 (clobber (match_scratch:XF 3 "=2"))]
14120 "TARGET_USE_FANCY_MATH_387
14121 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14122 || TARGET_MIX_SSE_I387)
14123 && flag_unsafe_math_optimizations"
14124 "fyl2xp1"
14125 [(set_attr "type" "fpspc")
14126 (set_attr "mode" "XF")])
14127
14128 (define_expand "log1pxf2"
14129 [(use (match_operand:XF 0 "register_operand" ""))
14130 (use (match_operand:XF 1 "register_operand" ""))]
14131 "TARGET_USE_FANCY_MATH_387
14132 && flag_unsafe_math_optimizations"
14133 {
14134 if (optimize_insn_for_size_p ())
14135 FAIL;
14136
14137 ix86_emit_i387_log1p (operands[0], operands[1]);
14138 DONE;
14139 })
14140
14141 (define_expand "log1p<mode>2"
14142 [(use (match_operand:MODEF 0 "register_operand" ""))
14143 (use (match_operand:MODEF 1 "register_operand" ""))]
14144 "TARGET_USE_FANCY_MATH_387
14145 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14146 || TARGET_MIX_SSE_I387)
14147 && flag_unsafe_math_optimizations"
14148 {
14149 rtx op0;
14150
14151 if (optimize_insn_for_size_p ())
14152 FAIL;
14153
14154 op0 = gen_reg_rtx (XFmode);
14155
14156 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14157
14158 ix86_emit_i387_log1p (op0, operands[1]);
14159 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14160 DONE;
14161 })
14162
14163 (define_insn "fxtractxf3_i387"
14164 [(set (match_operand:XF 0 "register_operand" "=f")
14165 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14166 UNSPEC_XTRACT_FRACT))
14167 (set (match_operand:XF 1 "register_operand" "=u")
14168 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14169 "TARGET_USE_FANCY_MATH_387
14170 && flag_unsafe_math_optimizations"
14171 "fxtract"
14172 [(set_attr "type" "fpspc")
14173 (set_attr "mode" "XF")])
14174
14175 (define_insn "fxtract_extend<mode>xf3_i387"
14176 [(set (match_operand:XF 0 "register_operand" "=f")
14177 (unspec:XF [(float_extend:XF
14178 (match_operand:MODEF 2 "register_operand" "0"))]
14179 UNSPEC_XTRACT_FRACT))
14180 (set (match_operand:XF 1 "register_operand" "=u")
14181 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14182 "TARGET_USE_FANCY_MATH_387
14183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14184 || TARGET_MIX_SSE_I387)
14185 && flag_unsafe_math_optimizations"
14186 "fxtract"
14187 [(set_attr "type" "fpspc")
14188 (set_attr "mode" "XF")])
14189
14190 (define_expand "logbxf2"
14191 [(parallel [(set (match_dup 2)
14192 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14193 UNSPEC_XTRACT_FRACT))
14194 (set (match_operand:XF 0 "register_operand" "")
14195 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14196 "TARGET_USE_FANCY_MATH_387
14197 && flag_unsafe_math_optimizations"
14198 "operands[2] = gen_reg_rtx (XFmode);")
14199
14200 (define_expand "logb<mode>2"
14201 [(use (match_operand:MODEF 0 "register_operand" ""))
14202 (use (match_operand:MODEF 1 "register_operand" ""))]
14203 "TARGET_USE_FANCY_MATH_387
14204 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14205 || TARGET_MIX_SSE_I387)
14206 && flag_unsafe_math_optimizations"
14207 {
14208 rtx op0 = gen_reg_rtx (XFmode);
14209 rtx op1 = gen_reg_rtx (XFmode);
14210
14211 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14212 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14213 DONE;
14214 })
14215
14216 (define_expand "ilogbxf2"
14217 [(use (match_operand:SI 0 "register_operand" ""))
14218 (use (match_operand:XF 1 "register_operand" ""))]
14219 "TARGET_USE_FANCY_MATH_387
14220 && flag_unsafe_math_optimizations"
14221 {
14222 rtx op0, op1;
14223
14224 if (optimize_insn_for_size_p ())
14225 FAIL;
14226
14227 op0 = gen_reg_rtx (XFmode);
14228 op1 = gen_reg_rtx (XFmode);
14229
14230 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14231 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14232 DONE;
14233 })
14234
14235 (define_expand "ilogb<mode>2"
14236 [(use (match_operand:SI 0 "register_operand" ""))
14237 (use (match_operand:MODEF 1 "register_operand" ""))]
14238 "TARGET_USE_FANCY_MATH_387
14239 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14240 || TARGET_MIX_SSE_I387)
14241 && flag_unsafe_math_optimizations"
14242 {
14243 rtx op0, op1;
14244
14245 if (optimize_insn_for_size_p ())
14246 FAIL;
14247
14248 op0 = gen_reg_rtx (XFmode);
14249 op1 = gen_reg_rtx (XFmode);
14250
14251 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14252 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14253 DONE;
14254 })
14255
14256 (define_insn "*f2xm1xf2_i387"
14257 [(set (match_operand:XF 0 "register_operand" "=f")
14258 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14259 UNSPEC_F2XM1))]
14260 "TARGET_USE_FANCY_MATH_387
14261 && flag_unsafe_math_optimizations"
14262 "f2xm1"
14263 [(set_attr "type" "fpspc")
14264 (set_attr "mode" "XF")])
14265
14266 (define_insn "*fscalexf4_i387"
14267 [(set (match_operand:XF 0 "register_operand" "=f")
14268 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14269 (match_operand:XF 3 "register_operand" "1")]
14270 UNSPEC_FSCALE_FRACT))
14271 (set (match_operand:XF 1 "register_operand" "=u")
14272 (unspec:XF [(match_dup 2) (match_dup 3)]
14273 UNSPEC_FSCALE_EXP))]
14274 "TARGET_USE_FANCY_MATH_387
14275 && flag_unsafe_math_optimizations"
14276 "fscale"
14277 [(set_attr "type" "fpspc")
14278 (set_attr "mode" "XF")])
14279
14280 (define_expand "expNcorexf3"
14281 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14282 (match_operand:XF 2 "register_operand" "")))
14283 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14284 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14285 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14286 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14287 (parallel [(set (match_operand:XF 0 "register_operand" "")
14288 (unspec:XF [(match_dup 8) (match_dup 4)]
14289 UNSPEC_FSCALE_FRACT))
14290 (set (match_dup 9)
14291 (unspec:XF [(match_dup 8) (match_dup 4)]
14292 UNSPEC_FSCALE_EXP))])]
14293 "TARGET_USE_FANCY_MATH_387
14294 && flag_unsafe_math_optimizations"
14295 {
14296 int i;
14297
14298 if (optimize_insn_for_size_p ())
14299 FAIL;
14300
14301 for (i = 3; i < 10; i++)
14302 operands[i] = gen_reg_rtx (XFmode);
14303
14304 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14305 })
14306
14307 (define_expand "expxf2"
14308 [(use (match_operand:XF 0 "register_operand" ""))
14309 (use (match_operand:XF 1 "register_operand" ""))]
14310 "TARGET_USE_FANCY_MATH_387
14311 && flag_unsafe_math_optimizations"
14312 {
14313 rtx op2;
14314
14315 if (optimize_insn_for_size_p ())
14316 FAIL;
14317
14318 op2 = gen_reg_rtx (XFmode);
14319 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14320
14321 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14322 DONE;
14323 })
14324
14325 (define_expand "exp<mode>2"
14326 [(use (match_operand:MODEF 0 "register_operand" ""))
14327 (use (match_operand:MODEF 1 "general_operand" ""))]
14328 "TARGET_USE_FANCY_MATH_387
14329 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14330 || TARGET_MIX_SSE_I387)
14331 && flag_unsafe_math_optimizations"
14332 {
14333 rtx op0, op1;
14334
14335 if (optimize_insn_for_size_p ())
14336 FAIL;
14337
14338 op0 = gen_reg_rtx (XFmode);
14339 op1 = gen_reg_rtx (XFmode);
14340
14341 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14342 emit_insn (gen_expxf2 (op0, op1));
14343 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14344 DONE;
14345 })
14346
14347 (define_expand "exp10xf2"
14348 [(use (match_operand:XF 0 "register_operand" ""))
14349 (use (match_operand:XF 1 "register_operand" ""))]
14350 "TARGET_USE_FANCY_MATH_387
14351 && flag_unsafe_math_optimizations"
14352 {
14353 rtx op2;
14354
14355 if (optimize_insn_for_size_p ())
14356 FAIL;
14357
14358 op2 = gen_reg_rtx (XFmode);
14359 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14360
14361 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14362 DONE;
14363 })
14364
14365 (define_expand "exp10<mode>2"
14366 [(use (match_operand:MODEF 0 "register_operand" ""))
14367 (use (match_operand:MODEF 1 "general_operand" ""))]
14368 "TARGET_USE_FANCY_MATH_387
14369 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14370 || TARGET_MIX_SSE_I387)
14371 && flag_unsafe_math_optimizations"
14372 {
14373 rtx op0, op1;
14374
14375 if (optimize_insn_for_size_p ())
14376 FAIL;
14377
14378 op0 = gen_reg_rtx (XFmode);
14379 op1 = gen_reg_rtx (XFmode);
14380
14381 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14382 emit_insn (gen_exp10xf2 (op0, op1));
14383 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14384 DONE;
14385 })
14386
14387 (define_expand "exp2xf2"
14388 [(use (match_operand:XF 0 "register_operand" ""))
14389 (use (match_operand:XF 1 "register_operand" ""))]
14390 "TARGET_USE_FANCY_MATH_387
14391 && flag_unsafe_math_optimizations"
14392 {
14393 rtx op2;
14394
14395 if (optimize_insn_for_size_p ())
14396 FAIL;
14397
14398 op2 = gen_reg_rtx (XFmode);
14399 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14400
14401 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14402 DONE;
14403 })
14404
14405 (define_expand "exp2<mode>2"
14406 [(use (match_operand:MODEF 0 "register_operand" ""))
14407 (use (match_operand:MODEF 1 "general_operand" ""))]
14408 "TARGET_USE_FANCY_MATH_387
14409 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14410 || TARGET_MIX_SSE_I387)
14411 && flag_unsafe_math_optimizations"
14412 {
14413 rtx op0, op1;
14414
14415 if (optimize_insn_for_size_p ())
14416 FAIL;
14417
14418 op0 = gen_reg_rtx (XFmode);
14419 op1 = gen_reg_rtx (XFmode);
14420
14421 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14422 emit_insn (gen_exp2xf2 (op0, op1));
14423 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14424 DONE;
14425 })
14426
14427 (define_expand "expm1xf2"
14428 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14429 (match_dup 2)))
14430 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14431 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14432 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14433 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14434 (parallel [(set (match_dup 7)
14435 (unspec:XF [(match_dup 6) (match_dup 4)]
14436 UNSPEC_FSCALE_FRACT))
14437 (set (match_dup 8)
14438 (unspec:XF [(match_dup 6) (match_dup 4)]
14439 UNSPEC_FSCALE_EXP))])
14440 (parallel [(set (match_dup 10)
14441 (unspec:XF [(match_dup 9) (match_dup 8)]
14442 UNSPEC_FSCALE_FRACT))
14443 (set (match_dup 11)
14444 (unspec:XF [(match_dup 9) (match_dup 8)]
14445 UNSPEC_FSCALE_EXP))])
14446 (set (match_dup 12) (minus:XF (match_dup 10)
14447 (float_extend:XF (match_dup 13))))
14448 (set (match_operand:XF 0 "register_operand" "")
14449 (plus:XF (match_dup 12) (match_dup 7)))]
14450 "TARGET_USE_FANCY_MATH_387
14451 && flag_unsafe_math_optimizations"
14452 {
14453 int i;
14454
14455 if (optimize_insn_for_size_p ())
14456 FAIL;
14457
14458 for (i = 2; i < 13; i++)
14459 operands[i] = gen_reg_rtx (XFmode);
14460
14461 operands[13]
14462 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14463
14464 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14465 })
14466
14467 (define_expand "expm1<mode>2"
14468 [(use (match_operand:MODEF 0 "register_operand" ""))
14469 (use (match_operand:MODEF 1 "general_operand" ""))]
14470 "TARGET_USE_FANCY_MATH_387
14471 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14472 || TARGET_MIX_SSE_I387)
14473 && flag_unsafe_math_optimizations"
14474 {
14475 rtx op0, op1;
14476
14477 if (optimize_insn_for_size_p ())
14478 FAIL;
14479
14480 op0 = gen_reg_rtx (XFmode);
14481 op1 = gen_reg_rtx (XFmode);
14482
14483 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14484 emit_insn (gen_expm1xf2 (op0, op1));
14485 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14486 DONE;
14487 })
14488
14489 (define_expand "ldexpxf3"
14490 [(set (match_dup 3)
14491 (float:XF (match_operand:SI 2 "register_operand" "")))
14492 (parallel [(set (match_operand:XF 0 " register_operand" "")
14493 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14494 (match_dup 3)]
14495 UNSPEC_FSCALE_FRACT))
14496 (set (match_dup 4)
14497 (unspec:XF [(match_dup 1) (match_dup 3)]
14498 UNSPEC_FSCALE_EXP))])]
14499 "TARGET_USE_FANCY_MATH_387
14500 && flag_unsafe_math_optimizations"
14501 {
14502 if (optimize_insn_for_size_p ())
14503 FAIL;
14504
14505 operands[3] = gen_reg_rtx (XFmode);
14506 operands[4] = gen_reg_rtx (XFmode);
14507 })
14508
14509 (define_expand "ldexp<mode>3"
14510 [(use (match_operand:MODEF 0 "register_operand" ""))
14511 (use (match_operand:MODEF 1 "general_operand" ""))
14512 (use (match_operand:SI 2 "register_operand" ""))]
14513 "TARGET_USE_FANCY_MATH_387
14514 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14515 || TARGET_MIX_SSE_I387)
14516 && flag_unsafe_math_optimizations"
14517 {
14518 rtx op0, op1;
14519
14520 if (optimize_insn_for_size_p ())
14521 FAIL;
14522
14523 op0 = gen_reg_rtx (XFmode);
14524 op1 = gen_reg_rtx (XFmode);
14525
14526 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14527 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14528 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14529 DONE;
14530 })
14531
14532 (define_expand "scalbxf3"
14533 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14534 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14535 (match_operand:XF 2 "register_operand" "")]
14536 UNSPEC_FSCALE_FRACT))
14537 (set (match_dup 3)
14538 (unspec:XF [(match_dup 1) (match_dup 2)]
14539 UNSPEC_FSCALE_EXP))])]
14540 "TARGET_USE_FANCY_MATH_387
14541 && flag_unsafe_math_optimizations"
14542 {
14543 if (optimize_insn_for_size_p ())
14544 FAIL;
14545
14546 operands[3] = gen_reg_rtx (XFmode);
14547 })
14548
14549 (define_expand "scalb<mode>3"
14550 [(use (match_operand:MODEF 0 "register_operand" ""))
14551 (use (match_operand:MODEF 1 "general_operand" ""))
14552 (use (match_operand:MODEF 2 "general_operand" ""))]
14553 "TARGET_USE_FANCY_MATH_387
14554 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14555 || TARGET_MIX_SSE_I387)
14556 && flag_unsafe_math_optimizations"
14557 {
14558 rtx op0, op1, op2;
14559
14560 if (optimize_insn_for_size_p ())
14561 FAIL;
14562
14563 op0 = gen_reg_rtx (XFmode);
14564 op1 = gen_reg_rtx (XFmode);
14565 op2 = gen_reg_rtx (XFmode);
14566
14567 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14568 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14569 emit_insn (gen_scalbxf3 (op0, op1, op2));
14570 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14571 DONE;
14572 })
14573
14574 (define_expand "significandxf2"
14575 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14576 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14577 UNSPEC_XTRACT_FRACT))
14578 (set (match_dup 2)
14579 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14580 "TARGET_USE_FANCY_MATH_387
14581 && flag_unsafe_math_optimizations"
14582 "operands[2] = gen_reg_rtx (XFmode);")
14583
14584 (define_expand "significand<mode>2"
14585 [(use (match_operand:MODEF 0 "register_operand" ""))
14586 (use (match_operand:MODEF 1 "register_operand" ""))]
14587 "TARGET_USE_FANCY_MATH_387
14588 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14589 || TARGET_MIX_SSE_I387)
14590 && flag_unsafe_math_optimizations"
14591 {
14592 rtx op0 = gen_reg_rtx (XFmode);
14593 rtx op1 = gen_reg_rtx (XFmode);
14594
14595 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14596 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14597 DONE;
14598 })
14599 \f
14600
14601 (define_insn "sse4_1_round<mode>2"
14602 [(set (match_operand:MODEF 0 "register_operand" "=x")
14603 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14604 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14605 UNSPEC_ROUND))]
14606 "TARGET_ROUND"
14607 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14608 [(set_attr "type" "ssecvt")
14609 (set_attr "prefix_extra" "1")
14610 (set_attr "prefix" "maybe_vex")
14611 (set_attr "mode" "<MODE>")])
14612
14613 (define_insn "rintxf2"
14614 [(set (match_operand:XF 0 "register_operand" "=f")
14615 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14616 UNSPEC_FRNDINT))]
14617 "TARGET_USE_FANCY_MATH_387
14618 && flag_unsafe_math_optimizations"
14619 "frndint"
14620 [(set_attr "type" "fpspc")
14621 (set_attr "mode" "XF")])
14622
14623 (define_expand "rint<mode>2"
14624 [(use (match_operand:MODEF 0 "register_operand" ""))
14625 (use (match_operand:MODEF 1 "register_operand" ""))]
14626 "(TARGET_USE_FANCY_MATH_387
14627 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14628 || TARGET_MIX_SSE_I387)
14629 && flag_unsafe_math_optimizations)
14630 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14631 && !flag_trapping_math)"
14632 {
14633 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14634 && !flag_trapping_math)
14635 {
14636 if (TARGET_ROUND)
14637 emit_insn (gen_sse4_1_round<mode>2
14638 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14639 else if (optimize_insn_for_size_p ())
14640 FAIL;
14641 else
14642 ix86_expand_rint (operand0, operand1);
14643 }
14644 else
14645 {
14646 rtx op0 = gen_reg_rtx (XFmode);
14647 rtx op1 = gen_reg_rtx (XFmode);
14648
14649 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14650 emit_insn (gen_rintxf2 (op0, op1));
14651
14652 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14653 }
14654 DONE;
14655 })
14656
14657 (define_expand "round<mode>2"
14658 [(match_operand:X87MODEF 0 "register_operand" "")
14659 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14660 "(TARGET_USE_FANCY_MATH_387
14661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14662 || TARGET_MIX_SSE_I387)
14663 && flag_unsafe_math_optimizations)
14664 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14665 && !flag_trapping_math && !flag_rounding_math)"
14666 {
14667 if (optimize_insn_for_size_p ())
14668 FAIL;
14669
14670 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14671 && !flag_trapping_math && !flag_rounding_math)
14672 {
14673 if (TARGET_ROUND)
14674 {
14675 operands[1] = force_reg (<MODE>mode, operands[1]);
14676 ix86_expand_round_sse4 (operands[0], operands[1]);
14677 }
14678 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14679 ix86_expand_round (operands[0], operands[1]);
14680 else
14681 ix86_expand_rounddf_32 (operands[0], operands[1]);
14682 }
14683 else
14684 {
14685 operands[1] = force_reg (<MODE>mode, operands[1]);
14686 ix86_emit_i387_round (operands[0], operands[1]);
14687 }
14688 DONE;
14689 })
14690
14691 (define_insn_and_split "*fistdi2_1"
14692 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14693 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14694 UNSPEC_FIST))]
14695 "TARGET_USE_FANCY_MATH_387
14696 && can_create_pseudo_p ()"
14697 "#"
14698 "&& 1"
14699 [(const_int 0)]
14700 {
14701 if (memory_operand (operands[0], VOIDmode))
14702 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14703 else
14704 {
14705 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14706 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14707 operands[2]));
14708 }
14709 DONE;
14710 }
14711 [(set_attr "type" "fpspc")
14712 (set_attr "mode" "DI")])
14713
14714 (define_insn "fistdi2"
14715 [(set (match_operand:DI 0 "memory_operand" "=m")
14716 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14717 UNSPEC_FIST))
14718 (clobber (match_scratch:XF 2 "=&1f"))]
14719 "TARGET_USE_FANCY_MATH_387"
14720 "* return output_fix_trunc (insn, operands, false);"
14721 [(set_attr "type" "fpspc")
14722 (set_attr "mode" "DI")])
14723
14724 (define_insn "fistdi2_with_temp"
14725 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14726 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14727 UNSPEC_FIST))
14728 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14729 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14730 "TARGET_USE_FANCY_MATH_387"
14731 "#"
14732 [(set_attr "type" "fpspc")
14733 (set_attr "mode" "DI")])
14734
14735 (define_split
14736 [(set (match_operand:DI 0 "register_operand" "")
14737 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14738 UNSPEC_FIST))
14739 (clobber (match_operand:DI 2 "memory_operand" ""))
14740 (clobber (match_scratch 3 ""))]
14741 "reload_completed"
14742 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14743 (clobber (match_dup 3))])
14744 (set (match_dup 0) (match_dup 2))])
14745
14746 (define_split
14747 [(set (match_operand:DI 0 "memory_operand" "")
14748 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14749 UNSPEC_FIST))
14750 (clobber (match_operand:DI 2 "memory_operand" ""))
14751 (clobber (match_scratch 3 ""))]
14752 "reload_completed"
14753 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14754 (clobber (match_dup 3))])])
14755
14756 (define_insn_and_split "*fist<mode>2_1"
14757 [(set (match_operand:SWI24 0 "register_operand" "")
14758 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14759 UNSPEC_FIST))]
14760 "TARGET_USE_FANCY_MATH_387
14761 && can_create_pseudo_p ()"
14762 "#"
14763 "&& 1"
14764 [(const_int 0)]
14765 {
14766 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14767 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14768 operands[2]));
14769 DONE;
14770 }
14771 [(set_attr "type" "fpspc")
14772 (set_attr "mode" "<MODE>")])
14773
14774 (define_insn "fist<mode>2"
14775 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14776 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14777 UNSPEC_FIST))]
14778 "TARGET_USE_FANCY_MATH_387"
14779 "* return output_fix_trunc (insn, operands, false);"
14780 [(set_attr "type" "fpspc")
14781 (set_attr "mode" "<MODE>")])
14782
14783 (define_insn "fist<mode>2_with_temp"
14784 [(set (match_operand:SWI24 0 "register_operand" "=r")
14785 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14786 UNSPEC_FIST))
14787 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14788 "TARGET_USE_FANCY_MATH_387"
14789 "#"
14790 [(set_attr "type" "fpspc")
14791 (set_attr "mode" "<MODE>")])
14792
14793 (define_split
14794 [(set (match_operand:SWI24 0 "register_operand" "")
14795 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14796 UNSPEC_FIST))
14797 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14798 "reload_completed"
14799 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14800 (set (match_dup 0) (match_dup 2))])
14801
14802 (define_split
14803 [(set (match_operand:SWI24 0 "memory_operand" "")
14804 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14805 UNSPEC_FIST))
14806 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14807 "reload_completed"
14808 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14809
14810 (define_expand "lrintxf<mode>2"
14811 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14812 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14813 UNSPEC_FIST))]
14814 "TARGET_USE_FANCY_MATH_387")
14815
14816 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14817 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14818 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14819 UNSPEC_FIX_NOTRUNC))]
14820 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14821 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14822
14823 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14824 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14825 (match_operand:X87MODEF 1 "register_operand" "")]
14826 "(TARGET_USE_FANCY_MATH_387
14827 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14828 || TARGET_MIX_SSE_I387)
14829 && flag_unsafe_math_optimizations)
14830 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14831 && <SWI248x:MODE>mode != HImode
14832 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14833 && !flag_trapping_math && !flag_rounding_math)"
14834 {
14835 if (optimize_insn_for_size_p ())
14836 FAIL;
14837
14838 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14839 && <SWI248x:MODE>mode != HImode
14840 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14841 && !flag_trapping_math && !flag_rounding_math)
14842 ix86_expand_lround (operand0, operand1);
14843 else
14844 ix86_emit_i387_round (operands[0], operands[1]);
14845 DONE;
14846 })
14847
14848 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14849 (define_insn_and_split "frndintxf2_floor"
14850 [(set (match_operand:XF 0 "register_operand" "")
14851 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14852 UNSPEC_FRNDINT_FLOOR))
14853 (clobber (reg:CC FLAGS_REG))]
14854 "TARGET_USE_FANCY_MATH_387
14855 && flag_unsafe_math_optimizations
14856 && can_create_pseudo_p ()"
14857 "#"
14858 "&& 1"
14859 [(const_int 0)]
14860 {
14861 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14862
14863 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14864 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14865
14866 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14867 operands[2], operands[3]));
14868 DONE;
14869 }
14870 [(set_attr "type" "frndint")
14871 (set_attr "i387_cw" "floor")
14872 (set_attr "mode" "XF")])
14873
14874 (define_insn "frndintxf2_floor_i387"
14875 [(set (match_operand:XF 0 "register_operand" "=f")
14876 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14877 UNSPEC_FRNDINT_FLOOR))
14878 (use (match_operand:HI 2 "memory_operand" "m"))
14879 (use (match_operand:HI 3 "memory_operand" "m"))]
14880 "TARGET_USE_FANCY_MATH_387
14881 && flag_unsafe_math_optimizations"
14882 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14883 [(set_attr "type" "frndint")
14884 (set_attr "i387_cw" "floor")
14885 (set_attr "mode" "XF")])
14886
14887 (define_expand "floorxf2"
14888 [(use (match_operand:XF 0 "register_operand" ""))
14889 (use (match_operand:XF 1 "register_operand" ""))]
14890 "TARGET_USE_FANCY_MATH_387
14891 && flag_unsafe_math_optimizations"
14892 {
14893 if (optimize_insn_for_size_p ())
14894 FAIL;
14895 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14896 DONE;
14897 })
14898
14899 (define_expand "floor<mode>2"
14900 [(use (match_operand:MODEF 0 "register_operand" ""))
14901 (use (match_operand:MODEF 1 "register_operand" ""))]
14902 "(TARGET_USE_FANCY_MATH_387
14903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14904 || TARGET_MIX_SSE_I387)
14905 && flag_unsafe_math_optimizations)
14906 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14907 && !flag_trapping_math)"
14908 {
14909 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14910 && !flag_trapping_math)
14911 {
14912 if (TARGET_ROUND)
14913 emit_insn (gen_sse4_1_round<mode>2
14914 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14915 else if (optimize_insn_for_size_p ())
14916 FAIL;
14917 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14918 ix86_expand_floorceil (operand0, operand1, true);
14919 else
14920 ix86_expand_floorceildf_32 (operand0, operand1, true);
14921 }
14922 else
14923 {
14924 rtx op0, op1;
14925
14926 if (optimize_insn_for_size_p ())
14927 FAIL;
14928
14929 op0 = gen_reg_rtx (XFmode);
14930 op1 = gen_reg_rtx (XFmode);
14931 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14932 emit_insn (gen_frndintxf2_floor (op0, op1));
14933
14934 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14935 }
14936 DONE;
14937 })
14938
14939 (define_insn_and_split "*fist<mode>2_floor_1"
14940 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14941 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14942 UNSPEC_FIST_FLOOR))
14943 (clobber (reg:CC FLAGS_REG))]
14944 "TARGET_USE_FANCY_MATH_387
14945 && flag_unsafe_math_optimizations
14946 && can_create_pseudo_p ()"
14947 "#"
14948 "&& 1"
14949 [(const_int 0)]
14950 {
14951 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14952
14953 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14954 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14955 if (memory_operand (operands[0], VOIDmode))
14956 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14957 operands[2], operands[3]));
14958 else
14959 {
14960 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14961 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14962 operands[2], operands[3],
14963 operands[4]));
14964 }
14965 DONE;
14966 }
14967 [(set_attr "type" "fistp")
14968 (set_attr "i387_cw" "floor")
14969 (set_attr "mode" "<MODE>")])
14970
14971 (define_insn "fistdi2_floor"
14972 [(set (match_operand:DI 0 "memory_operand" "=m")
14973 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14974 UNSPEC_FIST_FLOOR))
14975 (use (match_operand:HI 2 "memory_operand" "m"))
14976 (use (match_operand:HI 3 "memory_operand" "m"))
14977 (clobber (match_scratch:XF 4 "=&1f"))]
14978 "TARGET_USE_FANCY_MATH_387
14979 && flag_unsafe_math_optimizations"
14980 "* return output_fix_trunc (insn, operands, false);"
14981 [(set_attr "type" "fistp")
14982 (set_attr "i387_cw" "floor")
14983 (set_attr "mode" "DI")])
14984
14985 (define_insn "fistdi2_floor_with_temp"
14986 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14987 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14988 UNSPEC_FIST_FLOOR))
14989 (use (match_operand:HI 2 "memory_operand" "m,m"))
14990 (use (match_operand:HI 3 "memory_operand" "m,m"))
14991 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14992 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14993 "TARGET_USE_FANCY_MATH_387
14994 && flag_unsafe_math_optimizations"
14995 "#"
14996 [(set_attr "type" "fistp")
14997 (set_attr "i387_cw" "floor")
14998 (set_attr "mode" "DI")])
14999
15000 (define_split
15001 [(set (match_operand:DI 0 "register_operand" "")
15002 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15003 UNSPEC_FIST_FLOOR))
15004 (use (match_operand:HI 2 "memory_operand" ""))
15005 (use (match_operand:HI 3 "memory_operand" ""))
15006 (clobber (match_operand:DI 4 "memory_operand" ""))
15007 (clobber (match_scratch 5 ""))]
15008 "reload_completed"
15009 [(parallel [(set (match_dup 4)
15010 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15011 (use (match_dup 2))
15012 (use (match_dup 3))
15013 (clobber (match_dup 5))])
15014 (set (match_dup 0) (match_dup 4))])
15015
15016 (define_split
15017 [(set (match_operand:DI 0 "memory_operand" "")
15018 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15019 UNSPEC_FIST_FLOOR))
15020 (use (match_operand:HI 2 "memory_operand" ""))
15021 (use (match_operand:HI 3 "memory_operand" ""))
15022 (clobber (match_operand:DI 4 "memory_operand" ""))
15023 (clobber (match_scratch 5 ""))]
15024 "reload_completed"
15025 [(parallel [(set (match_dup 0)
15026 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15027 (use (match_dup 2))
15028 (use (match_dup 3))
15029 (clobber (match_dup 5))])])
15030
15031 (define_insn "fist<mode>2_floor"
15032 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15033 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15034 UNSPEC_FIST_FLOOR))
15035 (use (match_operand:HI 2 "memory_operand" "m"))
15036 (use (match_operand:HI 3 "memory_operand" "m"))]
15037 "TARGET_USE_FANCY_MATH_387
15038 && flag_unsafe_math_optimizations"
15039 "* return output_fix_trunc (insn, operands, false);"
15040 [(set_attr "type" "fistp")
15041 (set_attr "i387_cw" "floor")
15042 (set_attr "mode" "<MODE>")])
15043
15044 (define_insn "fist<mode>2_floor_with_temp"
15045 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15046 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15047 UNSPEC_FIST_FLOOR))
15048 (use (match_operand:HI 2 "memory_operand" "m,m"))
15049 (use (match_operand:HI 3 "memory_operand" "m,m"))
15050 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15051 "TARGET_USE_FANCY_MATH_387
15052 && flag_unsafe_math_optimizations"
15053 "#"
15054 [(set_attr "type" "fistp")
15055 (set_attr "i387_cw" "floor")
15056 (set_attr "mode" "<MODE>")])
15057
15058 (define_split
15059 [(set (match_operand:SWI24 0 "register_operand" "")
15060 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15061 UNSPEC_FIST_FLOOR))
15062 (use (match_operand:HI 2 "memory_operand" ""))
15063 (use (match_operand:HI 3 "memory_operand" ""))
15064 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15065 "reload_completed"
15066 [(parallel [(set (match_dup 4)
15067 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15068 (use (match_dup 2))
15069 (use (match_dup 3))])
15070 (set (match_dup 0) (match_dup 4))])
15071
15072 (define_split
15073 [(set (match_operand:SWI24 0 "memory_operand" "")
15074 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15075 UNSPEC_FIST_FLOOR))
15076 (use (match_operand:HI 2 "memory_operand" ""))
15077 (use (match_operand:HI 3 "memory_operand" ""))
15078 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15079 "reload_completed"
15080 [(parallel [(set (match_dup 0)
15081 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15082 (use (match_dup 2))
15083 (use (match_dup 3))])])
15084
15085 (define_expand "lfloorxf<mode>2"
15086 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15087 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15088 UNSPEC_FIST_FLOOR))
15089 (clobber (reg:CC FLAGS_REG))])]
15090 "TARGET_USE_FANCY_MATH_387
15091 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15092 && flag_unsafe_math_optimizations")
15093
15094 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15095 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15096 (match_operand:MODEF 1 "register_operand" "")]
15097 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15098 && !flag_trapping_math"
15099 {
15100 if (TARGET_64BIT && optimize_insn_for_size_p ())
15101 FAIL;
15102 ix86_expand_lfloorceil (operand0, operand1, true);
15103 DONE;
15104 })
15105
15106 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15107 (define_insn_and_split "frndintxf2_ceil"
15108 [(set (match_operand:XF 0 "register_operand" "")
15109 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15110 UNSPEC_FRNDINT_CEIL))
15111 (clobber (reg:CC FLAGS_REG))]
15112 "TARGET_USE_FANCY_MATH_387
15113 && flag_unsafe_math_optimizations
15114 && can_create_pseudo_p ()"
15115 "#"
15116 "&& 1"
15117 [(const_int 0)]
15118 {
15119 ix86_optimize_mode_switching[I387_CEIL] = 1;
15120
15121 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15122 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15123
15124 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15125 operands[2], operands[3]));
15126 DONE;
15127 }
15128 [(set_attr "type" "frndint")
15129 (set_attr "i387_cw" "ceil")
15130 (set_attr "mode" "XF")])
15131
15132 (define_insn "frndintxf2_ceil_i387"
15133 [(set (match_operand:XF 0 "register_operand" "=f")
15134 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15135 UNSPEC_FRNDINT_CEIL))
15136 (use (match_operand:HI 2 "memory_operand" "m"))
15137 (use (match_operand:HI 3 "memory_operand" "m"))]
15138 "TARGET_USE_FANCY_MATH_387
15139 && flag_unsafe_math_optimizations"
15140 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15141 [(set_attr "type" "frndint")
15142 (set_attr "i387_cw" "ceil")
15143 (set_attr "mode" "XF")])
15144
15145 (define_expand "ceilxf2"
15146 [(use (match_operand:XF 0 "register_operand" ""))
15147 (use (match_operand:XF 1 "register_operand" ""))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && flag_unsafe_math_optimizations"
15150 {
15151 if (optimize_insn_for_size_p ())
15152 FAIL;
15153 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15154 DONE;
15155 })
15156
15157 (define_expand "ceil<mode>2"
15158 [(use (match_operand:MODEF 0 "register_operand" ""))
15159 (use (match_operand:MODEF 1 "register_operand" ""))]
15160 "(TARGET_USE_FANCY_MATH_387
15161 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15162 || TARGET_MIX_SSE_I387)
15163 && flag_unsafe_math_optimizations)
15164 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15165 && !flag_trapping_math)"
15166 {
15167 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15168 && !flag_trapping_math)
15169 {
15170 if (TARGET_ROUND)
15171 emit_insn (gen_sse4_1_round<mode>2
15172 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15173 else if (optimize_insn_for_size_p ())
15174 FAIL;
15175 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15176 ix86_expand_floorceil (operand0, operand1, false);
15177 else
15178 ix86_expand_floorceildf_32 (operand0, operand1, false);
15179 }
15180 else
15181 {
15182 rtx op0, op1;
15183
15184 if (optimize_insn_for_size_p ())
15185 FAIL;
15186
15187 op0 = gen_reg_rtx (XFmode);
15188 op1 = gen_reg_rtx (XFmode);
15189 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15190 emit_insn (gen_frndintxf2_ceil (op0, op1));
15191
15192 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15193 }
15194 DONE;
15195 })
15196
15197 (define_insn_and_split "*fist<mode>2_ceil_1"
15198 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15199 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15200 UNSPEC_FIST_CEIL))
15201 (clobber (reg:CC FLAGS_REG))]
15202 "TARGET_USE_FANCY_MATH_387
15203 && flag_unsafe_math_optimizations
15204 && can_create_pseudo_p ()"
15205 "#"
15206 "&& 1"
15207 [(const_int 0)]
15208 {
15209 ix86_optimize_mode_switching[I387_CEIL] = 1;
15210
15211 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15212 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15213 if (memory_operand (operands[0], VOIDmode))
15214 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15215 operands[2], operands[3]));
15216 else
15217 {
15218 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15219 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15220 operands[2], operands[3],
15221 operands[4]));
15222 }
15223 DONE;
15224 }
15225 [(set_attr "type" "fistp")
15226 (set_attr "i387_cw" "ceil")
15227 (set_attr "mode" "<MODE>")])
15228
15229 (define_insn "fistdi2_ceil"
15230 [(set (match_operand:DI 0 "memory_operand" "=m")
15231 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15232 UNSPEC_FIST_CEIL))
15233 (use (match_operand:HI 2 "memory_operand" "m"))
15234 (use (match_operand:HI 3 "memory_operand" "m"))
15235 (clobber (match_scratch:XF 4 "=&1f"))]
15236 "TARGET_USE_FANCY_MATH_387
15237 && flag_unsafe_math_optimizations"
15238 "* return output_fix_trunc (insn, operands, false);"
15239 [(set_attr "type" "fistp")
15240 (set_attr "i387_cw" "ceil")
15241 (set_attr "mode" "DI")])
15242
15243 (define_insn "fistdi2_ceil_with_temp"
15244 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15245 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15246 UNSPEC_FIST_CEIL))
15247 (use (match_operand:HI 2 "memory_operand" "m,m"))
15248 (use (match_operand:HI 3 "memory_operand" "m,m"))
15249 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15250 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15251 "TARGET_USE_FANCY_MATH_387
15252 && flag_unsafe_math_optimizations"
15253 "#"
15254 [(set_attr "type" "fistp")
15255 (set_attr "i387_cw" "ceil")
15256 (set_attr "mode" "DI")])
15257
15258 (define_split
15259 [(set (match_operand:DI 0 "register_operand" "")
15260 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15261 UNSPEC_FIST_CEIL))
15262 (use (match_operand:HI 2 "memory_operand" ""))
15263 (use (match_operand:HI 3 "memory_operand" ""))
15264 (clobber (match_operand:DI 4 "memory_operand" ""))
15265 (clobber (match_scratch 5 ""))]
15266 "reload_completed"
15267 [(parallel [(set (match_dup 4)
15268 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15269 (use (match_dup 2))
15270 (use (match_dup 3))
15271 (clobber (match_dup 5))])
15272 (set (match_dup 0) (match_dup 4))])
15273
15274 (define_split
15275 [(set (match_operand:DI 0 "memory_operand" "")
15276 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15277 UNSPEC_FIST_CEIL))
15278 (use (match_operand:HI 2 "memory_operand" ""))
15279 (use (match_operand:HI 3 "memory_operand" ""))
15280 (clobber (match_operand:DI 4 "memory_operand" ""))
15281 (clobber (match_scratch 5 ""))]
15282 "reload_completed"
15283 [(parallel [(set (match_dup 0)
15284 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15285 (use (match_dup 2))
15286 (use (match_dup 3))
15287 (clobber (match_dup 5))])])
15288
15289 (define_insn "fist<mode>2_ceil"
15290 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15291 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15292 UNSPEC_FIST_CEIL))
15293 (use (match_operand:HI 2 "memory_operand" "m"))
15294 (use (match_operand:HI 3 "memory_operand" "m"))]
15295 "TARGET_USE_FANCY_MATH_387
15296 && flag_unsafe_math_optimizations"
15297 "* return output_fix_trunc (insn, operands, false);"
15298 [(set_attr "type" "fistp")
15299 (set_attr "i387_cw" "ceil")
15300 (set_attr "mode" "<MODE>")])
15301
15302 (define_insn "fist<mode>2_ceil_with_temp"
15303 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15304 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15305 UNSPEC_FIST_CEIL))
15306 (use (match_operand:HI 2 "memory_operand" "m,m"))
15307 (use (match_operand:HI 3 "memory_operand" "m,m"))
15308 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15309 "TARGET_USE_FANCY_MATH_387
15310 && flag_unsafe_math_optimizations"
15311 "#"
15312 [(set_attr "type" "fistp")
15313 (set_attr "i387_cw" "ceil")
15314 (set_attr "mode" "<MODE>")])
15315
15316 (define_split
15317 [(set (match_operand:SWI24 0 "register_operand" "")
15318 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15319 UNSPEC_FIST_CEIL))
15320 (use (match_operand:HI 2 "memory_operand" ""))
15321 (use (match_operand:HI 3 "memory_operand" ""))
15322 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15323 "reload_completed"
15324 [(parallel [(set (match_dup 4)
15325 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15326 (use (match_dup 2))
15327 (use (match_dup 3))])
15328 (set (match_dup 0) (match_dup 4))])
15329
15330 (define_split
15331 [(set (match_operand:SWI24 0 "memory_operand" "")
15332 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15333 UNSPEC_FIST_CEIL))
15334 (use (match_operand:HI 2 "memory_operand" ""))
15335 (use (match_operand:HI 3 "memory_operand" ""))
15336 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15337 "reload_completed"
15338 [(parallel [(set (match_dup 0)
15339 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15340 (use (match_dup 2))
15341 (use (match_dup 3))])])
15342
15343 (define_expand "lceilxf<mode>2"
15344 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15345 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15346 UNSPEC_FIST_CEIL))
15347 (clobber (reg:CC FLAGS_REG))])]
15348 "TARGET_USE_FANCY_MATH_387
15349 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15350 && flag_unsafe_math_optimizations")
15351
15352 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15353 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15354 (match_operand:MODEF 1 "register_operand" "")]
15355 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15356 && !flag_trapping_math"
15357 {
15358 ix86_expand_lfloorceil (operand0, operand1, false);
15359 DONE;
15360 })
15361
15362 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15363 (define_insn_and_split "frndintxf2_trunc"
15364 [(set (match_operand:XF 0 "register_operand" "")
15365 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15366 UNSPEC_FRNDINT_TRUNC))
15367 (clobber (reg:CC FLAGS_REG))]
15368 "TARGET_USE_FANCY_MATH_387
15369 && flag_unsafe_math_optimizations
15370 && can_create_pseudo_p ()"
15371 "#"
15372 "&& 1"
15373 [(const_int 0)]
15374 {
15375 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15376
15377 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15378 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15379
15380 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15381 operands[2], operands[3]));
15382 DONE;
15383 }
15384 [(set_attr "type" "frndint")
15385 (set_attr "i387_cw" "trunc")
15386 (set_attr "mode" "XF")])
15387
15388 (define_insn "frndintxf2_trunc_i387"
15389 [(set (match_operand:XF 0 "register_operand" "=f")
15390 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15391 UNSPEC_FRNDINT_TRUNC))
15392 (use (match_operand:HI 2 "memory_operand" "m"))
15393 (use (match_operand:HI 3 "memory_operand" "m"))]
15394 "TARGET_USE_FANCY_MATH_387
15395 && flag_unsafe_math_optimizations"
15396 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15397 [(set_attr "type" "frndint")
15398 (set_attr "i387_cw" "trunc")
15399 (set_attr "mode" "XF")])
15400
15401 (define_expand "btruncxf2"
15402 [(use (match_operand:XF 0 "register_operand" ""))
15403 (use (match_operand:XF 1 "register_operand" ""))]
15404 "TARGET_USE_FANCY_MATH_387
15405 && flag_unsafe_math_optimizations"
15406 {
15407 if (optimize_insn_for_size_p ())
15408 FAIL;
15409 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15410 DONE;
15411 })
15412
15413 (define_expand "btrunc<mode>2"
15414 [(use (match_operand:MODEF 0 "register_operand" ""))
15415 (use (match_operand:MODEF 1 "register_operand" ""))]
15416 "(TARGET_USE_FANCY_MATH_387
15417 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15418 || TARGET_MIX_SSE_I387)
15419 && flag_unsafe_math_optimizations)
15420 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15421 && !flag_trapping_math)"
15422 {
15423 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15424 && !flag_trapping_math)
15425 {
15426 if (TARGET_ROUND)
15427 emit_insn (gen_sse4_1_round<mode>2
15428 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15429 else if (optimize_insn_for_size_p ())
15430 FAIL;
15431 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15432 ix86_expand_trunc (operand0, operand1);
15433 else
15434 ix86_expand_truncdf_32 (operand0, operand1);
15435 }
15436 else
15437 {
15438 rtx op0, op1;
15439
15440 if (optimize_insn_for_size_p ())
15441 FAIL;
15442
15443 op0 = gen_reg_rtx (XFmode);
15444 op1 = gen_reg_rtx (XFmode);
15445 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15446 emit_insn (gen_frndintxf2_trunc (op0, op1));
15447
15448 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15449 }
15450 DONE;
15451 })
15452
15453 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15454 (define_insn_and_split "frndintxf2_mask_pm"
15455 [(set (match_operand:XF 0 "register_operand" "")
15456 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15457 UNSPEC_FRNDINT_MASK_PM))
15458 (clobber (reg:CC FLAGS_REG))]
15459 "TARGET_USE_FANCY_MATH_387
15460 && flag_unsafe_math_optimizations
15461 && can_create_pseudo_p ()"
15462 "#"
15463 "&& 1"
15464 [(const_int 0)]
15465 {
15466 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15467
15468 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15469 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15470
15471 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15472 operands[2], operands[3]));
15473 DONE;
15474 }
15475 [(set_attr "type" "frndint")
15476 (set_attr "i387_cw" "mask_pm")
15477 (set_attr "mode" "XF")])
15478
15479 (define_insn "frndintxf2_mask_pm_i387"
15480 [(set (match_operand:XF 0 "register_operand" "=f")
15481 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15482 UNSPEC_FRNDINT_MASK_PM))
15483 (use (match_operand:HI 2 "memory_operand" "m"))
15484 (use (match_operand:HI 3 "memory_operand" "m"))]
15485 "TARGET_USE_FANCY_MATH_387
15486 && flag_unsafe_math_optimizations"
15487 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15488 [(set_attr "type" "frndint")
15489 (set_attr "i387_cw" "mask_pm")
15490 (set_attr "mode" "XF")])
15491
15492 (define_expand "nearbyintxf2"
15493 [(use (match_operand:XF 0 "register_operand" ""))
15494 (use (match_operand:XF 1 "register_operand" ""))]
15495 "TARGET_USE_FANCY_MATH_387
15496 && flag_unsafe_math_optimizations"
15497 {
15498 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15499 DONE;
15500 })
15501
15502 (define_expand "nearbyint<mode>2"
15503 [(use (match_operand:MODEF 0 "register_operand" ""))
15504 (use (match_operand:MODEF 1 "register_operand" ""))]
15505 "TARGET_USE_FANCY_MATH_387
15506 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15507 || TARGET_MIX_SSE_I387)
15508 && flag_unsafe_math_optimizations"
15509 {
15510 rtx op0 = gen_reg_rtx (XFmode);
15511 rtx op1 = gen_reg_rtx (XFmode);
15512
15513 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15514 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15515
15516 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15517 DONE;
15518 })
15519
15520 (define_insn "fxam<mode>2_i387"
15521 [(set (match_operand:HI 0 "register_operand" "=a")
15522 (unspec:HI
15523 [(match_operand:X87MODEF 1 "register_operand" "f")]
15524 UNSPEC_FXAM))]
15525 "TARGET_USE_FANCY_MATH_387"
15526 "fxam\n\tfnstsw\t%0"
15527 [(set_attr "type" "multi")
15528 (set_attr "length" "4")
15529 (set_attr "unit" "i387")
15530 (set_attr "mode" "<MODE>")])
15531
15532 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15533 [(set (match_operand:HI 0 "register_operand" "")
15534 (unspec:HI
15535 [(match_operand:MODEF 1 "memory_operand" "")]
15536 UNSPEC_FXAM_MEM))]
15537 "TARGET_USE_FANCY_MATH_387
15538 && can_create_pseudo_p ()"
15539 "#"
15540 "&& 1"
15541 [(set (match_dup 2)(match_dup 1))
15542 (set (match_dup 0)
15543 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15544 {
15545 operands[2] = gen_reg_rtx (<MODE>mode);
15546
15547 MEM_VOLATILE_P (operands[1]) = 1;
15548 }
15549 [(set_attr "type" "multi")
15550 (set_attr "unit" "i387")
15551 (set_attr "mode" "<MODE>")])
15552
15553 (define_expand "isinfxf2"
15554 [(use (match_operand:SI 0 "register_operand" ""))
15555 (use (match_operand:XF 1 "register_operand" ""))]
15556 "TARGET_USE_FANCY_MATH_387
15557 && TARGET_C99_FUNCTIONS"
15558 {
15559 rtx mask = GEN_INT (0x45);
15560 rtx val = GEN_INT (0x05);
15561
15562 rtx cond;
15563
15564 rtx scratch = gen_reg_rtx (HImode);
15565 rtx res = gen_reg_rtx (QImode);
15566
15567 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15568
15569 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15570 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15571 cond = gen_rtx_fmt_ee (EQ, QImode,
15572 gen_rtx_REG (CCmode, FLAGS_REG),
15573 const0_rtx);
15574 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15575 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15576 DONE;
15577 })
15578
15579 (define_expand "isinf<mode>2"
15580 [(use (match_operand:SI 0 "register_operand" ""))
15581 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15582 "TARGET_USE_FANCY_MATH_387
15583 && TARGET_C99_FUNCTIONS
15584 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15585 {
15586 rtx mask = GEN_INT (0x45);
15587 rtx val = GEN_INT (0x05);
15588
15589 rtx cond;
15590
15591 rtx scratch = gen_reg_rtx (HImode);
15592 rtx res = gen_reg_rtx (QImode);
15593
15594 /* Remove excess precision by forcing value through memory. */
15595 if (memory_operand (operands[1], VOIDmode))
15596 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15597 else
15598 {
15599 enum ix86_stack_slot slot = (virtuals_instantiated
15600 ? SLOT_TEMP
15601 : SLOT_VIRTUAL);
15602 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15603
15604 emit_move_insn (temp, operands[1]);
15605 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15606 }
15607
15608 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15609 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15610 cond = gen_rtx_fmt_ee (EQ, QImode,
15611 gen_rtx_REG (CCmode, FLAGS_REG),
15612 const0_rtx);
15613 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15614 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15615 DONE;
15616 })
15617
15618 (define_expand "signbitxf2"
15619 [(use (match_operand:SI 0 "register_operand" ""))
15620 (use (match_operand:XF 1 "register_operand" ""))]
15621 "TARGET_USE_FANCY_MATH_387"
15622 {
15623 rtx scratch = gen_reg_rtx (HImode);
15624
15625 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15626 emit_insn (gen_andsi3 (operands[0],
15627 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15628 DONE;
15629 })
15630
15631 (define_insn "movmsk_df"
15632 [(set (match_operand:SI 0 "register_operand" "=r")
15633 (unspec:SI
15634 [(match_operand:DF 1 "register_operand" "x")]
15635 UNSPEC_MOVMSK))]
15636 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15637 "%vmovmskpd\t{%1, %0|%0, %1}"
15638 [(set_attr "type" "ssemov")
15639 (set_attr "prefix" "maybe_vex")
15640 (set_attr "mode" "DF")])
15641
15642 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15643 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15644 (define_expand "signbitdf2"
15645 [(use (match_operand:SI 0 "register_operand" ""))
15646 (use (match_operand:DF 1 "register_operand" ""))]
15647 "TARGET_USE_FANCY_MATH_387
15648 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15649 {
15650 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15651 {
15652 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15653 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15654 }
15655 else
15656 {
15657 rtx scratch = gen_reg_rtx (HImode);
15658
15659 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15660 emit_insn (gen_andsi3 (operands[0],
15661 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15662 }
15663 DONE;
15664 })
15665
15666 (define_expand "signbitsf2"
15667 [(use (match_operand:SI 0 "register_operand" ""))
15668 (use (match_operand:SF 1 "register_operand" ""))]
15669 "TARGET_USE_FANCY_MATH_387
15670 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15671 {
15672 rtx scratch = gen_reg_rtx (HImode);
15673
15674 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15675 emit_insn (gen_andsi3 (operands[0],
15676 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15677 DONE;
15678 })
15679 \f
15680 ;; Block operation instructions
15681
15682 (define_insn "cld"
15683 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15684 ""
15685 "cld"
15686 [(set_attr "length" "1")
15687 (set_attr "length_immediate" "0")
15688 (set_attr "modrm" "0")])
15689
15690 (define_expand "movmem<mode>"
15691 [(use (match_operand:BLK 0 "memory_operand" ""))
15692 (use (match_operand:BLK 1 "memory_operand" ""))
15693 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15694 (use (match_operand:SWI48 3 "const_int_operand" ""))
15695 (use (match_operand:SI 4 "const_int_operand" ""))
15696 (use (match_operand:SI 5 "const_int_operand" ""))]
15697 ""
15698 {
15699 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15700 operands[4], operands[5]))
15701 DONE;
15702 else
15703 FAIL;
15704 })
15705
15706 ;; Most CPUs don't like single string operations
15707 ;; Handle this case here to simplify previous expander.
15708
15709 (define_expand "strmov"
15710 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15711 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15712 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15713 (clobber (reg:CC FLAGS_REG))])
15714 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15715 (clobber (reg:CC FLAGS_REG))])]
15716 ""
15717 {
15718 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15719
15720 /* If .md ever supports :P for Pmode, these can be directly
15721 in the pattern above. */
15722 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15723 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15724
15725 /* Can't use this if the user has appropriated esi or edi. */
15726 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15727 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15728 {
15729 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15730 operands[2], operands[3],
15731 operands[5], operands[6]));
15732 DONE;
15733 }
15734
15735 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15736 })
15737
15738 (define_expand "strmov_singleop"
15739 [(parallel [(set (match_operand 1 "memory_operand" "")
15740 (match_operand 3 "memory_operand" ""))
15741 (set (match_operand 0 "register_operand" "")
15742 (match_operand 4 "" ""))
15743 (set (match_operand 2 "register_operand" "")
15744 (match_operand 5 "" ""))])]
15745 ""
15746 "ix86_current_function_needs_cld = 1;")
15747
15748 (define_insn "*strmovdi_rex_1"
15749 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15750 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15751 (set (match_operand:DI 0 "register_operand" "=D")
15752 (plus:DI (match_dup 2)
15753 (const_int 8)))
15754 (set (match_operand:DI 1 "register_operand" "=S")
15755 (plus:DI (match_dup 3)
15756 (const_int 8)))]
15757 "TARGET_64BIT
15758 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15759 "movsq"
15760 [(set_attr "type" "str")
15761 (set_attr "memory" "both")
15762 (set_attr "mode" "DI")])
15763
15764 (define_insn "*strmovsi_1"
15765 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15766 (mem:SI (match_operand:P 3 "register_operand" "1")))
15767 (set (match_operand:P 0 "register_operand" "=D")
15768 (plus:P (match_dup 2)
15769 (const_int 4)))
15770 (set (match_operand:P 1 "register_operand" "=S")
15771 (plus:P (match_dup 3)
15772 (const_int 4)))]
15773 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15774 "movs{l|d}"
15775 [(set_attr "type" "str")
15776 (set_attr "memory" "both")
15777 (set_attr "mode" "SI")])
15778
15779 (define_insn "*strmovhi_1"
15780 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15781 (mem:HI (match_operand:P 3 "register_operand" "1")))
15782 (set (match_operand:P 0 "register_operand" "=D")
15783 (plus:P (match_dup 2)
15784 (const_int 2)))
15785 (set (match_operand:P 1 "register_operand" "=S")
15786 (plus:P (match_dup 3)
15787 (const_int 2)))]
15788 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15789 "movsw"
15790 [(set_attr "type" "str")
15791 (set_attr "memory" "both")
15792 (set_attr "mode" "HI")])
15793
15794 (define_insn "*strmovqi_1"
15795 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15796 (mem:QI (match_operand:P 3 "register_operand" "1")))
15797 (set (match_operand:P 0 "register_operand" "=D")
15798 (plus:P (match_dup 2)
15799 (const_int 1)))
15800 (set (match_operand:P 1 "register_operand" "=S")
15801 (plus:P (match_dup 3)
15802 (const_int 1)))]
15803 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15804 "movsb"
15805 [(set_attr "type" "str")
15806 (set_attr "memory" "both")
15807 (set (attr "prefix_rex")
15808 (if_then_else
15809 (match_test "<P:MODE>mode == DImode")
15810 (const_string "0")
15811 (const_string "*")))
15812 (set_attr "mode" "QI")])
15813
15814 (define_expand "rep_mov"
15815 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15816 (set (match_operand 0 "register_operand" "")
15817 (match_operand 5 "" ""))
15818 (set (match_operand 2 "register_operand" "")
15819 (match_operand 6 "" ""))
15820 (set (match_operand 1 "memory_operand" "")
15821 (match_operand 3 "memory_operand" ""))
15822 (use (match_dup 4))])]
15823 ""
15824 "ix86_current_function_needs_cld = 1;")
15825
15826 (define_insn "*rep_movdi_rex64"
15827 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15828 (set (match_operand:DI 0 "register_operand" "=D")
15829 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15830 (const_int 3))
15831 (match_operand:DI 3 "register_operand" "0")))
15832 (set (match_operand:DI 1 "register_operand" "=S")
15833 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15834 (match_operand:DI 4 "register_operand" "1")))
15835 (set (mem:BLK (match_dup 3))
15836 (mem:BLK (match_dup 4)))
15837 (use (match_dup 5))]
15838 "TARGET_64BIT
15839 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15840 "rep{%;} movsq"
15841 [(set_attr "type" "str")
15842 (set_attr "prefix_rep" "1")
15843 (set_attr "memory" "both")
15844 (set_attr "mode" "DI")])
15845
15846 (define_insn "*rep_movsi"
15847 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15848 (set (match_operand:P 0 "register_operand" "=D")
15849 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15850 (const_int 2))
15851 (match_operand:P 3 "register_operand" "0")))
15852 (set (match_operand:P 1 "register_operand" "=S")
15853 (plus:P (ashift:P (match_dup 5) (const_int 2))
15854 (match_operand:P 4 "register_operand" "1")))
15855 (set (mem:BLK (match_dup 3))
15856 (mem:BLK (match_dup 4)))
15857 (use (match_dup 5))]
15858 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15859 "rep{%;} movs{l|d}"
15860 [(set_attr "type" "str")
15861 (set_attr "prefix_rep" "1")
15862 (set_attr "memory" "both")
15863 (set_attr "mode" "SI")])
15864
15865 (define_insn "*rep_movqi"
15866 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15867 (set (match_operand:P 0 "register_operand" "=D")
15868 (plus:P (match_operand:P 3 "register_operand" "0")
15869 (match_operand:P 5 "register_operand" "2")))
15870 (set (match_operand:P 1 "register_operand" "=S")
15871 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15872 (set (mem:BLK (match_dup 3))
15873 (mem:BLK (match_dup 4)))
15874 (use (match_dup 5))]
15875 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15876 "rep{%;} movsb"
15877 [(set_attr "type" "str")
15878 (set_attr "prefix_rep" "1")
15879 (set_attr "memory" "both")
15880 (set_attr "mode" "QI")])
15881
15882 (define_expand "setmem<mode>"
15883 [(use (match_operand:BLK 0 "memory_operand" ""))
15884 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15885 (use (match_operand:QI 2 "nonmemory_operand" ""))
15886 (use (match_operand 3 "const_int_operand" ""))
15887 (use (match_operand:SI 4 "const_int_operand" ""))
15888 (use (match_operand:SI 5 "const_int_operand" ""))]
15889 ""
15890 {
15891 if (ix86_expand_setmem (operands[0], operands[1],
15892 operands[2], operands[3],
15893 operands[4], operands[5]))
15894 DONE;
15895 else
15896 FAIL;
15897 })
15898
15899 ;; Most CPUs don't like single string operations
15900 ;; Handle this case here to simplify previous expander.
15901
15902 (define_expand "strset"
15903 [(set (match_operand 1 "memory_operand" "")
15904 (match_operand 2 "register_operand" ""))
15905 (parallel [(set (match_operand 0 "register_operand" "")
15906 (match_dup 3))
15907 (clobber (reg:CC FLAGS_REG))])]
15908 ""
15909 {
15910 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15911 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15912
15913 /* If .md ever supports :P for Pmode, this can be directly
15914 in the pattern above. */
15915 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15916 GEN_INT (GET_MODE_SIZE (GET_MODE
15917 (operands[2]))));
15918 /* Can't use this if the user has appropriated eax or edi. */
15919 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15920 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15921 {
15922 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15923 operands[3]));
15924 DONE;
15925 }
15926 })
15927
15928 (define_expand "strset_singleop"
15929 [(parallel [(set (match_operand 1 "memory_operand" "")
15930 (match_operand 2 "register_operand" ""))
15931 (set (match_operand 0 "register_operand" "")
15932 (match_operand 3 "" ""))])]
15933 ""
15934 "ix86_current_function_needs_cld = 1;")
15935
15936 (define_insn "*strsetdi_rex_1"
15937 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15938 (match_operand:DI 2 "register_operand" "a"))
15939 (set (match_operand:DI 0 "register_operand" "=D")
15940 (plus:DI (match_dup 1)
15941 (const_int 8)))]
15942 "TARGET_64BIT
15943 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15944 "stosq"
15945 [(set_attr "type" "str")
15946 (set_attr "memory" "store")
15947 (set_attr "mode" "DI")])
15948
15949 (define_insn "*strsetsi_1"
15950 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15951 (match_operand:SI 2 "register_operand" "a"))
15952 (set (match_operand:P 0 "register_operand" "=D")
15953 (plus:P (match_dup 1)
15954 (const_int 4)))]
15955 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15956 "stos{l|d}"
15957 [(set_attr "type" "str")
15958 (set_attr "memory" "store")
15959 (set_attr "mode" "SI")])
15960
15961 (define_insn "*strsethi_1"
15962 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15963 (match_operand:HI 2 "register_operand" "a"))
15964 (set (match_operand:P 0 "register_operand" "=D")
15965 (plus:P (match_dup 1)
15966 (const_int 2)))]
15967 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15968 "stosw"
15969 [(set_attr "type" "str")
15970 (set_attr "memory" "store")
15971 (set_attr "mode" "HI")])
15972
15973 (define_insn "*strsetqi_1"
15974 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15975 (match_operand:QI 2 "register_operand" "a"))
15976 (set (match_operand:P 0 "register_operand" "=D")
15977 (plus:P (match_dup 1)
15978 (const_int 1)))]
15979 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15980 "stosb"
15981 [(set_attr "type" "str")
15982 (set_attr "memory" "store")
15983 (set (attr "prefix_rex")
15984 (if_then_else
15985 (match_test "<P:MODE>mode == DImode")
15986 (const_string "0")
15987 (const_string "*")))
15988 (set_attr "mode" "QI")])
15989
15990 (define_expand "rep_stos"
15991 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15992 (set (match_operand 0 "register_operand" "")
15993 (match_operand 4 "" ""))
15994 (set (match_operand 2 "memory_operand" "") (const_int 0))
15995 (use (match_operand 3 "register_operand" ""))
15996 (use (match_dup 1))])]
15997 ""
15998 "ix86_current_function_needs_cld = 1;")
15999
16000 (define_insn "*rep_stosdi_rex64"
16001 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16002 (set (match_operand:DI 0 "register_operand" "=D")
16003 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16004 (const_int 3))
16005 (match_operand:DI 3 "register_operand" "0")))
16006 (set (mem:BLK (match_dup 3))
16007 (const_int 0))
16008 (use (match_operand:DI 2 "register_operand" "a"))
16009 (use (match_dup 4))]
16010 "TARGET_64BIT
16011 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16012 "rep{%;} stosq"
16013 [(set_attr "type" "str")
16014 (set_attr "prefix_rep" "1")
16015 (set_attr "memory" "store")
16016 (set_attr "mode" "DI")])
16017
16018 (define_insn "*rep_stossi"
16019 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16020 (set (match_operand:P 0 "register_operand" "=D")
16021 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16022 (const_int 2))
16023 (match_operand:P 3 "register_operand" "0")))
16024 (set (mem:BLK (match_dup 3))
16025 (const_int 0))
16026 (use (match_operand:SI 2 "register_operand" "a"))
16027 (use (match_dup 4))]
16028 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16029 "rep{%;} stos{l|d}"
16030 [(set_attr "type" "str")
16031 (set_attr "prefix_rep" "1")
16032 (set_attr "memory" "store")
16033 (set_attr "mode" "SI")])
16034
16035 (define_insn "*rep_stosqi"
16036 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16037 (set (match_operand:P 0 "register_operand" "=D")
16038 (plus:P (match_operand:P 3 "register_operand" "0")
16039 (match_operand:P 4 "register_operand" "1")))
16040 (set (mem:BLK (match_dup 3))
16041 (const_int 0))
16042 (use (match_operand:QI 2 "register_operand" "a"))
16043 (use (match_dup 4))]
16044 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16045 "rep{%;} stosb"
16046 [(set_attr "type" "str")
16047 (set_attr "prefix_rep" "1")
16048 (set_attr "memory" "store")
16049 (set (attr "prefix_rex")
16050 (if_then_else
16051 (match_test "<P:MODE>mode == DImode")
16052 (const_string "0")
16053 (const_string "*")))
16054 (set_attr "mode" "QI")])
16055
16056 (define_expand "cmpstrnsi"
16057 [(set (match_operand:SI 0 "register_operand" "")
16058 (compare:SI (match_operand:BLK 1 "general_operand" "")
16059 (match_operand:BLK 2 "general_operand" "")))
16060 (use (match_operand 3 "general_operand" ""))
16061 (use (match_operand 4 "immediate_operand" ""))]
16062 ""
16063 {
16064 rtx addr1, addr2, out, outlow, count, countreg, align;
16065
16066 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16067 FAIL;
16068
16069 /* Can't use this if the user has appropriated ecx, esi or edi. */
16070 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16071 FAIL;
16072
16073 out = operands[0];
16074 if (!REG_P (out))
16075 out = gen_reg_rtx (SImode);
16076
16077 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16078 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16079 if (addr1 != XEXP (operands[1], 0))
16080 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16081 if (addr2 != XEXP (operands[2], 0))
16082 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16083
16084 count = operands[3];
16085 countreg = ix86_zero_extend_to_Pmode (count);
16086
16087 /* %%% Iff we are testing strict equality, we can use known alignment
16088 to good advantage. This may be possible with combine, particularly
16089 once cc0 is dead. */
16090 align = operands[4];
16091
16092 if (CONST_INT_P (count))
16093 {
16094 if (INTVAL (count) == 0)
16095 {
16096 emit_move_insn (operands[0], const0_rtx);
16097 DONE;
16098 }
16099 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16100 operands[1], operands[2]));
16101 }
16102 else
16103 {
16104 rtx (*gen_cmp) (rtx, rtx);
16105
16106 gen_cmp = (TARGET_64BIT
16107 ? gen_cmpdi_1 : gen_cmpsi_1);
16108
16109 emit_insn (gen_cmp (countreg, countreg));
16110 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16111 operands[1], operands[2]));
16112 }
16113
16114 outlow = gen_lowpart (QImode, out);
16115 emit_insn (gen_cmpintqi (outlow));
16116 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16117
16118 if (operands[0] != out)
16119 emit_move_insn (operands[0], out);
16120
16121 DONE;
16122 })
16123
16124 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16125
16126 (define_expand "cmpintqi"
16127 [(set (match_dup 1)
16128 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16129 (set (match_dup 2)
16130 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16131 (parallel [(set (match_operand:QI 0 "register_operand" "")
16132 (minus:QI (match_dup 1)
16133 (match_dup 2)))
16134 (clobber (reg:CC FLAGS_REG))])]
16135 ""
16136 {
16137 operands[1] = gen_reg_rtx (QImode);
16138 operands[2] = gen_reg_rtx (QImode);
16139 })
16140
16141 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16142 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16143
16144 (define_expand "cmpstrnqi_nz_1"
16145 [(parallel [(set (reg:CC FLAGS_REG)
16146 (compare:CC (match_operand 4 "memory_operand" "")
16147 (match_operand 5 "memory_operand" "")))
16148 (use (match_operand 2 "register_operand" ""))
16149 (use (match_operand:SI 3 "immediate_operand" ""))
16150 (clobber (match_operand 0 "register_operand" ""))
16151 (clobber (match_operand 1 "register_operand" ""))
16152 (clobber (match_dup 2))])]
16153 ""
16154 "ix86_current_function_needs_cld = 1;")
16155
16156 (define_insn "*cmpstrnqi_nz_1"
16157 [(set (reg:CC FLAGS_REG)
16158 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16159 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16160 (use (match_operand:P 6 "register_operand" "2"))
16161 (use (match_operand:SI 3 "immediate_operand" "i"))
16162 (clobber (match_operand:P 0 "register_operand" "=S"))
16163 (clobber (match_operand:P 1 "register_operand" "=D"))
16164 (clobber (match_operand:P 2 "register_operand" "=c"))]
16165 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16166 "repz{%;} cmpsb"
16167 [(set_attr "type" "str")
16168 (set_attr "mode" "QI")
16169 (set (attr "prefix_rex")
16170 (if_then_else
16171 (match_test "<P:MODE>mode == DImode")
16172 (const_string "0")
16173 (const_string "*")))
16174 (set_attr "prefix_rep" "1")])
16175
16176 ;; The same, but the count is not known to not be zero.
16177
16178 (define_expand "cmpstrnqi_1"
16179 [(parallel [(set (reg:CC FLAGS_REG)
16180 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16181 (const_int 0))
16182 (compare:CC (match_operand 4 "memory_operand" "")
16183 (match_operand 5 "memory_operand" ""))
16184 (const_int 0)))
16185 (use (match_operand:SI 3 "immediate_operand" ""))
16186 (use (reg:CC FLAGS_REG))
16187 (clobber (match_operand 0 "register_operand" ""))
16188 (clobber (match_operand 1 "register_operand" ""))
16189 (clobber (match_dup 2))])]
16190 ""
16191 "ix86_current_function_needs_cld = 1;")
16192
16193 (define_insn "*cmpstrnqi_1"
16194 [(set (reg:CC FLAGS_REG)
16195 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16196 (const_int 0))
16197 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16198 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16199 (const_int 0)))
16200 (use (match_operand:SI 3 "immediate_operand" "i"))
16201 (use (reg:CC FLAGS_REG))
16202 (clobber (match_operand:P 0 "register_operand" "=S"))
16203 (clobber (match_operand:P 1 "register_operand" "=D"))
16204 (clobber (match_operand:P 2 "register_operand" "=c"))]
16205 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16206 "repz{%;} cmpsb"
16207 [(set_attr "type" "str")
16208 (set_attr "mode" "QI")
16209 (set (attr "prefix_rex")
16210 (if_then_else
16211 (match_test "<P:MODE>mode == DImode")
16212 (const_string "0")
16213 (const_string "*")))
16214 (set_attr "prefix_rep" "1")])
16215
16216 (define_expand "strlen<mode>"
16217 [(set (match_operand:P 0 "register_operand" "")
16218 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16219 (match_operand:QI 2 "immediate_operand" "")
16220 (match_operand 3 "immediate_operand" "")]
16221 UNSPEC_SCAS))]
16222 ""
16223 {
16224 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16225 DONE;
16226 else
16227 FAIL;
16228 })
16229
16230 (define_expand "strlenqi_1"
16231 [(parallel [(set (match_operand 0 "register_operand" "")
16232 (match_operand 2 "" ""))
16233 (clobber (match_operand 1 "register_operand" ""))
16234 (clobber (reg:CC FLAGS_REG))])]
16235 ""
16236 "ix86_current_function_needs_cld = 1;")
16237
16238 (define_insn "*strlenqi_1"
16239 [(set (match_operand:P 0 "register_operand" "=&c")
16240 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16241 (match_operand:QI 2 "register_operand" "a")
16242 (match_operand:P 3 "immediate_operand" "i")
16243 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16244 (clobber (match_operand:P 1 "register_operand" "=D"))
16245 (clobber (reg:CC FLAGS_REG))]
16246 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16247 "repnz{%;} scasb"
16248 [(set_attr "type" "str")
16249 (set_attr "mode" "QI")
16250 (set (attr "prefix_rex")
16251 (if_then_else
16252 (match_test "<P:MODE>mode == DImode")
16253 (const_string "0")
16254 (const_string "*")))
16255 (set_attr "prefix_rep" "1")])
16256
16257 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16258 ;; handled in combine, but it is not currently up to the task.
16259 ;; When used for their truth value, the cmpstrn* expanders generate
16260 ;; code like this:
16261 ;;
16262 ;; repz cmpsb
16263 ;; seta %al
16264 ;; setb %dl
16265 ;; cmpb %al, %dl
16266 ;; jcc label
16267 ;;
16268 ;; The intermediate three instructions are unnecessary.
16269
16270 ;; This one handles cmpstrn*_nz_1...
16271 (define_peephole2
16272 [(parallel[
16273 (set (reg:CC FLAGS_REG)
16274 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16275 (mem:BLK (match_operand 5 "register_operand" ""))))
16276 (use (match_operand 6 "register_operand" ""))
16277 (use (match_operand:SI 3 "immediate_operand" ""))
16278 (clobber (match_operand 0 "register_operand" ""))
16279 (clobber (match_operand 1 "register_operand" ""))
16280 (clobber (match_operand 2 "register_operand" ""))])
16281 (set (match_operand:QI 7 "register_operand" "")
16282 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16283 (set (match_operand:QI 8 "register_operand" "")
16284 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16285 (set (reg FLAGS_REG)
16286 (compare (match_dup 7) (match_dup 8)))
16287 ]
16288 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16289 [(parallel[
16290 (set (reg:CC FLAGS_REG)
16291 (compare:CC (mem:BLK (match_dup 4))
16292 (mem:BLK (match_dup 5))))
16293 (use (match_dup 6))
16294 (use (match_dup 3))
16295 (clobber (match_dup 0))
16296 (clobber (match_dup 1))
16297 (clobber (match_dup 2))])])
16298
16299 ;; ...and this one handles cmpstrn*_1.
16300 (define_peephole2
16301 [(parallel[
16302 (set (reg:CC FLAGS_REG)
16303 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16304 (const_int 0))
16305 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16306 (mem:BLK (match_operand 5 "register_operand" "")))
16307 (const_int 0)))
16308 (use (match_operand:SI 3 "immediate_operand" ""))
16309 (use (reg:CC FLAGS_REG))
16310 (clobber (match_operand 0 "register_operand" ""))
16311 (clobber (match_operand 1 "register_operand" ""))
16312 (clobber (match_operand 2 "register_operand" ""))])
16313 (set (match_operand:QI 7 "register_operand" "")
16314 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16315 (set (match_operand:QI 8 "register_operand" "")
16316 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16317 (set (reg FLAGS_REG)
16318 (compare (match_dup 7) (match_dup 8)))
16319 ]
16320 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16321 [(parallel[
16322 (set (reg:CC FLAGS_REG)
16323 (if_then_else:CC (ne (match_dup 6)
16324 (const_int 0))
16325 (compare:CC (mem:BLK (match_dup 4))
16326 (mem:BLK (match_dup 5)))
16327 (const_int 0)))
16328 (use (match_dup 3))
16329 (use (reg:CC FLAGS_REG))
16330 (clobber (match_dup 0))
16331 (clobber (match_dup 1))
16332 (clobber (match_dup 2))])])
16333 \f
16334 ;; Conditional move instructions.
16335
16336 (define_expand "mov<mode>cc"
16337 [(set (match_operand:SWIM 0 "register_operand" "")
16338 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16339 (match_operand:SWIM 2 "<general_operand>" "")
16340 (match_operand:SWIM 3 "<general_operand>" "")))]
16341 ""
16342 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16343
16344 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16345 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16346 ;; So just document what we're doing explicitly.
16347
16348 (define_expand "x86_mov<mode>cc_0_m1"
16349 [(parallel
16350 [(set (match_operand:SWI48 0 "register_operand" "")
16351 (if_then_else:SWI48
16352 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16353 [(match_operand 1 "flags_reg_operand" "")
16354 (const_int 0)])
16355 (const_int -1)
16356 (const_int 0)))
16357 (clobber (reg:CC FLAGS_REG))])])
16358
16359 (define_insn "*x86_mov<mode>cc_0_m1"
16360 [(set (match_operand:SWI48 0 "register_operand" "=r")
16361 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16362 [(reg FLAGS_REG) (const_int 0)])
16363 (const_int -1)
16364 (const_int 0)))
16365 (clobber (reg:CC FLAGS_REG))]
16366 ""
16367 "sbb{<imodesuffix>}\t%0, %0"
16368 ; Since we don't have the proper number of operands for an alu insn,
16369 ; fill in all the blanks.
16370 [(set_attr "type" "alu")
16371 (set_attr "use_carry" "1")
16372 (set_attr "pent_pair" "pu")
16373 (set_attr "memory" "none")
16374 (set_attr "imm_disp" "false")
16375 (set_attr "mode" "<MODE>")
16376 (set_attr "length_immediate" "0")])
16377
16378 (define_insn "*x86_mov<mode>cc_0_m1_se"
16379 [(set (match_operand:SWI48 0 "register_operand" "=r")
16380 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16381 [(reg FLAGS_REG) (const_int 0)])
16382 (const_int 1)
16383 (const_int 0)))
16384 (clobber (reg:CC FLAGS_REG))]
16385 ""
16386 "sbb{<imodesuffix>}\t%0, %0"
16387 [(set_attr "type" "alu")
16388 (set_attr "use_carry" "1")
16389 (set_attr "pent_pair" "pu")
16390 (set_attr "memory" "none")
16391 (set_attr "imm_disp" "false")
16392 (set_attr "mode" "<MODE>")
16393 (set_attr "length_immediate" "0")])
16394
16395 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16396 [(set (match_operand:SWI48 0 "register_operand" "=r")
16397 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16398 [(reg FLAGS_REG) (const_int 0)])))]
16399 ""
16400 "sbb{<imodesuffix>}\t%0, %0"
16401 [(set_attr "type" "alu")
16402 (set_attr "use_carry" "1")
16403 (set_attr "pent_pair" "pu")
16404 (set_attr "memory" "none")
16405 (set_attr "imm_disp" "false")
16406 (set_attr "mode" "<MODE>")
16407 (set_attr "length_immediate" "0")])
16408
16409 (define_insn "*mov<mode>cc_noc"
16410 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16411 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16412 [(reg FLAGS_REG) (const_int 0)])
16413 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16414 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16415 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16416 "@
16417 cmov%O2%C1\t{%2, %0|%0, %2}
16418 cmov%O2%c1\t{%3, %0|%0, %3}"
16419 [(set_attr "type" "icmov")
16420 (set_attr "mode" "<MODE>")])
16421
16422 (define_insn_and_split "*movqicc_noc"
16423 [(set (match_operand:QI 0 "register_operand" "=r,r")
16424 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16425 [(match_operand 4 "flags_reg_operand" "")
16426 (const_int 0)])
16427 (match_operand:QI 2 "register_operand" "r,0")
16428 (match_operand:QI 3 "register_operand" "0,r")))]
16429 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16430 "#"
16431 "&& reload_completed"
16432 [(set (match_dup 0)
16433 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16434 (match_dup 2)
16435 (match_dup 3)))]
16436 "operands[0] = gen_lowpart (SImode, operands[0]);
16437 operands[2] = gen_lowpart (SImode, operands[2]);
16438 operands[3] = gen_lowpart (SImode, operands[3]);"
16439 [(set_attr "type" "icmov")
16440 (set_attr "mode" "SI")])
16441
16442 (define_expand "mov<mode>cc"
16443 [(set (match_operand:X87MODEF 0 "register_operand" "")
16444 (if_then_else:X87MODEF
16445 (match_operand 1 "ix86_fp_comparison_operator" "")
16446 (match_operand:X87MODEF 2 "register_operand" "")
16447 (match_operand:X87MODEF 3 "register_operand" "")))]
16448 "(TARGET_80387 && TARGET_CMOVE)
16449 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16450 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16451
16452 (define_insn "*movxfcc_1"
16453 [(set (match_operand:XF 0 "register_operand" "=f,f")
16454 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16455 [(reg FLAGS_REG) (const_int 0)])
16456 (match_operand:XF 2 "register_operand" "f,0")
16457 (match_operand:XF 3 "register_operand" "0,f")))]
16458 "TARGET_80387 && TARGET_CMOVE"
16459 "@
16460 fcmov%F1\t{%2, %0|%0, %2}
16461 fcmov%f1\t{%3, %0|%0, %3}"
16462 [(set_attr "type" "fcmov")
16463 (set_attr "mode" "XF")])
16464
16465 (define_insn "*movdfcc_1_rex64"
16466 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16467 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16468 [(reg FLAGS_REG) (const_int 0)])
16469 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16470 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16471 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16472 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16473 "@
16474 fcmov%F1\t{%2, %0|%0, %2}
16475 fcmov%f1\t{%3, %0|%0, %3}
16476 cmov%O2%C1\t{%2, %0|%0, %2}
16477 cmov%O2%c1\t{%3, %0|%0, %3}"
16478 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16479 (set_attr "mode" "DF,DF,DI,DI")])
16480
16481 (define_insn "*movdfcc_1"
16482 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16483 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16484 [(reg FLAGS_REG) (const_int 0)])
16485 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16486 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16487 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16488 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16489 "@
16490 fcmov%F1\t{%2, %0|%0, %2}
16491 fcmov%f1\t{%3, %0|%0, %3}
16492 #
16493 #"
16494 [(set_attr "type" "fcmov,fcmov,multi,multi")
16495 (set_attr "mode" "DF,DF,DI,DI")])
16496
16497 (define_split
16498 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16499 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16500 [(match_operand 4 "flags_reg_operand" "")
16501 (const_int 0)])
16502 (match_operand:DF 2 "nonimmediate_operand" "")
16503 (match_operand:DF 3 "nonimmediate_operand" "")))]
16504 "!TARGET_64BIT && reload_completed"
16505 [(set (match_dup 2)
16506 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16507 (match_dup 5)
16508 (match_dup 6)))
16509 (set (match_dup 3)
16510 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16511 (match_dup 7)
16512 (match_dup 8)))]
16513 {
16514 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16515 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16516 })
16517
16518 (define_insn "*movsfcc_1_387"
16519 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16520 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16521 [(reg FLAGS_REG) (const_int 0)])
16522 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16523 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16524 "TARGET_80387 && TARGET_CMOVE
16525 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16526 "@
16527 fcmov%F1\t{%2, %0|%0, %2}
16528 fcmov%f1\t{%3, %0|%0, %3}
16529 cmov%O2%C1\t{%2, %0|%0, %2}
16530 cmov%O2%c1\t{%3, %0|%0, %3}"
16531 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16532 (set_attr "mode" "SF,SF,SI,SI")])
16533
16534 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16535 ;; the scalar versions to have only XMM registers as operands.
16536
16537 ;; XOP conditional move
16538 (define_insn "*xop_pcmov_<mode>"
16539 [(set (match_operand:MODEF 0 "register_operand" "=x")
16540 (if_then_else:MODEF
16541 (match_operand:MODEF 1 "register_operand" "x")
16542 (match_operand:MODEF 2 "register_operand" "x")
16543 (match_operand:MODEF 3 "register_operand" "x")))]
16544 "TARGET_XOP"
16545 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16546 [(set_attr "type" "sse4arg")])
16547
16548 ;; These versions of the min/max patterns are intentionally ignorant of
16549 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16550 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16551 ;; are undefined in this condition, we're certain this is correct.
16552
16553 (define_insn "<code><mode>3"
16554 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16555 (smaxmin:MODEF
16556 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16557 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16558 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16559 "@
16560 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16561 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16562 [(set_attr "isa" "noavx,avx")
16563 (set_attr "prefix" "orig,vex")
16564 (set_attr "type" "sseadd")
16565 (set_attr "mode" "<MODE>")])
16566
16567 ;; These versions of the min/max patterns implement exactly the operations
16568 ;; min = (op1 < op2 ? op1 : op2)
16569 ;; max = (!(op1 < op2) ? op1 : op2)
16570 ;; Their operands are not commutative, and thus they may be used in the
16571 ;; presence of -0.0 and NaN.
16572
16573 (define_insn "*ieee_smin<mode>3"
16574 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16575 (unspec:MODEF
16576 [(match_operand:MODEF 1 "register_operand" "0,x")
16577 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16578 UNSPEC_IEEE_MIN))]
16579 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16580 "@
16581 min<ssemodesuffix>\t{%2, %0|%0, %2}
16582 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16583 [(set_attr "isa" "noavx,avx")
16584 (set_attr "prefix" "orig,vex")
16585 (set_attr "type" "sseadd")
16586 (set_attr "mode" "<MODE>")])
16587
16588 (define_insn "*ieee_smax<mode>3"
16589 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16590 (unspec:MODEF
16591 [(match_operand:MODEF 1 "register_operand" "0,x")
16592 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16593 UNSPEC_IEEE_MAX))]
16594 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16595 "@
16596 max<ssemodesuffix>\t{%2, %0|%0, %2}
16597 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16598 [(set_attr "isa" "noavx,avx")
16599 (set_attr "prefix" "orig,vex")
16600 (set_attr "type" "sseadd")
16601 (set_attr "mode" "<MODE>")])
16602
16603 ;; Make two stack loads independent:
16604 ;; fld aa fld aa
16605 ;; fld %st(0) -> fld bb
16606 ;; fmul bb fmul %st(1), %st
16607 ;;
16608 ;; Actually we only match the last two instructions for simplicity.
16609 (define_peephole2
16610 [(set (match_operand 0 "fp_register_operand" "")
16611 (match_operand 1 "fp_register_operand" ""))
16612 (set (match_dup 0)
16613 (match_operator 2 "binary_fp_operator"
16614 [(match_dup 0)
16615 (match_operand 3 "memory_operand" "")]))]
16616 "REGNO (operands[0]) != REGNO (operands[1])"
16617 [(set (match_dup 0) (match_dup 3))
16618 (set (match_dup 0) (match_dup 4))]
16619
16620 ;; The % modifier is not operational anymore in peephole2's, so we have to
16621 ;; swap the operands manually in the case of addition and multiplication.
16622 "if (COMMUTATIVE_ARITH_P (operands[2]))
16623 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16624 GET_MODE (operands[2]),
16625 operands[0], operands[1]);
16626 else
16627 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16628 GET_MODE (operands[2]),
16629 operands[1], operands[0]);")
16630
16631 ;; Conditional addition patterns
16632 (define_expand "add<mode>cc"
16633 [(match_operand:SWI 0 "register_operand" "")
16634 (match_operand 1 "ordered_comparison_operator" "")
16635 (match_operand:SWI 2 "register_operand" "")
16636 (match_operand:SWI 3 "const_int_operand" "")]
16637 ""
16638 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16639 \f
16640 ;; Misc patterns (?)
16641
16642 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16643 ;; Otherwise there will be nothing to keep
16644 ;;
16645 ;; [(set (reg ebp) (reg esp))]
16646 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16647 ;; (clobber (eflags)]
16648 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16649 ;;
16650 ;; in proper program order.
16651
16652 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16653 [(set (match_operand:P 0 "register_operand" "=r,r")
16654 (plus:P (match_operand:P 1 "register_operand" "0,r")
16655 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16656 (clobber (reg:CC FLAGS_REG))
16657 (clobber (mem:BLK (scratch)))]
16658 ""
16659 {
16660 switch (get_attr_type (insn))
16661 {
16662 case TYPE_IMOV:
16663 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16664
16665 case TYPE_ALU:
16666 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16667 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16668 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16669
16670 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16671
16672 default:
16673 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16674 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16675 }
16676 }
16677 [(set (attr "type")
16678 (cond [(and (eq_attr "alternative" "0")
16679 (not (match_test "TARGET_OPT_AGU")))
16680 (const_string "alu")
16681 (match_operand:<MODE> 2 "const0_operand" "")
16682 (const_string "imov")
16683 ]
16684 (const_string "lea")))
16685 (set (attr "length_immediate")
16686 (cond [(eq_attr "type" "imov")
16687 (const_string "0")
16688 (and (eq_attr "type" "alu")
16689 (match_operand 2 "const128_operand" ""))
16690 (const_string "1")
16691 ]
16692 (const_string "*")))
16693 (set_attr "mode" "<MODE>")])
16694
16695 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16696 [(set (match_operand:P 0 "register_operand" "=r")
16697 (minus:P (match_operand:P 1 "register_operand" "0")
16698 (match_operand:P 2 "register_operand" "r")))
16699 (clobber (reg:CC FLAGS_REG))
16700 (clobber (mem:BLK (scratch)))]
16701 ""
16702 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16703 [(set_attr "type" "alu")
16704 (set_attr "mode" "<MODE>")])
16705
16706 (define_insn "allocate_stack_worker_probe_<mode>"
16707 [(set (match_operand:P 0 "register_operand" "=a")
16708 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16709 UNSPECV_STACK_PROBE))
16710 (clobber (reg:CC FLAGS_REG))]
16711 "ix86_target_stack_probe ()"
16712 "call\t___chkstk_ms"
16713 [(set_attr "type" "multi")
16714 (set_attr "length" "5")])
16715
16716 (define_expand "allocate_stack"
16717 [(match_operand 0 "register_operand" "")
16718 (match_operand 1 "general_operand" "")]
16719 "ix86_target_stack_probe ()"
16720 {
16721 rtx x;
16722
16723 #ifndef CHECK_STACK_LIMIT
16724 #define CHECK_STACK_LIMIT 0
16725 #endif
16726
16727 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16728 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16729 {
16730 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16731 stack_pointer_rtx, 0, OPTAB_DIRECT);
16732 if (x != stack_pointer_rtx)
16733 emit_move_insn (stack_pointer_rtx, x);
16734 }
16735 else
16736 {
16737 x = copy_to_mode_reg (Pmode, operands[1]);
16738 if (TARGET_64BIT)
16739 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16740 else
16741 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16742 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16743 stack_pointer_rtx, 0, OPTAB_DIRECT);
16744 if (x != stack_pointer_rtx)
16745 emit_move_insn (stack_pointer_rtx, x);
16746 }
16747
16748 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16749 DONE;
16750 })
16751
16752 ;; Use IOR for stack probes, this is shorter.
16753 (define_expand "probe_stack"
16754 [(match_operand 0 "memory_operand" "")]
16755 ""
16756 {
16757 rtx (*gen_ior3) (rtx, rtx, rtx);
16758
16759 gen_ior3 = (GET_MODE (operands[0]) == DImode
16760 ? gen_iordi3 : gen_iorsi3);
16761
16762 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16763 DONE;
16764 })
16765
16766 (define_insn "adjust_stack_and_probe<mode>"
16767 [(set (match_operand:P 0 "register_operand" "=r")
16768 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16769 UNSPECV_PROBE_STACK_RANGE))
16770 (set (reg:P SP_REG)
16771 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16772 (clobber (reg:CC FLAGS_REG))
16773 (clobber (mem:BLK (scratch)))]
16774 ""
16775 "* return output_adjust_stack_and_probe (operands[0]);"
16776 [(set_attr "type" "multi")])
16777
16778 (define_insn "probe_stack_range<mode>"
16779 [(set (match_operand:P 0 "register_operand" "=r")
16780 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16781 (match_operand:P 2 "const_int_operand" "n")]
16782 UNSPECV_PROBE_STACK_RANGE))
16783 (clobber (reg:CC FLAGS_REG))]
16784 ""
16785 "* return output_probe_stack_range (operands[0], operands[2]);"
16786 [(set_attr "type" "multi")])
16787
16788 (define_expand "builtin_setjmp_receiver"
16789 [(label_ref (match_operand 0 "" ""))]
16790 "!TARGET_64BIT && flag_pic"
16791 {
16792 #if TARGET_MACHO
16793 if (TARGET_MACHO)
16794 {
16795 rtx xops[3];
16796 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16797 rtx label_rtx = gen_label_rtx ();
16798 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16799 xops[0] = xops[1] = picreg;
16800 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16801 ix86_expand_binary_operator (MINUS, SImode, xops);
16802 }
16803 else
16804 #endif
16805 emit_insn (gen_set_got (pic_offset_table_rtx));
16806 DONE;
16807 })
16808 \f
16809 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16810
16811 (define_split
16812 [(set (match_operand 0 "register_operand" "")
16813 (match_operator 3 "promotable_binary_operator"
16814 [(match_operand 1 "register_operand" "")
16815 (match_operand 2 "aligned_operand" "")]))
16816 (clobber (reg:CC FLAGS_REG))]
16817 "! TARGET_PARTIAL_REG_STALL && reload_completed
16818 && ((GET_MODE (operands[0]) == HImode
16819 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16820 /* ??? next two lines just !satisfies_constraint_K (...) */
16821 || !CONST_INT_P (operands[2])
16822 || satisfies_constraint_K (operands[2])))
16823 || (GET_MODE (operands[0]) == QImode
16824 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16825 [(parallel [(set (match_dup 0)
16826 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16827 (clobber (reg:CC FLAGS_REG))])]
16828 "operands[0] = gen_lowpart (SImode, operands[0]);
16829 operands[1] = gen_lowpart (SImode, operands[1]);
16830 if (GET_CODE (operands[3]) != ASHIFT)
16831 operands[2] = gen_lowpart (SImode, operands[2]);
16832 PUT_MODE (operands[3], SImode);")
16833
16834 ; Promote the QImode tests, as i386 has encoding of the AND
16835 ; instruction with 32-bit sign-extended immediate and thus the
16836 ; instruction size is unchanged, except in the %eax case for
16837 ; which it is increased by one byte, hence the ! optimize_size.
16838 (define_split
16839 [(set (match_operand 0 "flags_reg_operand" "")
16840 (match_operator 2 "compare_operator"
16841 [(and (match_operand 3 "aligned_operand" "")
16842 (match_operand 4 "const_int_operand" ""))
16843 (const_int 0)]))
16844 (set (match_operand 1 "register_operand" "")
16845 (and (match_dup 3) (match_dup 4)))]
16846 "! TARGET_PARTIAL_REG_STALL && reload_completed
16847 && optimize_insn_for_speed_p ()
16848 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16849 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16850 /* Ensure that the operand will remain sign-extended immediate. */
16851 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16852 [(parallel [(set (match_dup 0)
16853 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16854 (const_int 0)]))
16855 (set (match_dup 1)
16856 (and:SI (match_dup 3) (match_dup 4)))])]
16857 {
16858 operands[4]
16859 = gen_int_mode (INTVAL (operands[4])
16860 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16861 operands[1] = gen_lowpart (SImode, operands[1]);
16862 operands[3] = gen_lowpart (SImode, operands[3]);
16863 })
16864
16865 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16866 ; the TEST instruction with 32-bit sign-extended immediate and thus
16867 ; the instruction size would at least double, which is not what we
16868 ; want even with ! optimize_size.
16869 (define_split
16870 [(set (match_operand 0 "flags_reg_operand" "")
16871 (match_operator 1 "compare_operator"
16872 [(and (match_operand:HI 2 "aligned_operand" "")
16873 (match_operand:HI 3 "const_int_operand" ""))
16874 (const_int 0)]))]
16875 "! TARGET_PARTIAL_REG_STALL && reload_completed
16876 && ! TARGET_FAST_PREFIX
16877 && optimize_insn_for_speed_p ()
16878 /* Ensure that the operand will remain sign-extended immediate. */
16879 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16880 [(set (match_dup 0)
16881 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16882 (const_int 0)]))]
16883 {
16884 operands[3]
16885 = gen_int_mode (INTVAL (operands[3])
16886 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16887 operands[2] = gen_lowpart (SImode, operands[2]);
16888 })
16889
16890 (define_split
16891 [(set (match_operand 0 "register_operand" "")
16892 (neg (match_operand 1 "register_operand" "")))
16893 (clobber (reg:CC FLAGS_REG))]
16894 "! TARGET_PARTIAL_REG_STALL && reload_completed
16895 && (GET_MODE (operands[0]) == HImode
16896 || (GET_MODE (operands[0]) == QImode
16897 && (TARGET_PROMOTE_QImode
16898 || optimize_insn_for_size_p ())))"
16899 [(parallel [(set (match_dup 0)
16900 (neg:SI (match_dup 1)))
16901 (clobber (reg:CC FLAGS_REG))])]
16902 "operands[0] = gen_lowpart (SImode, operands[0]);
16903 operands[1] = gen_lowpart (SImode, operands[1]);")
16904
16905 (define_split
16906 [(set (match_operand 0 "register_operand" "")
16907 (not (match_operand 1 "register_operand" "")))]
16908 "! TARGET_PARTIAL_REG_STALL && reload_completed
16909 && (GET_MODE (operands[0]) == HImode
16910 || (GET_MODE (operands[0]) == QImode
16911 && (TARGET_PROMOTE_QImode
16912 || optimize_insn_for_size_p ())))"
16913 [(set (match_dup 0)
16914 (not:SI (match_dup 1)))]
16915 "operands[0] = gen_lowpart (SImode, operands[0]);
16916 operands[1] = gen_lowpart (SImode, operands[1]);")
16917
16918 (define_split
16919 [(set (match_operand 0 "register_operand" "")
16920 (if_then_else (match_operator 1 "ordered_comparison_operator"
16921 [(reg FLAGS_REG) (const_int 0)])
16922 (match_operand 2 "register_operand" "")
16923 (match_operand 3 "register_operand" "")))]
16924 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16925 && (GET_MODE (operands[0]) == HImode
16926 || (GET_MODE (operands[0]) == QImode
16927 && (TARGET_PROMOTE_QImode
16928 || optimize_insn_for_size_p ())))"
16929 [(set (match_dup 0)
16930 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16931 "operands[0] = gen_lowpart (SImode, operands[0]);
16932 operands[2] = gen_lowpart (SImode, operands[2]);
16933 operands[3] = gen_lowpart (SImode, operands[3]);")
16934 \f
16935 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16936 ;; transform a complex memory operation into two memory to register operations.
16937
16938 ;; Don't push memory operands
16939 (define_peephole2
16940 [(set (match_operand:SWI 0 "push_operand" "")
16941 (match_operand:SWI 1 "memory_operand" ""))
16942 (match_scratch:SWI 2 "<r>")]
16943 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16944 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16945 [(set (match_dup 2) (match_dup 1))
16946 (set (match_dup 0) (match_dup 2))])
16947
16948 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16949 ;; SImode pushes.
16950 (define_peephole2
16951 [(set (match_operand:SF 0 "push_operand" "")
16952 (match_operand:SF 1 "memory_operand" ""))
16953 (match_scratch:SF 2 "r")]
16954 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16955 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16956 [(set (match_dup 2) (match_dup 1))
16957 (set (match_dup 0) (match_dup 2))])
16958
16959 ;; Don't move an immediate directly to memory when the instruction
16960 ;; gets too big.
16961 (define_peephole2
16962 [(match_scratch:SWI124 1 "<r>")
16963 (set (match_operand:SWI124 0 "memory_operand" "")
16964 (const_int 0))]
16965 "optimize_insn_for_speed_p ()
16966 && !TARGET_USE_MOV0
16967 && TARGET_SPLIT_LONG_MOVES
16968 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16969 && peep2_regno_dead_p (0, FLAGS_REG)"
16970 [(parallel [(set (match_dup 2) (const_int 0))
16971 (clobber (reg:CC FLAGS_REG))])
16972 (set (match_dup 0) (match_dup 1))]
16973 "operands[2] = gen_lowpart (SImode, operands[1]);")
16974
16975 (define_peephole2
16976 [(match_scratch:SWI124 2 "<r>")
16977 (set (match_operand:SWI124 0 "memory_operand" "")
16978 (match_operand:SWI124 1 "immediate_operand" ""))]
16979 "optimize_insn_for_speed_p ()
16980 && TARGET_SPLIT_LONG_MOVES
16981 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16982 [(set (match_dup 2) (match_dup 1))
16983 (set (match_dup 0) (match_dup 2))])
16984
16985 ;; Don't compare memory with zero, load and use a test instead.
16986 (define_peephole2
16987 [(set (match_operand 0 "flags_reg_operand" "")
16988 (match_operator 1 "compare_operator"
16989 [(match_operand:SI 2 "memory_operand" "")
16990 (const_int 0)]))
16991 (match_scratch:SI 3 "r")]
16992 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16993 [(set (match_dup 3) (match_dup 2))
16994 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16995
16996 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16997 ;; Don't split NOTs with a displacement operand, because resulting XOR
16998 ;; will not be pairable anyway.
16999 ;;
17000 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17001 ;; represented using a modRM byte. The XOR replacement is long decoded,
17002 ;; so this split helps here as well.
17003 ;;
17004 ;; Note: Can't do this as a regular split because we can't get proper
17005 ;; lifetime information then.
17006
17007 (define_peephole2
17008 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17009 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17010 "optimize_insn_for_speed_p ()
17011 && ((TARGET_NOT_UNPAIRABLE
17012 && (!MEM_P (operands[0])
17013 || !memory_displacement_operand (operands[0], <MODE>mode)))
17014 || (TARGET_NOT_VECTORMODE
17015 && long_memory_operand (operands[0], <MODE>mode)))
17016 && peep2_regno_dead_p (0, FLAGS_REG)"
17017 [(parallel [(set (match_dup 0)
17018 (xor:SWI124 (match_dup 1) (const_int -1)))
17019 (clobber (reg:CC FLAGS_REG))])])
17020
17021 ;; Non pairable "test imm, reg" instructions can be translated to
17022 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17023 ;; byte opcode instead of two, have a short form for byte operands),
17024 ;; so do it for other CPUs as well. Given that the value was dead,
17025 ;; this should not create any new dependencies. Pass on the sub-word
17026 ;; versions if we're concerned about partial register stalls.
17027
17028 (define_peephole2
17029 [(set (match_operand 0 "flags_reg_operand" "")
17030 (match_operator 1 "compare_operator"
17031 [(and:SI (match_operand:SI 2 "register_operand" "")
17032 (match_operand:SI 3 "immediate_operand" ""))
17033 (const_int 0)]))]
17034 "ix86_match_ccmode (insn, CCNOmode)
17035 && (true_regnum (operands[2]) != AX_REG
17036 || satisfies_constraint_K (operands[3]))
17037 && peep2_reg_dead_p (1, operands[2])"
17038 [(parallel
17039 [(set (match_dup 0)
17040 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17041 (const_int 0)]))
17042 (set (match_dup 2)
17043 (and:SI (match_dup 2) (match_dup 3)))])])
17044
17045 ;; We don't need to handle HImode case, because it will be promoted to SImode
17046 ;; on ! TARGET_PARTIAL_REG_STALL
17047
17048 (define_peephole2
17049 [(set (match_operand 0 "flags_reg_operand" "")
17050 (match_operator 1 "compare_operator"
17051 [(and:QI (match_operand:QI 2 "register_operand" "")
17052 (match_operand:QI 3 "immediate_operand" ""))
17053 (const_int 0)]))]
17054 "! TARGET_PARTIAL_REG_STALL
17055 && ix86_match_ccmode (insn, CCNOmode)
17056 && true_regnum (operands[2]) != AX_REG
17057 && peep2_reg_dead_p (1, operands[2])"
17058 [(parallel
17059 [(set (match_dup 0)
17060 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17061 (const_int 0)]))
17062 (set (match_dup 2)
17063 (and:QI (match_dup 2) (match_dup 3)))])])
17064
17065 (define_peephole2
17066 [(set (match_operand 0 "flags_reg_operand" "")
17067 (match_operator 1 "compare_operator"
17068 [(and:SI
17069 (zero_extract:SI
17070 (match_operand 2 "ext_register_operand" "")
17071 (const_int 8)
17072 (const_int 8))
17073 (match_operand 3 "const_int_operand" ""))
17074 (const_int 0)]))]
17075 "! TARGET_PARTIAL_REG_STALL
17076 && ix86_match_ccmode (insn, CCNOmode)
17077 && true_regnum (operands[2]) != AX_REG
17078 && peep2_reg_dead_p (1, operands[2])"
17079 [(parallel [(set (match_dup 0)
17080 (match_op_dup 1
17081 [(and:SI
17082 (zero_extract:SI
17083 (match_dup 2)
17084 (const_int 8)
17085 (const_int 8))
17086 (match_dup 3))
17087 (const_int 0)]))
17088 (set (zero_extract:SI (match_dup 2)
17089 (const_int 8)
17090 (const_int 8))
17091 (and:SI
17092 (zero_extract:SI
17093 (match_dup 2)
17094 (const_int 8)
17095 (const_int 8))
17096 (match_dup 3)))])])
17097
17098 ;; Don't do logical operations with memory inputs.
17099 (define_peephole2
17100 [(match_scratch:SI 2 "r")
17101 (parallel [(set (match_operand:SI 0 "register_operand" "")
17102 (match_operator:SI 3 "arith_or_logical_operator"
17103 [(match_dup 0)
17104 (match_operand:SI 1 "memory_operand" "")]))
17105 (clobber (reg:CC FLAGS_REG))])]
17106 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17107 [(set (match_dup 2) (match_dup 1))
17108 (parallel [(set (match_dup 0)
17109 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17110 (clobber (reg:CC FLAGS_REG))])])
17111
17112 (define_peephole2
17113 [(match_scratch:SI 2 "r")
17114 (parallel [(set (match_operand:SI 0 "register_operand" "")
17115 (match_operator:SI 3 "arith_or_logical_operator"
17116 [(match_operand:SI 1 "memory_operand" "")
17117 (match_dup 0)]))
17118 (clobber (reg:CC FLAGS_REG))])]
17119 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17120 [(set (match_dup 2) (match_dup 1))
17121 (parallel [(set (match_dup 0)
17122 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17123 (clobber (reg:CC FLAGS_REG))])])
17124
17125 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17126 ;; refers to the destination of the load!
17127
17128 (define_peephole2
17129 [(set (match_operand:SI 0 "register_operand" "")
17130 (match_operand:SI 1 "register_operand" ""))
17131 (parallel [(set (match_dup 0)
17132 (match_operator:SI 3 "commutative_operator"
17133 [(match_dup 0)
17134 (match_operand:SI 2 "memory_operand" "")]))
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "REGNO (operands[0]) != REGNO (operands[1])
17137 && GENERAL_REGNO_P (REGNO (operands[0]))
17138 && GENERAL_REGNO_P (REGNO (operands[1]))"
17139 [(set (match_dup 0) (match_dup 4))
17140 (parallel [(set (match_dup 0)
17141 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17142 (clobber (reg:CC FLAGS_REG))])]
17143 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17144
17145 (define_peephole2
17146 [(set (match_operand 0 "register_operand" "")
17147 (match_operand 1 "register_operand" ""))
17148 (set (match_dup 0)
17149 (match_operator 3 "commutative_operator"
17150 [(match_dup 0)
17151 (match_operand 2 "memory_operand" "")]))]
17152 "REGNO (operands[0]) != REGNO (operands[1])
17153 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17154 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17155 [(set (match_dup 0) (match_dup 2))
17156 (set (match_dup 0)
17157 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17158
17159 ; Don't do logical operations with memory outputs
17160 ;
17161 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17162 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17163 ; the same decoder scheduling characteristics as the original.
17164
17165 (define_peephole2
17166 [(match_scratch:SI 2 "r")
17167 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17168 (match_operator:SI 3 "arith_or_logical_operator"
17169 [(match_dup 0)
17170 (match_operand:SI 1 "nonmemory_operand" "")]))
17171 (clobber (reg:CC FLAGS_REG))])]
17172 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17173 /* Do not split stack checking probes. */
17174 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17175 [(set (match_dup 2) (match_dup 0))
17176 (parallel [(set (match_dup 2)
17177 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17178 (clobber (reg:CC FLAGS_REG))])
17179 (set (match_dup 0) (match_dup 2))])
17180
17181 (define_peephole2
17182 [(match_scratch:SI 2 "r")
17183 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17184 (match_operator:SI 3 "arith_or_logical_operator"
17185 [(match_operand:SI 1 "nonmemory_operand" "")
17186 (match_dup 0)]))
17187 (clobber (reg:CC FLAGS_REG))])]
17188 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17189 /* Do not split stack checking probes. */
17190 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17191 [(set (match_dup 2) (match_dup 0))
17192 (parallel [(set (match_dup 2)
17193 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17194 (clobber (reg:CC FLAGS_REG))])
17195 (set (match_dup 0) (match_dup 2))])
17196
17197 ;; Attempt to use arith or logical operations with memory outputs with
17198 ;; setting of flags.
17199 (define_peephole2
17200 [(set (match_operand:SWI 0 "register_operand" "")
17201 (match_operand:SWI 1 "memory_operand" ""))
17202 (parallel [(set (match_dup 0)
17203 (match_operator:SWI 3 "plusminuslogic_operator"
17204 [(match_dup 0)
17205 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17206 (clobber (reg:CC FLAGS_REG))])
17207 (set (match_dup 1) (match_dup 0))
17208 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17209 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17210 && peep2_reg_dead_p (4, operands[0])
17211 && !reg_overlap_mentioned_p (operands[0], operands[1])
17212 && ix86_match_ccmode (peep2_next_insn (3),
17213 (GET_CODE (operands[3]) == PLUS
17214 || GET_CODE (operands[3]) == MINUS)
17215 ? CCGOCmode : CCNOmode)"
17216 [(parallel [(set (match_dup 4) (match_dup 5))
17217 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17218 (match_dup 2)]))])]
17219 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17220 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17221 copy_rtx (operands[1]),
17222 copy_rtx (operands[2]));
17223 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17224 operands[5], const0_rtx);")
17225
17226 (define_peephole2
17227 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17228 (match_operator:SWI 2 "plusminuslogic_operator"
17229 [(match_dup 0)
17230 (match_operand:SWI 1 "memory_operand" "")]))
17231 (clobber (reg:CC FLAGS_REG))])
17232 (set (match_dup 1) (match_dup 0))
17233 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17234 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17235 && GET_CODE (operands[2]) != MINUS
17236 && peep2_reg_dead_p (3, operands[0])
17237 && !reg_overlap_mentioned_p (operands[0], operands[1])
17238 && ix86_match_ccmode (peep2_next_insn (2),
17239 GET_CODE (operands[2]) == PLUS
17240 ? CCGOCmode : CCNOmode)"
17241 [(parallel [(set (match_dup 3) (match_dup 4))
17242 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17243 (match_dup 0)]))])]
17244 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17245 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17246 copy_rtx (operands[1]),
17247 copy_rtx (operands[0]));
17248 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17249 operands[4], const0_rtx);")
17250
17251 (define_peephole2
17252 [(set (match_operand:SWI12 0 "register_operand" "")
17253 (match_operand:SWI12 1 "memory_operand" ""))
17254 (parallel [(set (match_operand:SI 4 "register_operand" "")
17255 (match_operator:SI 3 "plusminuslogic_operator"
17256 [(match_dup 4)
17257 (match_operand:SI 2 "nonmemory_operand" "")]))
17258 (clobber (reg:CC FLAGS_REG))])
17259 (set (match_dup 1) (match_dup 0))
17260 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17261 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17262 && REG_P (operands[0]) && REG_P (operands[4])
17263 && REGNO (operands[0]) == REGNO (operands[4])
17264 && peep2_reg_dead_p (4, operands[0])
17265 && !reg_overlap_mentioned_p (operands[0], operands[1])
17266 && ix86_match_ccmode (peep2_next_insn (3),
17267 (GET_CODE (operands[3]) == PLUS
17268 || GET_CODE (operands[3]) == MINUS)
17269 ? CCGOCmode : CCNOmode)"
17270 [(parallel [(set (match_dup 4) (match_dup 5))
17271 (set (match_dup 1) (match_dup 6))])]
17272 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17273 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17274 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17275 copy_rtx (operands[1]), operands[2]);
17276 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17277 operands[5], const0_rtx);
17278 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17279 copy_rtx (operands[1]),
17280 copy_rtx (operands[2]));")
17281
17282 ;; Attempt to always use XOR for zeroing registers.
17283 (define_peephole2
17284 [(set (match_operand 0 "register_operand" "")
17285 (match_operand 1 "const0_operand" ""))]
17286 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17287 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17288 && GENERAL_REG_P (operands[0])
17289 && peep2_regno_dead_p (0, FLAGS_REG)"
17290 [(parallel [(set (match_dup 0) (const_int 0))
17291 (clobber (reg:CC FLAGS_REG))])]
17292 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17293
17294 (define_peephole2
17295 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17296 (const_int 0))]
17297 "(GET_MODE (operands[0]) == QImode
17298 || GET_MODE (operands[0]) == HImode)
17299 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17300 && peep2_regno_dead_p (0, FLAGS_REG)"
17301 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17302 (clobber (reg:CC FLAGS_REG))])])
17303
17304 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17305 (define_peephole2
17306 [(set (match_operand:SWI248 0 "register_operand" "")
17307 (const_int -1))]
17308 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17309 && peep2_regno_dead_p (0, FLAGS_REG)"
17310 [(parallel [(set (match_dup 0) (const_int -1))
17311 (clobber (reg:CC FLAGS_REG))])]
17312 {
17313 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17314 operands[0] = gen_lowpart (SImode, operands[0]);
17315 })
17316
17317 ;; Attempt to convert simple lea to add/shift.
17318 ;; These can be created by move expanders.
17319
17320 (define_peephole2
17321 [(set (match_operand:SWI48 0 "register_operand" "")
17322 (plus:SWI48 (match_dup 0)
17323 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17324 "peep2_regno_dead_p (0, FLAGS_REG)"
17325 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17326 (clobber (reg:CC FLAGS_REG))])])
17327
17328 (define_peephole2
17329 [(set (match_operand:SI 0 "register_operand" "")
17330 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17331 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17332 "TARGET_64BIT
17333 && peep2_regno_dead_p (0, FLAGS_REG)
17334 && REGNO (operands[0]) == REGNO (operands[1])"
17335 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17336 (clobber (reg:CC FLAGS_REG))])]
17337 "operands[2] = gen_lowpart (SImode, operands[2]);")
17338
17339 (define_peephole2
17340 [(set (match_operand:SWI48 0 "register_operand" "")
17341 (mult:SWI48 (match_dup 0)
17342 (match_operand:SWI48 1 "const_int_operand" "")))]
17343 "exact_log2 (INTVAL (operands[1])) >= 0
17344 && peep2_regno_dead_p (0, FLAGS_REG)"
17345 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17346 (clobber (reg:CC FLAGS_REG))])]
17347 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17348
17349 (define_peephole2
17350 [(set (match_operand:SI 0 "register_operand" "")
17351 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17352 (match_operand:DI 2 "const_int_operand" "")) 0))]
17353 "TARGET_64BIT
17354 && exact_log2 (INTVAL (operands[2])) >= 0
17355 && REGNO (operands[0]) == REGNO (operands[1])
17356 && peep2_regno_dead_p (0, FLAGS_REG)"
17357 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17358 (clobber (reg:CC FLAGS_REG))])]
17359 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17360
17361 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17362 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17363 ;; On many CPUs it is also faster, since special hardware to avoid esp
17364 ;; dependencies is present.
17365
17366 ;; While some of these conversions may be done using splitters, we use
17367 ;; peepholes in order to allow combine_stack_adjustments pass to see
17368 ;; nonobfuscated RTL.
17369
17370 ;; Convert prologue esp subtractions to push.
17371 ;; We need register to push. In order to keep verify_flow_info happy we have
17372 ;; two choices
17373 ;; - use scratch and clobber it in order to avoid dependencies
17374 ;; - use already live register
17375 ;; We can't use the second way right now, since there is no reliable way how to
17376 ;; verify that given register is live. First choice will also most likely in
17377 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17378 ;; call clobbered registers are dead. We may want to use base pointer as an
17379 ;; alternative when no register is available later.
17380
17381 (define_peephole2
17382 [(match_scratch:P 1 "r")
17383 (parallel [(set (reg:P SP_REG)
17384 (plus:P (reg:P SP_REG)
17385 (match_operand:P 0 "const_int_operand" "")))
17386 (clobber (reg:CC FLAGS_REG))
17387 (clobber (mem:BLK (scratch)))])]
17388 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17389 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17390 [(clobber (match_dup 1))
17391 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17392 (clobber (mem:BLK (scratch)))])])
17393
17394 (define_peephole2
17395 [(match_scratch:P 1 "r")
17396 (parallel [(set (reg:P SP_REG)
17397 (plus:P (reg:P SP_REG)
17398 (match_operand:P 0 "const_int_operand" "")))
17399 (clobber (reg:CC FLAGS_REG))
17400 (clobber (mem:BLK (scratch)))])]
17401 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17402 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17403 [(clobber (match_dup 1))
17404 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17405 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17406 (clobber (mem:BLK (scratch)))])])
17407
17408 ;; Convert esp subtractions to push.
17409 (define_peephole2
17410 [(match_scratch:P 1 "r")
17411 (parallel [(set (reg:P SP_REG)
17412 (plus:P (reg:P SP_REG)
17413 (match_operand:P 0 "const_int_operand" "")))
17414 (clobber (reg:CC FLAGS_REG))])]
17415 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17416 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17417 [(clobber (match_dup 1))
17418 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17419
17420 (define_peephole2
17421 [(match_scratch:P 1 "r")
17422 (parallel [(set (reg:P SP_REG)
17423 (plus:P (reg:P SP_REG)
17424 (match_operand:P 0 "const_int_operand" "")))
17425 (clobber (reg:CC FLAGS_REG))])]
17426 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17427 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17428 [(clobber (match_dup 1))
17429 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17430 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17431
17432 ;; Convert epilogue deallocator to pop.
17433 (define_peephole2
17434 [(match_scratch:P 1 "r")
17435 (parallel [(set (reg:P SP_REG)
17436 (plus:P (reg:P SP_REG)
17437 (match_operand:P 0 "const_int_operand" "")))
17438 (clobber (reg:CC FLAGS_REG))
17439 (clobber (mem:BLK (scratch)))])]
17440 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17441 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17442 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17443 (clobber (mem:BLK (scratch)))])])
17444
17445 ;; Two pops case is tricky, since pop causes dependency
17446 ;; on destination register. We use two registers if available.
17447 (define_peephole2
17448 [(match_scratch:P 1 "r")
17449 (match_scratch:P 2 "r")
17450 (parallel [(set (reg:P SP_REG)
17451 (plus:P (reg:P SP_REG)
17452 (match_operand:P 0 "const_int_operand" "")))
17453 (clobber (reg:CC FLAGS_REG))
17454 (clobber (mem:BLK (scratch)))])]
17455 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17456 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17457 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17458 (clobber (mem:BLK (scratch)))])
17459 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17460
17461 (define_peephole2
17462 [(match_scratch:P 1 "r")
17463 (parallel [(set (reg:P SP_REG)
17464 (plus:P (reg:P SP_REG)
17465 (match_operand:P 0 "const_int_operand" "")))
17466 (clobber (reg:CC FLAGS_REG))
17467 (clobber (mem:BLK (scratch)))])]
17468 "optimize_insn_for_size_p ()
17469 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17470 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17471 (clobber (mem:BLK (scratch)))])
17472 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17473
17474 ;; Convert esp additions to pop.
17475 (define_peephole2
17476 [(match_scratch:P 1 "r")
17477 (parallel [(set (reg:P SP_REG)
17478 (plus:P (reg:P SP_REG)
17479 (match_operand:P 0 "const_int_operand" "")))
17480 (clobber (reg:CC FLAGS_REG))])]
17481 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17482 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17483
17484 ;; Two pops case is tricky, since pop causes dependency
17485 ;; on destination register. We use two registers if available.
17486 (define_peephole2
17487 [(match_scratch:P 1 "r")
17488 (match_scratch:P 2 "r")
17489 (parallel [(set (reg:P SP_REG)
17490 (plus:P (reg:P SP_REG)
17491 (match_operand:P 0 "const_int_operand" "")))
17492 (clobber (reg:CC FLAGS_REG))])]
17493 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17494 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17495 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17496
17497 (define_peephole2
17498 [(match_scratch:P 1 "r")
17499 (parallel [(set (reg:P SP_REG)
17500 (plus:P (reg:P SP_REG)
17501 (match_operand:P 0 "const_int_operand" "")))
17502 (clobber (reg:CC FLAGS_REG))])]
17503 "optimize_insn_for_size_p ()
17504 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17505 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17506 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17507 \f
17508 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17509 ;; required and register dies. Similarly for 128 to -128.
17510 (define_peephole2
17511 [(set (match_operand 0 "flags_reg_operand" "")
17512 (match_operator 1 "compare_operator"
17513 [(match_operand 2 "register_operand" "")
17514 (match_operand 3 "const_int_operand" "")]))]
17515 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17516 && incdec_operand (operands[3], GET_MODE (operands[3])))
17517 || (!TARGET_FUSE_CMP_AND_BRANCH
17518 && INTVAL (operands[3]) == 128))
17519 && ix86_match_ccmode (insn, CCGCmode)
17520 && peep2_reg_dead_p (1, operands[2])"
17521 [(parallel [(set (match_dup 0)
17522 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17523 (clobber (match_dup 2))])])
17524 \f
17525 ;; Convert imul by three, five and nine into lea
17526 (define_peephole2
17527 [(parallel
17528 [(set (match_operand:SWI48 0 "register_operand" "")
17529 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17530 (match_operand:SWI48 2 "const359_operand" "")))
17531 (clobber (reg:CC FLAGS_REG))])]
17532 "!TARGET_PARTIAL_REG_STALL
17533 || <MODE>mode == SImode
17534 || optimize_function_for_size_p (cfun)"
17535 [(set (match_dup 0)
17536 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17537 (match_dup 1)))]
17538 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17539
17540 (define_peephole2
17541 [(parallel
17542 [(set (match_operand:SWI48 0 "register_operand" "")
17543 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17544 (match_operand:SWI48 2 "const359_operand" "")))
17545 (clobber (reg:CC FLAGS_REG))])]
17546 "optimize_insn_for_speed_p ()
17547 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17548 [(set (match_dup 0) (match_dup 1))
17549 (set (match_dup 0)
17550 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17551 (match_dup 0)))]
17552 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17553
17554 ;; imul $32bit_imm, mem, reg is vector decoded, while
17555 ;; imul $32bit_imm, reg, reg is direct decoded.
17556 (define_peephole2
17557 [(match_scratch:SWI48 3 "r")
17558 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17559 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17560 (match_operand:SWI48 2 "immediate_operand" "")))
17561 (clobber (reg:CC FLAGS_REG))])]
17562 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17563 && !satisfies_constraint_K (operands[2])"
17564 [(set (match_dup 3) (match_dup 1))
17565 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17566 (clobber (reg:CC FLAGS_REG))])])
17567
17568 (define_peephole2
17569 [(match_scratch:SI 3 "r")
17570 (parallel [(set (match_operand:DI 0 "register_operand" "")
17571 (zero_extend:DI
17572 (mult:SI (match_operand:SI 1 "memory_operand" "")
17573 (match_operand:SI 2 "immediate_operand" ""))))
17574 (clobber (reg:CC FLAGS_REG))])]
17575 "TARGET_64BIT
17576 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17577 && !satisfies_constraint_K (operands[2])"
17578 [(set (match_dup 3) (match_dup 1))
17579 (parallel [(set (match_dup 0)
17580 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17581 (clobber (reg:CC FLAGS_REG))])])
17582
17583 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17584 ;; Convert it into imul reg, reg
17585 ;; It would be better to force assembler to encode instruction using long
17586 ;; immediate, but there is apparently no way to do so.
17587 (define_peephole2
17588 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17589 (mult:SWI248
17590 (match_operand:SWI248 1 "nonimmediate_operand" "")
17591 (match_operand:SWI248 2 "const_int_operand" "")))
17592 (clobber (reg:CC FLAGS_REG))])
17593 (match_scratch:SWI248 3 "r")]
17594 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17595 && satisfies_constraint_K (operands[2])"
17596 [(set (match_dup 3) (match_dup 2))
17597 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17598 (clobber (reg:CC FLAGS_REG))])]
17599 {
17600 if (!rtx_equal_p (operands[0], operands[1]))
17601 emit_move_insn (operands[0], operands[1]);
17602 })
17603
17604 ;; After splitting up read-modify operations, array accesses with memory
17605 ;; operands might end up in form:
17606 ;; sall $2, %eax
17607 ;; movl 4(%esp), %edx
17608 ;; addl %edx, %eax
17609 ;; instead of pre-splitting:
17610 ;; sall $2, %eax
17611 ;; addl 4(%esp), %eax
17612 ;; Turn it into:
17613 ;; movl 4(%esp), %edx
17614 ;; leal (%edx,%eax,4), %eax
17615
17616 (define_peephole2
17617 [(match_scratch:P 5 "r")
17618 (parallel [(set (match_operand 0 "register_operand" "")
17619 (ashift (match_operand 1 "register_operand" "")
17620 (match_operand 2 "const_int_operand" "")))
17621 (clobber (reg:CC FLAGS_REG))])
17622 (parallel [(set (match_operand 3 "register_operand" "")
17623 (plus (match_dup 0)
17624 (match_operand 4 "x86_64_general_operand" "")))
17625 (clobber (reg:CC FLAGS_REG))])]
17626 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17627 /* Validate MODE for lea. */
17628 && ((!TARGET_PARTIAL_REG_STALL
17629 && (GET_MODE (operands[0]) == QImode
17630 || GET_MODE (operands[0]) == HImode))
17631 || GET_MODE (operands[0]) == SImode
17632 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17633 && (rtx_equal_p (operands[0], operands[3])
17634 || peep2_reg_dead_p (2, operands[0]))
17635 /* We reorder load and the shift. */
17636 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17637 [(set (match_dup 5) (match_dup 4))
17638 (set (match_dup 0) (match_dup 1))]
17639 {
17640 enum machine_mode op1mode = GET_MODE (operands[1]);
17641 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17642 int scale = 1 << INTVAL (operands[2]);
17643 rtx index = gen_lowpart (Pmode, operands[1]);
17644 rtx base = gen_lowpart (Pmode, operands[5]);
17645 rtx dest = gen_lowpart (mode, operands[3]);
17646
17647 operands[1] = gen_rtx_PLUS (Pmode, base,
17648 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17649 operands[5] = base;
17650 if (mode != Pmode)
17651 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17652 if (op1mode != Pmode)
17653 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17654 operands[0] = dest;
17655 })
17656 \f
17657 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17658 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17659 ;; caught for use by garbage collectors and the like. Using an insn that
17660 ;; maps to SIGILL makes it more likely the program will rightfully die.
17661 ;; Keeping with tradition, "6" is in honor of #UD.
17662 (define_insn "trap"
17663 [(trap_if (const_int 1) (const_int 6))]
17664 ""
17665 { return ASM_SHORT "0x0b0f"; }
17666 [(set_attr "length" "2")])
17667
17668 (define_expand "prefetch"
17669 [(prefetch (match_operand 0 "address_operand" "")
17670 (match_operand:SI 1 "const_int_operand" "")
17671 (match_operand:SI 2 "const_int_operand" ""))]
17672 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17673 {
17674 int rw = INTVAL (operands[1]);
17675 int locality = INTVAL (operands[2]);
17676
17677 gcc_assert (rw == 0 || rw == 1);
17678 gcc_assert (locality >= 0 && locality <= 3);
17679 gcc_assert (GET_MODE (operands[0]) == Pmode
17680 || GET_MODE (operands[0]) == VOIDmode);
17681
17682 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17683 supported by SSE counterpart or the SSE prefetch is not available
17684 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17685 of locality. */
17686 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17687 operands[2] = GEN_INT (3);
17688 else
17689 operands[1] = const0_rtx;
17690 })
17691
17692 (define_insn "*prefetch_sse_<mode>"
17693 [(prefetch (match_operand:P 0 "address_operand" "p")
17694 (const_int 0)
17695 (match_operand:SI 1 "const_int_operand" ""))]
17696 "TARGET_PREFETCH_SSE"
17697 {
17698 static const char * const patterns[4] = {
17699 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17700 };
17701
17702 int locality = INTVAL (operands[1]);
17703 gcc_assert (locality >= 0 && locality <= 3);
17704
17705 return patterns[locality];
17706 }
17707 [(set_attr "type" "sse")
17708 (set_attr "atom_sse_attr" "prefetch")
17709 (set (attr "length_address")
17710 (symbol_ref "memory_address_length (operands[0])"))
17711 (set_attr "memory" "none")])
17712
17713 (define_insn "*prefetch_3dnow_<mode>"
17714 [(prefetch (match_operand:P 0 "address_operand" "p")
17715 (match_operand:SI 1 "const_int_operand" "n")
17716 (const_int 3))]
17717 "TARGET_3DNOW"
17718 {
17719 if (INTVAL (operands[1]) == 0)
17720 return "prefetch\t%a0";
17721 else
17722 return "prefetchw\t%a0";
17723 }
17724 [(set_attr "type" "mmx")
17725 (set (attr "length_address")
17726 (symbol_ref "memory_address_length (operands[0])"))
17727 (set_attr "memory" "none")])
17728
17729 (define_expand "stack_protect_set"
17730 [(match_operand 0 "memory_operand" "")
17731 (match_operand 1 "memory_operand" "")]
17732 ""
17733 {
17734 rtx (*insn)(rtx, rtx);
17735
17736 #ifdef TARGET_THREAD_SSP_OFFSET
17737 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17738 insn = (TARGET_LP64
17739 ? gen_stack_tls_protect_set_di
17740 : gen_stack_tls_protect_set_si);
17741 #else
17742 insn = (TARGET_LP64
17743 ? gen_stack_protect_set_di
17744 : gen_stack_protect_set_si);
17745 #endif
17746
17747 emit_insn (insn (operands[0], operands[1]));
17748 DONE;
17749 })
17750
17751 (define_insn "stack_protect_set_<mode>"
17752 [(set (match_operand:PTR 0 "memory_operand" "=m")
17753 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17754 UNSPEC_SP_SET))
17755 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17756 (clobber (reg:CC FLAGS_REG))]
17757 ""
17758 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17759 [(set_attr "type" "multi")])
17760
17761 (define_insn "stack_tls_protect_set_<mode>"
17762 [(set (match_operand:PTR 0 "memory_operand" "=m")
17763 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17764 UNSPEC_SP_TLS_SET))
17765 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17766 (clobber (reg:CC FLAGS_REG))]
17767 ""
17768 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17769 [(set_attr "type" "multi")])
17770
17771 (define_expand "stack_protect_test"
17772 [(match_operand 0 "memory_operand" "")
17773 (match_operand 1 "memory_operand" "")
17774 (match_operand 2 "" "")]
17775 ""
17776 {
17777 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17778
17779 rtx (*insn)(rtx, rtx, rtx);
17780
17781 #ifdef TARGET_THREAD_SSP_OFFSET
17782 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17783 insn = (TARGET_LP64
17784 ? gen_stack_tls_protect_test_di
17785 : gen_stack_tls_protect_test_si);
17786 #else
17787 insn = (TARGET_LP64
17788 ? gen_stack_protect_test_di
17789 : gen_stack_protect_test_si);
17790 #endif
17791
17792 emit_insn (insn (flags, operands[0], operands[1]));
17793
17794 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17795 flags, const0_rtx, operands[2]));
17796 DONE;
17797 })
17798
17799 (define_insn "stack_protect_test_<mode>"
17800 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17801 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17802 (match_operand:PTR 2 "memory_operand" "m")]
17803 UNSPEC_SP_TEST))
17804 (clobber (match_scratch:PTR 3 "=&r"))]
17805 ""
17806 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17807 [(set_attr "type" "multi")])
17808
17809 (define_insn "stack_tls_protect_test_<mode>"
17810 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17811 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17812 (match_operand:PTR 2 "const_int_operand" "i")]
17813 UNSPEC_SP_TLS_TEST))
17814 (clobber (match_scratch:PTR 3 "=r"))]
17815 ""
17816 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17817 [(set_attr "type" "multi")])
17818
17819 (define_insn "sse4_2_crc32<mode>"
17820 [(set (match_operand:SI 0 "register_operand" "=r")
17821 (unspec:SI
17822 [(match_operand:SI 1 "register_operand" "0")
17823 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17824 UNSPEC_CRC32))]
17825 "TARGET_SSE4_2 || TARGET_CRC32"
17826 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17827 [(set_attr "type" "sselog1")
17828 (set_attr "prefix_rep" "1")
17829 (set_attr "prefix_extra" "1")
17830 (set (attr "prefix_data16")
17831 (if_then_else (match_operand:HI 2 "" "")
17832 (const_string "1")
17833 (const_string "*")))
17834 (set (attr "prefix_rex")
17835 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17836 (const_string "1")
17837 (const_string "*")))
17838 (set_attr "mode" "SI")])
17839
17840 (define_insn "sse4_2_crc32di"
17841 [(set (match_operand:DI 0 "register_operand" "=r")
17842 (unspec:DI
17843 [(match_operand:DI 1 "register_operand" "0")
17844 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17845 UNSPEC_CRC32))]
17846 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17847 "crc32{q}\t{%2, %0|%0, %2}"
17848 [(set_attr "type" "sselog1")
17849 (set_attr "prefix_rep" "1")
17850 (set_attr "prefix_extra" "1")
17851 (set_attr "mode" "DI")])
17852
17853 (define_expand "rdpmc"
17854 [(match_operand:DI 0 "register_operand" "")
17855 (match_operand:SI 1 "register_operand" "")]
17856 ""
17857 {
17858 rtx reg = gen_reg_rtx (DImode);
17859 rtx si;
17860
17861 /* Force operand 1 into ECX. */
17862 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17863 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17864 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17865 UNSPECV_RDPMC);
17866
17867 if (TARGET_64BIT)
17868 {
17869 rtvec vec = rtvec_alloc (2);
17870 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17871 rtx upper = gen_reg_rtx (DImode);
17872 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17873 gen_rtvec (1, const0_rtx),
17874 UNSPECV_RDPMC);
17875 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17876 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17877 emit_insn (load);
17878 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17879 NULL, 1, OPTAB_DIRECT);
17880 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17881 OPTAB_DIRECT);
17882 }
17883 else
17884 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17885 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17886 DONE;
17887 })
17888
17889 (define_insn "*rdpmc"
17890 [(set (match_operand:DI 0 "register_operand" "=A")
17891 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17892 UNSPECV_RDPMC))]
17893 "!TARGET_64BIT"
17894 "rdpmc"
17895 [(set_attr "type" "other")
17896 (set_attr "length" "2")])
17897
17898 (define_insn "*rdpmc_rex64"
17899 [(set (match_operand:DI 0 "register_operand" "=a")
17900 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17901 UNSPECV_RDPMC))
17902 (set (match_operand:DI 1 "register_operand" "=d")
17903 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17904 "TARGET_64BIT"
17905 "rdpmc"
17906 [(set_attr "type" "other")
17907 (set_attr "length" "2")])
17908
17909 (define_expand "rdtsc"
17910 [(set (match_operand:DI 0 "register_operand" "")
17911 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17912 ""
17913 {
17914 if (TARGET_64BIT)
17915 {
17916 rtvec vec = rtvec_alloc (2);
17917 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17918 rtx upper = gen_reg_rtx (DImode);
17919 rtx lower = gen_reg_rtx (DImode);
17920 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17921 gen_rtvec (1, const0_rtx),
17922 UNSPECV_RDTSC);
17923 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17924 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17925 emit_insn (load);
17926 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17927 NULL, 1, OPTAB_DIRECT);
17928 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17929 OPTAB_DIRECT);
17930 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17931 DONE;
17932 }
17933 })
17934
17935 (define_insn "*rdtsc"
17936 [(set (match_operand:DI 0 "register_operand" "=A")
17937 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17938 "!TARGET_64BIT"
17939 "rdtsc"
17940 [(set_attr "type" "other")
17941 (set_attr "length" "2")])
17942
17943 (define_insn "*rdtsc_rex64"
17944 [(set (match_operand:DI 0 "register_operand" "=a")
17945 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17946 (set (match_operand:DI 1 "register_operand" "=d")
17947 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17948 "TARGET_64BIT"
17949 "rdtsc"
17950 [(set_attr "type" "other")
17951 (set_attr "length" "2")])
17952
17953 (define_expand "rdtscp"
17954 [(match_operand:DI 0 "register_operand" "")
17955 (match_operand:SI 1 "memory_operand" "")]
17956 ""
17957 {
17958 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17959 gen_rtvec (1, const0_rtx),
17960 UNSPECV_RDTSCP);
17961 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17962 gen_rtvec (1, const0_rtx),
17963 UNSPECV_RDTSCP);
17964 rtx reg = gen_reg_rtx (DImode);
17965 rtx tmp = gen_reg_rtx (SImode);
17966
17967 if (TARGET_64BIT)
17968 {
17969 rtvec vec = rtvec_alloc (3);
17970 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17971 rtx upper = gen_reg_rtx (DImode);
17972 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17973 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17974 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17975 emit_insn (load);
17976 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17977 NULL, 1, OPTAB_DIRECT);
17978 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17979 OPTAB_DIRECT);
17980 }
17981 else
17982 {
17983 rtvec vec = rtvec_alloc (2);
17984 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17985 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17986 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17987 emit_insn (load);
17988 }
17989 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17990 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17991 DONE;
17992 })
17993
17994 (define_insn "*rdtscp"
17995 [(set (match_operand:DI 0 "register_operand" "=A")
17996 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17997 (set (match_operand:SI 1 "register_operand" "=c")
17998 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17999 "!TARGET_64BIT"
18000 "rdtscp"
18001 [(set_attr "type" "other")
18002 (set_attr "length" "3")])
18003
18004 (define_insn "*rdtscp_rex64"
18005 [(set (match_operand:DI 0 "register_operand" "=a")
18006 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18007 (set (match_operand:DI 1 "register_operand" "=d")
18008 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18009 (set (match_operand:SI 2 "register_operand" "=c")
18010 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18011 "TARGET_64BIT"
18012 "rdtscp"
18013 [(set_attr "type" "other")
18014 (set_attr "length" "3")])
18015
18016 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18017 ;;
18018 ;; LWP instructions
18019 ;;
18020 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18021
18022 (define_expand "lwp_llwpcb"
18023 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18024 UNSPECV_LLWP_INTRINSIC)]
18025 "TARGET_LWP")
18026
18027 (define_insn "*lwp_llwpcb<mode>1"
18028 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18029 UNSPECV_LLWP_INTRINSIC)]
18030 "TARGET_LWP"
18031 "llwpcb\t%0"
18032 [(set_attr "type" "lwp")
18033 (set_attr "mode" "<MODE>")
18034 (set_attr "length" "5")])
18035
18036 (define_expand "lwp_slwpcb"
18037 [(set (match_operand 0 "register_operand" "=r")
18038 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18039 "TARGET_LWP"
18040 {
18041 rtx (*insn)(rtx);
18042
18043 insn = (TARGET_64BIT
18044 ? gen_lwp_slwpcbdi
18045 : gen_lwp_slwpcbsi);
18046
18047 emit_insn (insn (operands[0]));
18048 DONE;
18049 })
18050
18051 (define_insn "lwp_slwpcb<mode>"
18052 [(set (match_operand:P 0 "register_operand" "=r")
18053 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18054 "TARGET_LWP"
18055 "slwpcb\t%0"
18056 [(set_attr "type" "lwp")
18057 (set_attr "mode" "<MODE>")
18058 (set_attr "length" "5")])
18059
18060 (define_expand "lwp_lwpval<mode>3"
18061 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18062 (match_operand:SI 2 "nonimmediate_operand" "rm")
18063 (match_operand:SI 3 "const_int_operand" "i")]
18064 UNSPECV_LWPVAL_INTRINSIC)]
18065 "TARGET_LWP"
18066 "/* Avoid unused variable warning. */
18067 (void) operand0;")
18068
18069 (define_insn "*lwp_lwpval<mode>3_1"
18070 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18071 (match_operand:SI 1 "nonimmediate_operand" "rm")
18072 (match_operand:SI 2 "const_int_operand" "i")]
18073 UNSPECV_LWPVAL_INTRINSIC)]
18074 "TARGET_LWP"
18075 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18076 [(set_attr "type" "lwp")
18077 (set_attr "mode" "<MODE>")
18078 (set (attr "length")
18079 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18080
18081 (define_expand "lwp_lwpins<mode>3"
18082 [(set (reg:CCC FLAGS_REG)
18083 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18084 (match_operand:SI 2 "nonimmediate_operand" "rm")
18085 (match_operand:SI 3 "const_int_operand" "i")]
18086 UNSPECV_LWPINS_INTRINSIC))
18087 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18088 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18089 "TARGET_LWP")
18090
18091 (define_insn "*lwp_lwpins<mode>3_1"
18092 [(set (reg:CCC FLAGS_REG)
18093 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18094 (match_operand:SI 1 "nonimmediate_operand" "rm")
18095 (match_operand:SI 2 "const_int_operand" "i")]
18096 UNSPECV_LWPINS_INTRINSIC))]
18097 "TARGET_LWP"
18098 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18099 [(set_attr "type" "lwp")
18100 (set_attr "mode" "<MODE>")
18101 (set (attr "length")
18102 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18103
18104 (define_insn "rdfsbase<mode>"
18105 [(set (match_operand:SWI48 0 "register_operand" "=r")
18106 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18107 "TARGET_64BIT && TARGET_FSGSBASE"
18108 "rdfsbase %0"
18109 [(set_attr "type" "other")
18110 (set_attr "prefix_extra" "2")])
18111
18112 (define_insn "rdgsbase<mode>"
18113 [(set (match_operand:SWI48 0 "register_operand" "=r")
18114 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18115 "TARGET_64BIT && TARGET_FSGSBASE"
18116 "rdgsbase %0"
18117 [(set_attr "type" "other")
18118 (set_attr "prefix_extra" "2")])
18119
18120 (define_insn "wrfsbase<mode>"
18121 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18122 UNSPECV_WRFSBASE)]
18123 "TARGET_64BIT && TARGET_FSGSBASE"
18124 "wrfsbase %0"
18125 [(set_attr "type" "other")
18126 (set_attr "prefix_extra" "2")])
18127
18128 (define_insn "wrgsbase<mode>"
18129 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18130 UNSPECV_WRGSBASE)]
18131 "TARGET_64BIT && TARGET_FSGSBASE"
18132 "wrgsbase %0"
18133 [(set_attr "type" "other")
18134 (set_attr "prefix_extra" "2")])
18135
18136 (define_insn "rdrand<mode>_1"
18137 [(set (match_operand:SWI248 0 "register_operand" "=r")
18138 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18139 (set (reg:CCC FLAGS_REG)
18140 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18141 "TARGET_RDRND"
18142 "rdrand\t%0"
18143 [(set_attr "type" "other")
18144 (set_attr "prefix_extra" "1")])
18145
18146 (define_expand "pause"
18147 [(set (match_dup 0)
18148 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18149 ""
18150 {
18151 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18152 MEM_VOLATILE_P (operands[0]) = 1;
18153 })
18154
18155 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18156 ;; They have the same encoding.
18157 (define_insn "*pause"
18158 [(set (match_operand:BLK 0 "" "")
18159 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18160 ""
18161 "rep; nop"
18162 [(set_attr "length" "2")
18163 (set_attr "memory" "unknown")])
18164
18165 (include "mmx.md")
18166 (include "sse.md")
18167 (include "sync.md")