79db5f82f24bce805faa0961d7b4112db67296dc
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2013 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12 ;;
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
21 ;;
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
24 ;;
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;; otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;; delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
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 "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
67
68 (define_c_enum "unspec" [
69 ;; Relocation specifiers
70 UNSPEC_GOT
71 UNSPEC_GOTOFF
72 UNSPEC_GOTPCREL
73 UNSPEC_GOTTPOFF
74 UNSPEC_TPOFF
75 UNSPEC_NTPOFF
76 UNSPEC_DTPOFF
77 UNSPEC_GOTNTPOFF
78 UNSPEC_INDNTPOFF
79 UNSPEC_PLTOFF
80 UNSPEC_MACHOPIC_OFFSET
81 UNSPEC_PCREL
82
83 ;; Prologue support
84 UNSPEC_STACK_ALLOC
85 UNSPEC_SET_GOT
86 UNSPEC_SET_RIP
87 UNSPEC_SET_GOT_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
89 UNSPEC_STACK_CHECK
90
91 ;; TLS support
92 UNSPEC_TP
93 UNSPEC_TLS_GD
94 UNSPEC_TLS_LD_BASE
95 UNSPEC_TLSDESC
96 UNSPEC_TLS_IE_SUN
97
98 ;; Other random patterns
99 UNSPEC_SCAS
100 UNSPEC_FNSTSW
101 UNSPEC_SAHF
102 UNSPEC_PARITY
103 UNSPEC_FSTCW
104 UNSPEC_ADD_CARRY
105 UNSPEC_FLDCW
106 UNSPEC_REP
107 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_TRUNC_NOOP
109 UNSPEC_DIV_ALREADY_SPLIT
110 UNSPEC_MS_TO_SYSV_CALL
111 UNSPEC_PAUSE
112 UNSPEC_LEA_ADDR
113 UNSPEC_XBEGIN_ABORT
114 UNSPEC_STOS
115
116 ;; For SSE/MMX support:
117 UNSPEC_FIX_NOTRUNC
118 UNSPEC_MASKMOV
119 UNSPEC_MOVMSK
120 UNSPEC_RCP
121 UNSPEC_RSQRT
122 UNSPEC_PSADBW
123
124 ;; Generic math support
125 UNSPEC_COPYSIGN
126 UNSPEC_IEEE_MIN ; not commutative
127 UNSPEC_IEEE_MAX ; not commutative
128
129 ;; x87 Floating point
130 UNSPEC_SIN
131 UNSPEC_COS
132 UNSPEC_FPATAN
133 UNSPEC_FYL2X
134 UNSPEC_FYL2XP1
135 UNSPEC_FRNDINT
136 UNSPEC_FIST
137 UNSPEC_F2XM1
138 UNSPEC_TAN
139 UNSPEC_FXAM
140
141 ;; x87 Rounding
142 UNSPEC_FRNDINT_FLOOR
143 UNSPEC_FRNDINT_CEIL
144 UNSPEC_FRNDINT_TRUNC
145 UNSPEC_FRNDINT_MASK_PM
146 UNSPEC_FIST_FLOOR
147 UNSPEC_FIST_CEIL
148
149 ;; x87 Double output FP
150 UNSPEC_SINCOS_COS
151 UNSPEC_SINCOS_SIN
152 UNSPEC_XTRACT_FRACT
153 UNSPEC_XTRACT_EXP
154 UNSPEC_FSCALE_FRACT
155 UNSPEC_FSCALE_EXP
156 UNSPEC_FPREM_F
157 UNSPEC_FPREM_U
158 UNSPEC_FPREM1_F
159 UNSPEC_FPREM1_U
160
161 UNSPEC_C2_FLAG
162 UNSPEC_FXAM_MEM
163
164 ;; SSP patterns
165 UNSPEC_SP_SET
166 UNSPEC_SP_TEST
167 UNSPEC_SP_TLS_SET
168 UNSPEC_SP_TLS_TEST
169
170 ;; For ROUND support
171 UNSPEC_ROUND
172
173 ;; For CRC32 support
174 UNSPEC_CRC32
175
176 ;; For BMI support
177 UNSPEC_BEXTR
178
179 ;; For BMI2 support
180 UNSPEC_PDEP
181 UNSPEC_PEXT
182
183 UNSPEC_BNDMK
184 UNSPEC_BNDMK_ADDR
185 UNSPEC_BNDSTX
186 UNSPEC_BNDLDX
187 UNSPEC_BNDLDX_ADDR
188 UNSPEC_BNDCL
189 UNSPEC_BNDCU
190 UNSPEC_BNDCN
191 UNSPEC_MPX_FENCE
192 ])
193
194 (define_c_enum "unspecv" [
195 UNSPECV_BLOCKAGE
196 UNSPECV_STACK_PROBE
197 UNSPECV_PROBE_STACK_RANGE
198 UNSPECV_ALIGN
199 UNSPECV_PROLOGUE_USE
200 UNSPECV_SPLIT_STACK_RETURN
201 UNSPECV_CLD
202 UNSPECV_NOPS
203 UNSPECV_RDTSC
204 UNSPECV_RDTSCP
205 UNSPECV_RDPMC
206 UNSPECV_LLWP_INTRINSIC
207 UNSPECV_SLWP_INTRINSIC
208 UNSPECV_LWPVAL_INTRINSIC
209 UNSPECV_LWPINS_INTRINSIC
210 UNSPECV_RDFSBASE
211 UNSPECV_RDGSBASE
212 UNSPECV_WRFSBASE
213 UNSPECV_WRGSBASE
214 UNSPECV_FXSAVE
215 UNSPECV_FXRSTOR
216 UNSPECV_FXSAVE64
217 UNSPECV_FXRSTOR64
218 UNSPECV_XSAVE
219 UNSPECV_XRSTOR
220 UNSPECV_XSAVE64
221 UNSPECV_XRSTOR64
222 UNSPECV_XSAVEOPT
223 UNSPECV_XSAVEOPT64
224
225 ;; For RDRAND support
226 UNSPECV_RDRAND
227
228 ;; For RDSEED support
229 UNSPECV_RDSEED
230
231 ;; For RTM support
232 UNSPECV_XBEGIN
233 UNSPECV_XEND
234 UNSPECV_XABORT
235 UNSPECV_XTEST
236
237 UNSPECV_NLGR
238 ])
239
240 ;; Constants to represent rounding modes in the ROUND instruction
241 (define_constants
242 [(ROUND_FLOOR 0x1)
243 (ROUND_CEIL 0x2)
244 (ROUND_TRUNC 0x3)
245 (ROUND_MXCSR 0x4)
246 (ROUND_NO_EXC 0x8)
247 ])
248
249 ;; Constants to represent pcomtrue/pcomfalse variants
250 (define_constants
251 [(PCOM_FALSE 0)
252 (PCOM_TRUE 1)
253 (COM_FALSE_S 2)
254 (COM_FALSE_P 3)
255 (COM_TRUE_S 4)
256 (COM_TRUE_P 5)
257 ])
258
259 ;; Constants used in the XOP pperm instruction
260 (define_constants
261 [(PPERM_SRC 0x00) /* copy source */
262 (PPERM_INVERT 0x20) /* invert source */
263 (PPERM_REVERSE 0x40) /* bit reverse source */
264 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
265 (PPERM_ZERO 0x80) /* all 0's */
266 (PPERM_ONES 0xa0) /* all 1's */
267 (PPERM_SIGN 0xc0) /* propagate sign bit */
268 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
269 (PPERM_SRC1 0x00) /* use first source byte */
270 (PPERM_SRC2 0x10) /* use second source byte */
271 ])
272
273 ;; Registers by name.
274 (define_constants
275 [(AX_REG 0)
276 (DX_REG 1)
277 (CX_REG 2)
278 (BX_REG 3)
279 (SI_REG 4)
280 (DI_REG 5)
281 (BP_REG 6)
282 (SP_REG 7)
283 (ST0_REG 8)
284 (ST1_REG 9)
285 (ST2_REG 10)
286 (ST3_REG 11)
287 (ST4_REG 12)
288 (ST5_REG 13)
289 (ST6_REG 14)
290 (ST7_REG 15)
291 (FLAGS_REG 17)
292 (FPSR_REG 18)
293 (FPCR_REG 19)
294 (XMM0_REG 21)
295 (XMM1_REG 22)
296 (XMM2_REG 23)
297 (XMM3_REG 24)
298 (XMM4_REG 25)
299 (XMM5_REG 26)
300 (XMM6_REG 27)
301 (XMM7_REG 28)
302 (MM0_REG 29)
303 (MM1_REG 30)
304 (MM2_REG 31)
305 (MM3_REG 32)
306 (MM4_REG 33)
307 (MM5_REG 34)
308 (MM6_REG 35)
309 (MM7_REG 36)
310 (R8_REG 37)
311 (R9_REG 38)
312 (R10_REG 39)
313 (R11_REG 40)
314 (R12_REG 41)
315 (R13_REG 42)
316 (R14_REG 43)
317 (R15_REG 44)
318 (XMM8_REG 45)
319 (XMM9_REG 46)
320 (XMM10_REG 47)
321 (XMM11_REG 48)
322 (XMM12_REG 49)
323 (XMM13_REG 50)
324 (XMM14_REG 51)
325 (XMM15_REG 52)
326 (XMM16_REG 53)
327 (XMM17_REG 54)
328 (XMM18_REG 55)
329 (XMM19_REG 56)
330 (XMM20_REG 57)
331 (XMM21_REG 58)
332 (XMM22_REG 59)
333 (XMM23_REG 60)
334 (XMM24_REG 61)
335 (XMM25_REG 62)
336 (XMM26_REG 63)
337 (XMM27_REG 64)
338 (XMM28_REG 65)
339 (XMM29_REG 66)
340 (XMM30_REG 67)
341 (XMM31_REG 68)
342 (MASK0_REG 69)
343 (MASK1_REG 70)
344 (MASK2_REG 71)
345 (MASK3_REG 72)
346 (MASK4_REG 73)
347 (MASK5_REG 74)
348 (MASK6_REG 75)
349 (MASK7_REG 76)
350 (BND0_REG 77)
351 (BND1_REG 78)
352 ])
353
354 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
355 ;; from i386.c.
356
357 ;; In C guard expressions, put expressions which may be compile-time
358 ;; constants first. This allows for better optimization. For
359 ;; example, write "TARGET_64BIT && reload_completed", not
360 ;; "reload_completed && TARGET_64BIT".
361
362 \f
363 ;; Processor type.
364 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
365 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
366 (const (symbol_ref "ix86_schedule")))
367
368 ;; A basic instruction type. Refinements due to arguments to be
369 ;; provided in other attributes.
370 (define_attr "type"
371 "other,multi,
372 alu,alu1,negnot,imov,imovx,lea,
373 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
374 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
375 push,pop,call,callv,leave,
376 str,bitmanip,
377 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
378 fxch,fistp,fisttp,frndint,
379 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
380 ssemul,sseimul,ssediv,sselog,sselog1,
381 sseishft,sseishft1,ssecmp,ssecomi,
382 ssecvt,ssecvt1,sseicvt,sseins,
383 sseshuf,sseshuf1,ssemuladd,sse4arg,
384 lwp,mskmov,msklog,
385 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
386 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
387 (const_string "other"))
388
389 ;; Main data type used by the insn
390 (define_attr "mode"
391 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
392 V2DF,V2SF,V1DF,V8DF"
393 (const_string "unknown"))
394
395 ;; The CPU unit operations uses.
396 (define_attr "unit" "integer,i387,sse,mmx,unknown"
397 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
398 fxch,fistp,fisttp,frndint")
399 (const_string "i387")
400 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
401 ssemul,sseimul,ssediv,sselog,sselog1,
402 sseishft,sseishft1,ssecmp,ssecomi,
403 ssecvt,ssecvt1,sseicvt,sseins,
404 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
405 (const_string "sse")
406 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
407 (const_string "mmx")
408 (eq_attr "type" "other")
409 (const_string "unknown")]
410 (const_string "integer")))
411
412 ;; The (bounding maximum) length of an instruction immediate.
413 (define_attr "length_immediate" ""
414 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
415 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
416 mpxld,mpxst")
417 (const_int 0)
418 (eq_attr "unit" "i387,sse,mmx")
419 (const_int 0)
420 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
421 rotate,rotatex,rotate1,imul,icmp,push,pop")
422 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
423 (eq_attr "type" "imov,test")
424 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
425 (eq_attr "type" "call")
426 (if_then_else (match_operand 0 "constant_call_address_operand")
427 (const_int 4)
428 (const_int 0))
429 (eq_attr "type" "callv")
430 (if_then_else (match_operand 1 "constant_call_address_operand")
431 (const_int 4)
432 (const_int 0))
433 ;; We don't know the size before shorten_branches. Expect
434 ;; the instruction to fit for better scheduling.
435 (eq_attr "type" "ibr")
436 (const_int 1)
437 ]
438 (symbol_ref "/* Update immediate_length and other attributes! */
439 gcc_unreachable (),1")))
440
441 ;; The (bounding maximum) length of an instruction address.
442 (define_attr "length_address" ""
443 (cond [(eq_attr "type" "str,other,multi,fxch")
444 (const_int 0)
445 (and (eq_attr "type" "call")
446 (match_operand 0 "constant_call_address_operand"))
447 (const_int 0)
448 (and (eq_attr "type" "callv")
449 (match_operand 1 "constant_call_address_operand"))
450 (const_int 0)
451 ]
452 (symbol_ref "ix86_attr_length_address_default (insn)")))
453
454 ;; Set when length prefix is used.
455 (define_attr "prefix_data16" ""
456 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
457 (const_int 0)
458 (eq_attr "mode" "HI")
459 (const_int 1)
460 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
461 (const_int 1)
462 ]
463 (const_int 0)))
464
465 ;; Set when string REP prefix is used.
466 (define_attr "prefix_rep" ""
467 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
468 (const_int 0)
469 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
470 (const_int 1)
471 (and (eq_attr "type" "ibr,call,callv")
472 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
473 (const_int 1)
474 ]
475 (const_int 0)))
476
477 ;; Set when 0f opcode prefix is used.
478 (define_attr "prefix_0f" ""
479 (if_then_else
480 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
481 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
482 (eq_attr "unit" "sse,mmx"))
483 (const_int 1)
484 (const_int 0)))
485
486 ;; Set when REX opcode prefix is used.
487 (define_attr "prefix_rex" ""
488 (cond [(not (match_test "TARGET_64BIT"))
489 (const_int 0)
490 (and (eq_attr "mode" "DI")
491 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
492 (eq_attr "unit" "!mmx")))
493 (const_int 1)
494 (and (eq_attr "mode" "QI")
495 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
496 (const_int 1)
497 (match_test "x86_extended_reg_mentioned_p (insn)")
498 (const_int 1)
499 (and (eq_attr "type" "imovx")
500 (match_operand:QI 1 "ext_QIreg_operand"))
501 (const_int 1)
502 ]
503 (const_int 0)))
504
505 ;; There are also additional prefixes in 3DNOW, SSSE3.
506 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
507 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
508 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
509 (define_attr "prefix_extra" ""
510 (cond [(eq_attr "type" "ssemuladd,sse4arg")
511 (const_int 2)
512 (eq_attr "type" "sseiadd1,ssecvt1")
513 (const_int 1)
514 ]
515 (const_int 0)))
516
517 ;; Prefix used: original, VEX or maybe VEX.
518 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
519 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
520 (const_string "vex")
521 (eq_attr "mode" "XI,V16SF,V8DF")
522 (const_string "evex")
523 ]
524 (const_string "orig")))
525
526 ;; VEX W bit is used.
527 (define_attr "prefix_vex_w" "" (const_int 0))
528
529 ;; The length of VEX prefix
530 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
531 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
532 ;; still prefix_0f 1, with prefix_extra 1.
533 (define_attr "length_vex" ""
534 (if_then_else (and (eq_attr "prefix_0f" "1")
535 (eq_attr "prefix_extra" "0"))
536 (if_then_else (eq_attr "prefix_vex_w" "1")
537 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
538 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
539 (if_then_else (eq_attr "prefix_vex_w" "1")
540 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
541 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
542
543 ;; 4-bytes evex prefix and 1 byte opcode.
544 (define_attr "length_evex" "" (const_int 5))
545
546 ;; Set when modrm byte is used.
547 (define_attr "modrm" ""
548 (cond [(eq_attr "type" "str,leave")
549 (const_int 0)
550 (eq_attr "unit" "i387")
551 (const_int 0)
552 (and (eq_attr "type" "incdec")
553 (and (not (match_test "TARGET_64BIT"))
554 (ior (match_operand:SI 1 "register_operand")
555 (match_operand:HI 1 "register_operand"))))
556 (const_int 0)
557 (and (eq_attr "type" "push")
558 (not (match_operand 1 "memory_operand")))
559 (const_int 0)
560 (and (eq_attr "type" "pop")
561 (not (match_operand 0 "memory_operand")))
562 (const_int 0)
563 (and (eq_attr "type" "imov")
564 (and (not (eq_attr "mode" "DI"))
565 (ior (and (match_operand 0 "register_operand")
566 (match_operand 1 "immediate_operand"))
567 (ior (and (match_operand 0 "ax_reg_operand")
568 (match_operand 1 "memory_displacement_only_operand"))
569 (and (match_operand 0 "memory_displacement_only_operand")
570 (match_operand 1 "ax_reg_operand"))))))
571 (const_int 0)
572 (and (eq_attr "type" "call")
573 (match_operand 0 "constant_call_address_operand"))
574 (const_int 0)
575 (and (eq_attr "type" "callv")
576 (match_operand 1 "constant_call_address_operand"))
577 (const_int 0)
578 (and (eq_attr "type" "alu,alu1,icmp,test")
579 (match_operand 0 "ax_reg_operand"))
580 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
581 ]
582 (const_int 1)))
583
584 ;; When this attribute is set, calculate total insn length from
585 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
586 (define_attr "length_nobnd" "" (const_int 0))
587
588 ;; The (bounding maximum) length of an instruction in bytes.
589 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
590 ;; Later we may want to split them and compute proper length as for
591 ;; other insns.
592 (define_attr "length" ""
593 (cond [(eq_attr "length_nobnd" "!0")
594 (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
595 (attr "length_nobnd"))
596 (eq_attr "type" "other,multi,fistp,frndint")
597 (const_int 16)
598 (eq_attr "type" "fcmp")
599 (const_int 4)
600 (eq_attr "unit" "i387")
601 (plus (const_int 2)
602 (plus (attr "prefix_data16")
603 (attr "length_address")))
604 (ior (eq_attr "prefix" "evex")
605 (and (ior (eq_attr "prefix" "maybe_evex")
606 (eq_attr "prefix" "maybe_vex"))
607 (match_test "TARGET_AVX512F")))
608 (plus (attr "length_evex")
609 (plus (attr "length_immediate")
610 (plus (attr "modrm")
611 (attr "length_address"))))
612 (ior (eq_attr "prefix" "vex")
613 (and (ior (eq_attr "prefix" "maybe_vex")
614 (eq_attr "prefix" "maybe_evex"))
615 (match_test "TARGET_AVX")))
616 (plus (attr "length_vex")
617 (plus (attr "length_immediate")
618 (plus (attr "modrm")
619 (attr "length_address"))))]
620 (plus (plus (attr "modrm")
621 (plus (attr "prefix_0f")
622 (plus (attr "prefix_rex")
623 (plus (attr "prefix_extra")
624 (const_int 1)))))
625 (plus (attr "prefix_rep")
626 (plus (attr "prefix_data16")
627 (plus (attr "length_immediate")
628 (attr "length_address")))))))
629
630 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
631 ;; `store' if there is a simple memory reference therein, or `unknown'
632 ;; if the instruction is complex.
633
634 (define_attr "memory" "none,load,store,both,unknown"
635 (cond [(eq_attr "type" "other,multi,str,lwp")
636 (const_string "unknown")
637 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
638 (const_string "none")
639 (eq_attr "type" "fistp,leave")
640 (const_string "both")
641 (eq_attr "type" "frndint")
642 (const_string "load")
643 (eq_attr "type" "mpxld")
644 (const_string "load")
645 (eq_attr "type" "mpxst")
646 (const_string "store")
647 (eq_attr "type" "push")
648 (if_then_else (match_operand 1 "memory_operand")
649 (const_string "both")
650 (const_string "store"))
651 (eq_attr "type" "pop")
652 (if_then_else (match_operand 0 "memory_operand")
653 (const_string "both")
654 (const_string "load"))
655 (eq_attr "type" "setcc")
656 (if_then_else (match_operand 0 "memory_operand")
657 (const_string "store")
658 (const_string "none"))
659 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
660 (if_then_else (ior (match_operand 0 "memory_operand")
661 (match_operand 1 "memory_operand"))
662 (const_string "load")
663 (const_string "none"))
664 (eq_attr "type" "ibr")
665 (if_then_else (match_operand 0 "memory_operand")
666 (const_string "load")
667 (const_string "none"))
668 (eq_attr "type" "call")
669 (if_then_else (match_operand 0 "constant_call_address_operand")
670 (const_string "none")
671 (const_string "load"))
672 (eq_attr "type" "callv")
673 (if_then_else (match_operand 1 "constant_call_address_operand")
674 (const_string "none")
675 (const_string "load"))
676 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
677 (match_operand 1 "memory_operand"))
678 (const_string "both")
679 (and (match_operand 0 "memory_operand")
680 (match_operand 1 "memory_operand"))
681 (const_string "both")
682 (match_operand 0 "memory_operand")
683 (const_string "store")
684 (match_operand 1 "memory_operand")
685 (const_string "load")
686 (and (eq_attr "type"
687 "!alu1,negnot,ishift1,
688 imov,imovx,icmp,test,bitmanip,
689 fmov,fcmp,fsgn,
690 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
691 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
692 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
693 (match_operand 2 "memory_operand"))
694 (const_string "load")
695 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
696 (match_operand 3 "memory_operand"))
697 (const_string "load")
698 ]
699 (const_string "none")))
700
701 ;; Indicates if an instruction has both an immediate and a displacement.
702
703 (define_attr "imm_disp" "false,true,unknown"
704 (cond [(eq_attr "type" "other,multi")
705 (const_string "unknown")
706 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
707 (and (match_operand 0 "memory_displacement_operand")
708 (match_operand 1 "immediate_operand")))
709 (const_string "true")
710 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
711 (and (match_operand 0 "memory_displacement_operand")
712 (match_operand 2 "immediate_operand")))
713 (const_string "true")
714 ]
715 (const_string "false")))
716
717 ;; Indicates if an FP operation has an integer source.
718
719 (define_attr "fp_int_src" "false,true"
720 (const_string "false"))
721
722 ;; Defines rounding mode of an FP operation.
723
724 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
725 (const_string "any"))
726
727 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
728 (define_attr "use_carry" "0,1" (const_string "0"))
729
730 ;; Define attribute to indicate unaligned ssemov insns
731 (define_attr "movu" "0,1" (const_string "0"))
732
733 ;; Used to control the "enabled" attribute on a per-instruction basis.
734 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
735 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
736 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f"
737 (const_string "base"))
738
739 (define_attr "enabled" ""
740 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
741 (eq_attr "isa" "x64_sse4")
742 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
743 (eq_attr "isa" "x64_sse4_noavx")
744 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
745 (eq_attr "isa" "x64_avx")
746 (symbol_ref "TARGET_64BIT && TARGET_AVX")
747 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
748 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
749 (eq_attr "isa" "sse2_noavx")
750 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
751 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
752 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
753 (eq_attr "isa" "sse4_noavx")
754 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
755 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
756 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
757 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
758 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
759 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
760 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
761 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
762 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
763 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
764 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
765 (eq_attr "isa" "fma_avx512f")
766 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
767 ]
768 (const_int 1)))
769
770 ;; Describe a user's asm statement.
771 (define_asm_attributes
772 [(set_attr "length" "128")
773 (set_attr "type" "multi")])
774
775 (define_code_iterator plusminus [plus minus])
776
777 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
778
779 (define_code_iterator multdiv [mult div])
780
781 ;; Base name for define_insn
782 (define_code_attr plusminus_insn
783 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
784 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
785
786 ;; Base name for insn mnemonic.
787 (define_code_attr plusminus_mnemonic
788 [(plus "add") (ss_plus "adds") (us_plus "addus")
789 (minus "sub") (ss_minus "subs") (us_minus "subus")])
790 (define_code_attr plusminus_carry_mnemonic
791 [(plus "adc") (minus "sbb")])
792 (define_code_attr multdiv_mnemonic
793 [(mult "mul") (div "div")])
794
795 ;; Mark commutative operators as such in constraints.
796 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
797 (minus "") (ss_minus "") (us_minus "")])
798
799 ;; Mapping of max and min
800 (define_code_iterator maxmin [smax smin umax umin])
801
802 ;; Mapping of signed max and min
803 (define_code_iterator smaxmin [smax smin])
804
805 ;; Mapping of unsigned max and min
806 (define_code_iterator umaxmin [umax umin])
807
808 ;; Base name for integer and FP insn mnemonic
809 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
810 (umax "maxu") (umin "minu")])
811 (define_code_attr maxmin_float [(smax "max") (smin "min")])
812
813 ;; Mapping of logic operators
814 (define_code_iterator any_logic [and ior xor])
815 (define_code_iterator any_or [ior xor])
816 (define_code_iterator fpint_logic [and xor])
817
818 ;; Base name for insn mnemonic.
819 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
820
821 ;; Mapping of logic-shift operators
822 (define_code_iterator any_lshift [ashift lshiftrt])
823
824 ;; Mapping of shift-right operators
825 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
826
827 ;; Mapping of all shift operators
828 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
829
830 ;; Base name for define_insn
831 (define_code_attr shift_insn
832 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
833
834 ;; Base name for insn mnemonic.
835 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
836 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
837
838 ;; Mapping of rotate operators
839 (define_code_iterator any_rotate [rotate rotatert])
840
841 ;; Base name for define_insn
842 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
843
844 ;; Base name for insn mnemonic.
845 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
846
847 ;; Mapping of abs neg operators
848 (define_code_iterator absneg [abs neg])
849
850 ;; Base name for x87 insn mnemonic.
851 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
852
853 ;; Used in signed and unsigned widening multiplications.
854 (define_code_iterator any_extend [sign_extend zero_extend])
855
856 ;; Prefix for insn menmonic.
857 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
858
859 ;; Prefix for define_insn
860 (define_code_attr u [(sign_extend "") (zero_extend "u")])
861 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
862 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
863
864 ;; Used in signed and unsigned truncations.
865 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
866 ;; Instruction suffix for truncations.
867 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
868
869 ;; Used in signed and unsigned fix.
870 (define_code_iterator any_fix [fix unsigned_fix])
871 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
872
873 ;; All integer modes.
874 (define_mode_iterator SWI1248x [QI HI SI DI])
875
876 ;; All integer modes without QImode.
877 (define_mode_iterator SWI248x [HI SI DI])
878
879 ;; All integer modes without QImode and HImode.
880 (define_mode_iterator SWI48x [SI DI])
881
882 ;; All integer modes without SImode and DImode.
883 (define_mode_iterator SWI12 [QI HI])
884
885 ;; All integer modes without DImode.
886 (define_mode_iterator SWI124 [QI HI SI])
887
888 ;; All integer modes without QImode and DImode.
889 (define_mode_iterator SWI24 [HI SI])
890
891 ;; Single word integer modes.
892 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
893
894 ;; Single word integer modes without QImode.
895 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
896
897 ;; Single word integer modes without QImode and HImode.
898 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
899
900 ;; All math-dependant single and double word integer modes.
901 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
902 (HI "TARGET_HIMODE_MATH")
903 SI DI (TI "TARGET_64BIT")])
904
905 ;; Math-dependant single word integer modes.
906 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
907 (HI "TARGET_HIMODE_MATH")
908 SI (DI "TARGET_64BIT")])
909
910 ;; Math-dependant integer modes without DImode.
911 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
912 (HI "TARGET_HIMODE_MATH")
913 SI])
914
915 ;; Math-dependant single word integer modes without QImode.
916 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
917 SI (DI "TARGET_64BIT")])
918
919 ;; Double word integer modes.
920 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
921 (TI "TARGET_64BIT")])
922
923 ;; Double word integer modes as mode attribute.
924 (define_mode_attr DWI [(SI "DI") (DI "TI")])
925 (define_mode_attr dwi [(SI "di") (DI "ti")])
926
927 ;; Half mode for double word integer modes.
928 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
929 (DI "TARGET_64BIT")])
930
931 ;; Bound modes.
932 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
933 (BND64 "TARGET_LP64")])
934
935 ;; Pointer mode corresponding to bound mode.
936 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
937
938 ;; MPX check types
939 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
940
941 ;; Check name
942 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
943 (UNSPEC_BNDCU "cu")
944 (UNSPEC_BNDCN "cn")])
945
946 ;; Instruction suffix for integer modes.
947 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
948
949 ;; Pointer size prefix for integer modes (Intel asm dialect)
950 (define_mode_attr iptrsize [(QI "BYTE")
951 (HI "WORD")
952 (SI "DWORD")
953 (DI "QWORD")])
954
955 ;; Register class for integer modes.
956 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
957
958 ;; Immediate operand constraint for integer modes.
959 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
960
961 ;; General operand constraint for word modes.
962 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
963
964 ;; Immediate operand constraint for double integer modes.
965 (define_mode_attr di [(SI "nF") (DI "e")])
966
967 ;; Immediate operand constraint for shifts.
968 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
969
970 ;; General operand predicate for integer modes.
971 (define_mode_attr general_operand
972 [(QI "general_operand")
973 (HI "general_operand")
974 (SI "x86_64_general_operand")
975 (DI "x86_64_general_operand")
976 (TI "x86_64_general_operand")])
977
978 ;; General sign/zero extend operand predicate for integer modes.
979 (define_mode_attr general_szext_operand
980 [(QI "general_operand")
981 (HI "general_operand")
982 (SI "x86_64_szext_general_operand")
983 (DI "x86_64_szext_general_operand")])
984
985 ;; Immediate operand predicate for integer modes.
986 (define_mode_attr immediate_operand
987 [(QI "immediate_operand")
988 (HI "immediate_operand")
989 (SI "x86_64_immediate_operand")
990 (DI "x86_64_immediate_operand")])
991
992 ;; Nonmemory operand predicate for integer modes.
993 (define_mode_attr nonmemory_operand
994 [(QI "nonmemory_operand")
995 (HI "nonmemory_operand")
996 (SI "x86_64_nonmemory_operand")
997 (DI "x86_64_nonmemory_operand")])
998
999 ;; Operand predicate for shifts.
1000 (define_mode_attr shift_operand
1001 [(QI "nonimmediate_operand")
1002 (HI "nonimmediate_operand")
1003 (SI "nonimmediate_operand")
1004 (DI "shiftdi_operand")
1005 (TI "register_operand")])
1006
1007 ;; Operand predicate for shift argument.
1008 (define_mode_attr shift_immediate_operand
1009 [(QI "const_1_to_31_operand")
1010 (HI "const_1_to_31_operand")
1011 (SI "const_1_to_31_operand")
1012 (DI "const_1_to_63_operand")])
1013
1014 ;; Input operand predicate for arithmetic left shifts.
1015 (define_mode_attr ashl_input_operand
1016 [(QI "nonimmediate_operand")
1017 (HI "nonimmediate_operand")
1018 (SI "nonimmediate_operand")
1019 (DI "ashldi_input_operand")
1020 (TI "reg_or_pm1_operand")])
1021
1022 ;; SSE and x87 SFmode and DFmode floating point modes
1023 (define_mode_iterator MODEF [SF DF])
1024
1025 ;; All x87 floating point modes
1026 (define_mode_iterator X87MODEF [SF DF XF])
1027
1028 ;; SSE instruction suffix for various modes
1029 (define_mode_attr ssemodesuffix
1030 [(SF "ss") (DF "sd")
1031 (V16SF "ps") (V8DF "pd")
1032 (V8SF "ps") (V4DF "pd")
1033 (V4SF "ps") (V2DF "pd")
1034 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1035 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1036 (V64QI "b") (V16SI "d") (V8DI "q")])
1037
1038 ;; SSE vector suffix for floating point modes
1039 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1040
1041 ;; SSE vector mode corresponding to a scalar mode
1042 (define_mode_attr ssevecmode
1043 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1044 (define_mode_attr ssevecmodelower
1045 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1046
1047 ;; Instruction suffix for REX 64bit operators.
1048 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1049
1050 ;; This mode iterator allows :P to be used for patterns that operate on
1051 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1052 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1053
1054 ;; This mode iterator allows :W to be used for patterns that operate on
1055 ;; word_mode sized quantities.
1056 (define_mode_iterator W
1057 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1058
1059 ;; This mode iterator allows :PTR to be used for patterns that operate on
1060 ;; ptr_mode sized quantities.
1061 (define_mode_iterator PTR
1062 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1063 \f
1064 ;; Scheduling descriptions
1065
1066 (include "pentium.md")
1067 (include "ppro.md")
1068 (include "k6.md")
1069 (include "athlon.md")
1070 (include "bdver1.md")
1071 (include "bdver3.md")
1072 (include "btver2.md")
1073 (include "geode.md")
1074 (include "atom.md")
1075 (include "slm.md")
1076 (include "core2.md")
1077
1078 \f
1079 ;; Operand and operator predicates and constraints
1080
1081 (include "predicates.md")
1082 (include "constraints.md")
1083
1084 \f
1085 ;; Compare and branch/compare and store instructions.
1086
1087 (define_expand "cbranch<mode>4"
1088 [(set (reg:CC FLAGS_REG)
1089 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1090 (match_operand:SDWIM 2 "<general_operand>")))
1091 (set (pc) (if_then_else
1092 (match_operator 0 "ordered_comparison_operator"
1093 [(reg:CC FLAGS_REG) (const_int 0)])
1094 (label_ref (match_operand 3))
1095 (pc)))]
1096 ""
1097 {
1098 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1099 operands[1] = force_reg (<MODE>mode, operands[1]);
1100 ix86_expand_branch (GET_CODE (operands[0]),
1101 operands[1], operands[2], operands[3]);
1102 DONE;
1103 })
1104
1105 (define_expand "cstore<mode>4"
1106 [(set (reg:CC FLAGS_REG)
1107 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1108 (match_operand:SWIM 3 "<general_operand>")))
1109 (set (match_operand:QI 0 "register_operand")
1110 (match_operator 1 "ordered_comparison_operator"
1111 [(reg:CC FLAGS_REG) (const_int 0)]))]
1112 ""
1113 {
1114 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1115 operands[2] = force_reg (<MODE>mode, operands[2]);
1116 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1117 operands[2], operands[3]);
1118 DONE;
1119 })
1120
1121 (define_expand "cmp<mode>_1"
1122 [(set (reg:CC FLAGS_REG)
1123 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1124 (match_operand:SWI48 1 "<general_operand>")))])
1125
1126 (define_insn "*cmp<mode>_ccno_1"
1127 [(set (reg FLAGS_REG)
1128 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1129 (match_operand:SWI 1 "const0_operand")))]
1130 "ix86_match_ccmode (insn, CCNOmode)"
1131 "@
1132 test{<imodesuffix>}\t%0, %0
1133 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1134 [(set_attr "type" "test,icmp")
1135 (set_attr "length_immediate" "0,1")
1136 (set_attr "mode" "<MODE>")])
1137
1138 (define_insn "*cmp<mode>_1"
1139 [(set (reg FLAGS_REG)
1140 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1141 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1142 "ix86_match_ccmode (insn, CCmode)"
1143 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1144 [(set_attr "type" "icmp")
1145 (set_attr "mode" "<MODE>")])
1146
1147 (define_insn "*cmp<mode>_minus_1"
1148 [(set (reg FLAGS_REG)
1149 (compare
1150 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1151 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1152 (const_int 0)))]
1153 "ix86_match_ccmode (insn, CCGOCmode)"
1154 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1155 [(set_attr "type" "icmp")
1156 (set_attr "mode" "<MODE>")])
1157
1158 (define_insn "*cmpqi_ext_1"
1159 [(set (reg FLAGS_REG)
1160 (compare
1161 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1162 (subreg:QI
1163 (zero_extract:SI
1164 (match_operand 1 "ext_register_operand" "Q,Q")
1165 (const_int 8)
1166 (const_int 8)) 0)))]
1167 "ix86_match_ccmode (insn, CCmode)"
1168 "cmp{b}\t{%h1, %0|%0, %h1}"
1169 [(set_attr "isa" "*,nox64")
1170 (set_attr "type" "icmp")
1171 (set_attr "mode" "QI")])
1172
1173 (define_insn "*cmpqi_ext_2"
1174 [(set (reg FLAGS_REG)
1175 (compare
1176 (subreg:QI
1177 (zero_extract:SI
1178 (match_operand 0 "ext_register_operand" "Q")
1179 (const_int 8)
1180 (const_int 8)) 0)
1181 (match_operand:QI 1 "const0_operand")))]
1182 "ix86_match_ccmode (insn, CCNOmode)"
1183 "test{b}\t%h0, %h0"
1184 [(set_attr "type" "test")
1185 (set_attr "length_immediate" "0")
1186 (set_attr "mode" "QI")])
1187
1188 (define_expand "cmpqi_ext_3"
1189 [(set (reg:CC FLAGS_REG)
1190 (compare:CC
1191 (subreg:QI
1192 (zero_extract:SI
1193 (match_operand 0 "ext_register_operand")
1194 (const_int 8)
1195 (const_int 8)) 0)
1196 (match_operand:QI 1 "const_int_operand")))])
1197
1198 (define_insn "*cmpqi_ext_3"
1199 [(set (reg FLAGS_REG)
1200 (compare
1201 (subreg:QI
1202 (zero_extract:SI
1203 (match_operand 0 "ext_register_operand" "Q,Q")
1204 (const_int 8)
1205 (const_int 8)) 0)
1206 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1207 "ix86_match_ccmode (insn, CCmode)"
1208 "cmp{b}\t{%1, %h0|%h0, %1}"
1209 [(set_attr "isa" "*,nox64")
1210 (set_attr "type" "icmp")
1211 (set_attr "modrm" "1")
1212 (set_attr "mode" "QI")])
1213
1214 (define_insn "*cmpqi_ext_4"
1215 [(set (reg FLAGS_REG)
1216 (compare
1217 (subreg:QI
1218 (zero_extract:SI
1219 (match_operand 0 "ext_register_operand" "Q")
1220 (const_int 8)
1221 (const_int 8)) 0)
1222 (subreg:QI
1223 (zero_extract:SI
1224 (match_operand 1 "ext_register_operand" "Q")
1225 (const_int 8)
1226 (const_int 8)) 0)))]
1227 "ix86_match_ccmode (insn, CCmode)"
1228 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1229 [(set_attr "type" "icmp")
1230 (set_attr "mode" "QI")])
1231
1232 ;; These implement float point compares.
1233 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1234 ;; which would allow mix and match FP modes on the compares. Which is what
1235 ;; the old patterns did, but with many more of them.
1236
1237 (define_expand "cbranchxf4"
1238 [(set (reg:CC FLAGS_REG)
1239 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1240 (match_operand:XF 2 "nonmemory_operand")))
1241 (set (pc) (if_then_else
1242 (match_operator 0 "ix86_fp_comparison_operator"
1243 [(reg:CC FLAGS_REG)
1244 (const_int 0)])
1245 (label_ref (match_operand 3))
1246 (pc)))]
1247 "TARGET_80387"
1248 {
1249 ix86_expand_branch (GET_CODE (operands[0]),
1250 operands[1], operands[2], operands[3]);
1251 DONE;
1252 })
1253
1254 (define_expand "cstorexf4"
1255 [(set (reg:CC FLAGS_REG)
1256 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1257 (match_operand:XF 3 "nonmemory_operand")))
1258 (set (match_operand:QI 0 "register_operand")
1259 (match_operator 1 "ix86_fp_comparison_operator"
1260 [(reg:CC FLAGS_REG)
1261 (const_int 0)]))]
1262 "TARGET_80387"
1263 {
1264 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1265 operands[2], operands[3]);
1266 DONE;
1267 })
1268
1269 (define_expand "cbranch<mode>4"
1270 [(set (reg:CC FLAGS_REG)
1271 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1272 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1273 (set (pc) (if_then_else
1274 (match_operator 0 "ix86_fp_comparison_operator"
1275 [(reg:CC FLAGS_REG)
1276 (const_int 0)])
1277 (label_ref (match_operand 3))
1278 (pc)))]
1279 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1280 {
1281 ix86_expand_branch (GET_CODE (operands[0]),
1282 operands[1], operands[2], operands[3]);
1283 DONE;
1284 })
1285
1286 (define_expand "cstore<mode>4"
1287 [(set (reg:CC FLAGS_REG)
1288 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1289 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1290 (set (match_operand:QI 0 "register_operand")
1291 (match_operator 1 "ix86_fp_comparison_operator"
1292 [(reg:CC FLAGS_REG)
1293 (const_int 0)]))]
1294 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1295 {
1296 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1297 operands[2], operands[3]);
1298 DONE;
1299 })
1300
1301 (define_expand "cbranchcc4"
1302 [(set (pc) (if_then_else
1303 (match_operator 0 "comparison_operator"
1304 [(match_operand 1 "flags_reg_operand")
1305 (match_operand 2 "const0_operand")])
1306 (label_ref (match_operand 3))
1307 (pc)))]
1308 ""
1309 {
1310 ix86_expand_branch (GET_CODE (operands[0]),
1311 operands[1], operands[2], operands[3]);
1312 DONE;
1313 })
1314
1315 (define_expand "cstorecc4"
1316 [(set (match_operand:QI 0 "register_operand")
1317 (match_operator 1 "comparison_operator"
1318 [(match_operand 2 "flags_reg_operand")
1319 (match_operand 3 "const0_operand")]))]
1320 ""
1321 {
1322 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1323 operands[2], operands[3]);
1324 DONE;
1325 })
1326
1327
1328 ;; FP compares, step 1:
1329 ;; Set the FP condition codes.
1330 ;;
1331 ;; CCFPmode compare with exceptions
1332 ;; CCFPUmode compare with no exceptions
1333
1334 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1335 ;; used to manage the reg stack popping would not be preserved.
1336
1337 (define_insn "*cmp<mode>_0_i387"
1338 [(set (match_operand:HI 0 "register_operand" "=a")
1339 (unspec:HI
1340 [(compare:CCFP
1341 (match_operand:X87MODEF 1 "register_operand" "f")
1342 (match_operand:X87MODEF 2 "const0_operand"))]
1343 UNSPEC_FNSTSW))]
1344 "TARGET_80387"
1345 "* return output_fp_compare (insn, operands, false, false);"
1346 [(set_attr "type" "multi")
1347 (set_attr "unit" "i387")
1348 (set_attr "mode" "<MODE>")])
1349
1350 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1351 [(set (reg:CCFP FLAGS_REG)
1352 (compare:CCFP
1353 (match_operand:X87MODEF 1 "register_operand" "f")
1354 (match_operand:X87MODEF 2 "const0_operand")))
1355 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1356 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1357 "#"
1358 "&& reload_completed"
1359 [(set (match_dup 0)
1360 (unspec:HI
1361 [(compare:CCFP (match_dup 1)(match_dup 2))]
1362 UNSPEC_FNSTSW))
1363 (set (reg:CC FLAGS_REG)
1364 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1365 ""
1366 [(set_attr "type" "multi")
1367 (set_attr "unit" "i387")
1368 (set_attr "mode" "<MODE>")])
1369
1370 (define_insn "*cmpxf_i387"
1371 [(set (match_operand:HI 0 "register_operand" "=a")
1372 (unspec:HI
1373 [(compare:CCFP
1374 (match_operand:XF 1 "register_operand" "f")
1375 (match_operand:XF 2 "register_operand" "f"))]
1376 UNSPEC_FNSTSW))]
1377 "TARGET_80387"
1378 "* return output_fp_compare (insn, operands, false, false);"
1379 [(set_attr "type" "multi")
1380 (set_attr "unit" "i387")
1381 (set_attr "mode" "XF")])
1382
1383 (define_insn_and_split "*cmpxf_cc_i387"
1384 [(set (reg:CCFP FLAGS_REG)
1385 (compare:CCFP
1386 (match_operand:XF 1 "register_operand" "f")
1387 (match_operand:XF 2 "register_operand" "f")))
1388 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1389 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1390 "#"
1391 "&& reload_completed"
1392 [(set (match_dup 0)
1393 (unspec:HI
1394 [(compare:CCFP (match_dup 1)(match_dup 2))]
1395 UNSPEC_FNSTSW))
1396 (set (reg:CC FLAGS_REG)
1397 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1398 ""
1399 [(set_attr "type" "multi")
1400 (set_attr "unit" "i387")
1401 (set_attr "mode" "XF")])
1402
1403 (define_insn "*cmp<mode>_i387"
1404 [(set (match_operand:HI 0 "register_operand" "=a")
1405 (unspec:HI
1406 [(compare:CCFP
1407 (match_operand:MODEF 1 "register_operand" "f")
1408 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1409 UNSPEC_FNSTSW))]
1410 "TARGET_80387"
1411 "* return output_fp_compare (insn, operands, false, false);"
1412 [(set_attr "type" "multi")
1413 (set_attr "unit" "i387")
1414 (set_attr "mode" "<MODE>")])
1415
1416 (define_insn_and_split "*cmp<mode>_cc_i387"
1417 [(set (reg:CCFP FLAGS_REG)
1418 (compare:CCFP
1419 (match_operand:MODEF 1 "register_operand" "f")
1420 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1421 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1422 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1423 "#"
1424 "&& reload_completed"
1425 [(set (match_dup 0)
1426 (unspec:HI
1427 [(compare:CCFP (match_dup 1)(match_dup 2))]
1428 UNSPEC_FNSTSW))
1429 (set (reg:CC FLAGS_REG)
1430 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1431 ""
1432 [(set_attr "type" "multi")
1433 (set_attr "unit" "i387")
1434 (set_attr "mode" "<MODE>")])
1435
1436 (define_insn "*cmpu<mode>_i387"
1437 [(set (match_operand:HI 0 "register_operand" "=a")
1438 (unspec:HI
1439 [(compare:CCFPU
1440 (match_operand:X87MODEF 1 "register_operand" "f")
1441 (match_operand:X87MODEF 2 "register_operand" "f"))]
1442 UNSPEC_FNSTSW))]
1443 "TARGET_80387"
1444 "* return output_fp_compare (insn, operands, false, true);"
1445 [(set_attr "type" "multi")
1446 (set_attr "unit" "i387")
1447 (set_attr "mode" "<MODE>")])
1448
1449 (define_insn_and_split "*cmpu<mode>_cc_i387"
1450 [(set (reg:CCFPU FLAGS_REG)
1451 (compare:CCFPU
1452 (match_operand:X87MODEF 1 "register_operand" "f")
1453 (match_operand:X87MODEF 2 "register_operand" "f")))
1454 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1455 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1456 "#"
1457 "&& reload_completed"
1458 [(set (match_dup 0)
1459 (unspec:HI
1460 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1461 UNSPEC_FNSTSW))
1462 (set (reg:CC FLAGS_REG)
1463 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1464 ""
1465 [(set_attr "type" "multi")
1466 (set_attr "unit" "i387")
1467 (set_attr "mode" "<MODE>")])
1468
1469 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1470 [(set (match_operand:HI 0 "register_operand" "=a")
1471 (unspec:HI
1472 [(compare:CCFP
1473 (match_operand:X87MODEF 1 "register_operand" "f")
1474 (match_operator:X87MODEF 3 "float_operator"
1475 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1476 UNSPEC_FNSTSW))]
1477 "TARGET_80387
1478 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1479 || optimize_function_for_size_p (cfun))"
1480 "* return output_fp_compare (insn, operands, false, false);"
1481 [(set_attr "type" "multi")
1482 (set_attr "unit" "i387")
1483 (set_attr "fp_int_src" "true")
1484 (set_attr "mode" "<SWI24:MODE>")])
1485
1486 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1487 [(set (reg:CCFP FLAGS_REG)
1488 (compare:CCFP
1489 (match_operand:X87MODEF 1 "register_operand" "f")
1490 (match_operator:X87MODEF 3 "float_operator"
1491 [(match_operand:SWI24 2 "memory_operand" "m")])))
1492 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1493 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1494 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1495 || optimize_function_for_size_p (cfun))"
1496 "#"
1497 "&& reload_completed"
1498 [(set (match_dup 0)
1499 (unspec:HI
1500 [(compare:CCFP
1501 (match_dup 1)
1502 (match_op_dup 3 [(match_dup 2)]))]
1503 UNSPEC_FNSTSW))
1504 (set (reg:CC FLAGS_REG)
1505 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1506 ""
1507 [(set_attr "type" "multi")
1508 (set_attr "unit" "i387")
1509 (set_attr "fp_int_src" "true")
1510 (set_attr "mode" "<SWI24:MODE>")])
1511
1512 ;; FP compares, step 2
1513 ;; Move the fpsw to ax.
1514
1515 (define_insn "x86_fnstsw_1"
1516 [(set (match_operand:HI 0 "register_operand" "=a")
1517 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1518 "TARGET_80387"
1519 "fnstsw\t%0"
1520 [(set (attr "length")
1521 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1522 (set_attr "mode" "SI")
1523 (set_attr "unit" "i387")])
1524
1525 ;; FP compares, step 3
1526 ;; Get ax into flags, general case.
1527
1528 (define_insn "x86_sahf_1"
1529 [(set (reg:CC FLAGS_REG)
1530 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1531 UNSPEC_SAHF))]
1532 "TARGET_SAHF"
1533 {
1534 #ifndef HAVE_AS_IX86_SAHF
1535 if (TARGET_64BIT)
1536 return ASM_BYTE "0x9e";
1537 else
1538 #endif
1539 return "sahf";
1540 }
1541 [(set_attr "length" "1")
1542 (set_attr "athlon_decode" "vector")
1543 (set_attr "amdfam10_decode" "direct")
1544 (set_attr "bdver1_decode" "direct")
1545 (set_attr "mode" "SI")])
1546
1547 ;; Pentium Pro can do steps 1 through 3 in one go.
1548 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1549 ;; (these i387 instructions set flags directly)
1550
1551 (define_mode_iterator FPCMP [CCFP CCFPU])
1552 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1553
1554 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1555 [(set (reg:FPCMP FLAGS_REG)
1556 (compare:FPCMP
1557 (match_operand:MODEF 0 "register_operand" "f,x")
1558 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1559 "TARGET_MIX_SSE_I387
1560 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1561 "* return output_fp_compare (insn, operands, true,
1562 <FPCMP:MODE>mode == CCFPUmode);"
1563 [(set_attr "type" "fcmp,ssecomi")
1564 (set_attr "prefix" "orig,maybe_vex")
1565 (set_attr "mode" "<MODEF:MODE>")
1566 (set (attr "prefix_rep")
1567 (if_then_else (eq_attr "type" "ssecomi")
1568 (const_string "0")
1569 (const_string "*")))
1570 (set (attr "prefix_data16")
1571 (cond [(eq_attr "type" "fcmp")
1572 (const_string "*")
1573 (eq_attr "mode" "DF")
1574 (const_string "1")
1575 ]
1576 (const_string "0")))
1577 (set_attr "athlon_decode" "vector")
1578 (set_attr "amdfam10_decode" "direct")
1579 (set_attr "bdver1_decode" "double")])
1580
1581 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1582 [(set (reg:FPCMP FLAGS_REG)
1583 (compare:FPCMP
1584 (match_operand:MODEF 0 "register_operand" "x")
1585 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1586 "TARGET_SSE_MATH
1587 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1588 "* return output_fp_compare (insn, operands, true,
1589 <FPCMP:MODE>mode == CCFPUmode);"
1590 [(set_attr "type" "ssecomi")
1591 (set_attr "prefix" "maybe_vex")
1592 (set_attr "mode" "<MODEF:MODE>")
1593 (set_attr "prefix_rep" "0")
1594 (set (attr "prefix_data16")
1595 (if_then_else (eq_attr "mode" "DF")
1596 (const_string "1")
1597 (const_string "0")))
1598 (set_attr "athlon_decode" "vector")
1599 (set_attr "amdfam10_decode" "direct")
1600 (set_attr "bdver1_decode" "double")])
1601
1602 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1603 [(set (reg:FPCMP FLAGS_REG)
1604 (compare:FPCMP
1605 (match_operand:X87MODEF 0 "register_operand" "f")
1606 (match_operand:X87MODEF 1 "register_operand" "f")))]
1607 "TARGET_80387 && TARGET_CMOVE
1608 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1609 "* return output_fp_compare (insn, operands, true,
1610 <FPCMP:MODE>mode == CCFPUmode);"
1611 [(set_attr "type" "fcmp")
1612 (set_attr "mode" "<X87MODEF:MODE>")
1613 (set_attr "athlon_decode" "vector")
1614 (set_attr "amdfam10_decode" "direct")
1615 (set_attr "bdver1_decode" "double")])
1616 \f
1617 ;; Push/pop instructions.
1618
1619 (define_insn "*push<mode>2"
1620 [(set (match_operand:DWI 0 "push_operand" "=<")
1621 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1622 ""
1623 "#"
1624 [(set_attr "type" "multi")
1625 (set_attr "mode" "<MODE>")])
1626
1627 (define_split
1628 [(set (match_operand:TI 0 "push_operand")
1629 (match_operand:TI 1 "general_operand"))]
1630 "TARGET_64BIT && reload_completed
1631 && !SSE_REG_P (operands[1])"
1632 [(const_int 0)]
1633 "ix86_split_long_move (operands); DONE;")
1634
1635 (define_insn "*pushdi2_rex64"
1636 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1637 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1638 "TARGET_64BIT"
1639 "@
1640 push{q}\t%1
1641 #"
1642 [(set_attr "type" "push,multi")
1643 (set_attr "mode" "DI")])
1644
1645 ;; Convert impossible pushes of immediate to existing instructions.
1646 ;; First try to get scratch register and go through it. In case this
1647 ;; fails, push sign extended lower part first and then overwrite
1648 ;; upper part by 32bit move.
1649 (define_peephole2
1650 [(match_scratch:DI 2 "r")
1651 (set (match_operand:DI 0 "push_operand")
1652 (match_operand:DI 1 "immediate_operand"))]
1653 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1654 && !x86_64_immediate_operand (operands[1], DImode)"
1655 [(set (match_dup 2) (match_dup 1))
1656 (set (match_dup 0) (match_dup 2))])
1657
1658 ;; We need to define this as both peepholer and splitter for case
1659 ;; peephole2 pass is not run.
1660 ;; "&& 1" is needed to keep it from matching the previous pattern.
1661 (define_peephole2
1662 [(set (match_operand:DI 0 "push_operand")
1663 (match_operand:DI 1 "immediate_operand"))]
1664 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1665 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1666 [(set (match_dup 0) (match_dup 1))
1667 (set (match_dup 2) (match_dup 3))]
1668 {
1669 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1670
1671 operands[1] = gen_lowpart (DImode, operands[2]);
1672 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1673 GEN_INT (4)));
1674 })
1675
1676 (define_split
1677 [(set (match_operand:DI 0 "push_operand")
1678 (match_operand:DI 1 "immediate_operand"))]
1679 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1680 ? epilogue_completed : reload_completed)
1681 && !symbolic_operand (operands[1], DImode)
1682 && !x86_64_immediate_operand (operands[1], DImode)"
1683 [(set (match_dup 0) (match_dup 1))
1684 (set (match_dup 2) (match_dup 3))]
1685 {
1686 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1687
1688 operands[1] = gen_lowpart (DImode, operands[2]);
1689 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1690 GEN_INT (4)));
1691 })
1692
1693 (define_split
1694 [(set (match_operand:DI 0 "push_operand")
1695 (match_operand:DI 1 "general_operand"))]
1696 "!TARGET_64BIT && reload_completed
1697 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1698 [(const_int 0)]
1699 "ix86_split_long_move (operands); DONE;")
1700
1701 (define_insn "*pushsi2"
1702 [(set (match_operand:SI 0 "push_operand" "=<")
1703 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1704 "!TARGET_64BIT"
1705 "push{l}\t%1"
1706 [(set_attr "type" "push")
1707 (set_attr "mode" "SI")])
1708
1709 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1710 ;; "push a byte/word". But actually we use pushl, which has the effect
1711 ;; of rounding the amount pushed up to a word.
1712
1713 ;; For TARGET_64BIT we always round up to 8 bytes.
1714 (define_insn "*push<mode>2_rex64"
1715 [(set (match_operand:SWI124 0 "push_operand" "=X")
1716 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1717 "TARGET_64BIT"
1718 "push{q}\t%q1"
1719 [(set_attr "type" "push")
1720 (set_attr "mode" "DI")])
1721
1722 (define_insn "*push<mode>2"
1723 [(set (match_operand:SWI12 0 "push_operand" "=X")
1724 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1725 "!TARGET_64BIT"
1726 "push{l}\t%k1"
1727 [(set_attr "type" "push")
1728 (set_attr "mode" "SI")])
1729
1730 (define_insn "*push<mode>2_prologue"
1731 [(set (match_operand:W 0 "push_operand" "=<")
1732 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1733 (clobber (mem:BLK (scratch)))]
1734 ""
1735 "push{<imodesuffix>}\t%1"
1736 [(set_attr "type" "push")
1737 (set_attr "mode" "<MODE>")])
1738
1739 (define_insn "*pop<mode>1"
1740 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1741 (match_operand:W 1 "pop_operand" ">"))]
1742 ""
1743 "pop{<imodesuffix>}\t%0"
1744 [(set_attr "type" "pop")
1745 (set_attr "mode" "<MODE>")])
1746
1747 (define_insn "*pop<mode>1_epilogue"
1748 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1749 (match_operand:W 1 "pop_operand" ">"))
1750 (clobber (mem:BLK (scratch)))]
1751 ""
1752 "pop{<imodesuffix>}\t%0"
1753 [(set_attr "type" "pop")
1754 (set_attr "mode" "<MODE>")])
1755 \f
1756 ;; Move instructions.
1757
1758 (define_expand "movxi"
1759 [(set (match_operand:XI 0 "nonimmediate_operand")
1760 (match_operand:XI 1 "general_operand"))]
1761 "TARGET_AVX512F"
1762 "ix86_expand_move (XImode, operands); DONE;")
1763
1764 ;; Reload patterns to support multi-word load/store
1765 ;; with non-offsetable address.
1766 (define_expand "reload_noff_store"
1767 [(parallel [(match_operand 0 "memory_operand" "=m")
1768 (match_operand 1 "register_operand" "r")
1769 (match_operand:DI 2 "register_operand" "=&r")])]
1770 "TARGET_64BIT"
1771 {
1772 rtx mem = operands[0];
1773 rtx addr = XEXP (mem, 0);
1774
1775 emit_move_insn (operands[2], addr);
1776 mem = replace_equiv_address_nv (mem, operands[2]);
1777
1778 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1779 DONE;
1780 })
1781
1782 (define_expand "reload_noff_load"
1783 [(parallel [(match_operand 0 "register_operand" "=r")
1784 (match_operand 1 "memory_operand" "m")
1785 (match_operand:DI 2 "register_operand" "=r")])]
1786 "TARGET_64BIT"
1787 {
1788 rtx mem = operands[1];
1789 rtx addr = XEXP (mem, 0);
1790
1791 emit_move_insn (operands[2], addr);
1792 mem = replace_equiv_address_nv (mem, operands[2]);
1793
1794 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1795 DONE;
1796 })
1797
1798 (define_expand "movoi"
1799 [(set (match_operand:OI 0 "nonimmediate_operand")
1800 (match_operand:OI 1 "general_operand"))]
1801 "TARGET_AVX"
1802 "ix86_expand_move (OImode, operands); DONE;")
1803
1804 (define_expand "movti"
1805 [(set (match_operand:TI 0 "nonimmediate_operand")
1806 (match_operand:TI 1 "nonimmediate_operand"))]
1807 "TARGET_64BIT || TARGET_SSE"
1808 {
1809 if (TARGET_64BIT)
1810 ix86_expand_move (TImode, operands);
1811 else if (push_operand (operands[0], TImode))
1812 ix86_expand_push (TImode, operands[1]);
1813 else
1814 ix86_expand_vector_move (TImode, operands);
1815 DONE;
1816 })
1817
1818 ;; This expands to what emit_move_complex would generate if we didn't
1819 ;; have a movti pattern. Having this avoids problems with reload on
1820 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1821 ;; to have around all the time.
1822 (define_expand "movcdi"
1823 [(set (match_operand:CDI 0 "nonimmediate_operand")
1824 (match_operand:CDI 1 "general_operand"))]
1825 ""
1826 {
1827 if (push_operand (operands[0], CDImode))
1828 emit_move_complex_push (CDImode, operands[0], operands[1]);
1829 else
1830 emit_move_complex_parts (operands[0], operands[1]);
1831 DONE;
1832 })
1833
1834 (define_expand "mov<mode>"
1835 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1836 (match_operand:SWI1248x 1 "general_operand"))]
1837 ""
1838 "ix86_expand_move (<MODE>mode, operands); DONE;")
1839
1840 (define_insn "*mov<mode>_xor"
1841 [(set (match_operand:SWI48 0 "register_operand" "=r")
1842 (match_operand:SWI48 1 "const0_operand"))
1843 (clobber (reg:CC FLAGS_REG))]
1844 "reload_completed"
1845 "xor{l}\t%k0, %k0"
1846 [(set_attr "type" "alu1")
1847 (set_attr "mode" "SI")
1848 (set_attr "length_immediate" "0")])
1849
1850 (define_insn "*mov<mode>_or"
1851 [(set (match_operand:SWI48 0 "register_operand" "=r")
1852 (match_operand:SWI48 1 "const_int_operand"))
1853 (clobber (reg:CC FLAGS_REG))]
1854 "reload_completed
1855 && operands[1] == constm1_rtx"
1856 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1857 [(set_attr "type" "alu1")
1858 (set_attr "mode" "<MODE>")
1859 (set_attr "length_immediate" "1")])
1860
1861 (define_insn "*movxi_internal_avx512f"
1862 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1863 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1864 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1865 {
1866 switch (which_alternative)
1867 {
1868 case 0:
1869 return standard_sse_constant_opcode (insn, operands[1]);
1870 case 1:
1871 case 2:
1872 if (misaligned_operand (operands[0], XImode)
1873 || misaligned_operand (operands[1], XImode))
1874 return "vmovdqu32\t{%1, %0|%0, %1}";
1875 else
1876 return "vmovdqa32\t{%1, %0|%0, %1}";
1877 default:
1878 gcc_unreachable ();
1879 }
1880 }
1881 [(set_attr "type" "sselog1,ssemov,ssemov")
1882 (set_attr "prefix" "evex")
1883 (set_attr "mode" "XI")])
1884
1885 (define_insn "*movoi_internal_avx"
1886 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1887 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1888 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1889 {
1890 switch (get_attr_type (insn))
1891 {
1892 case TYPE_SSELOG1:
1893 return standard_sse_constant_opcode (insn, operands[1]);
1894
1895 case TYPE_SSEMOV:
1896 if (misaligned_operand (operands[0], OImode)
1897 || misaligned_operand (operands[1], OImode))
1898 {
1899 if (get_attr_mode (insn) == MODE_V8SF)
1900 return "vmovups\t{%1, %0|%0, %1}";
1901 else
1902 return "vmovdqu\t{%1, %0|%0, %1}";
1903 }
1904 else
1905 {
1906 if (get_attr_mode (insn) == MODE_V8SF)
1907 return "vmovaps\t{%1, %0|%0, %1}";
1908 else
1909 return "vmovdqa\t{%1, %0|%0, %1}";
1910 }
1911
1912 default:
1913 gcc_unreachable ();
1914 }
1915 }
1916 [(set_attr "type" "sselog1,ssemov,ssemov")
1917 (set_attr "prefix" "vex")
1918 (set (attr "mode")
1919 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1920 (const_string "V8SF")
1921 (and (eq_attr "alternative" "2")
1922 (match_test "TARGET_SSE_TYPELESS_STORES"))
1923 (const_string "V8SF")
1924 ]
1925 (const_string "OI")))])
1926
1927 (define_insn "*movti_internal"
1928 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1929 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1930 "(TARGET_64BIT || TARGET_SSE)
1931 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1932 {
1933 switch (get_attr_type (insn))
1934 {
1935 case TYPE_MULTI:
1936 return "#";
1937
1938 case TYPE_SSELOG1:
1939 return standard_sse_constant_opcode (insn, operands[1]);
1940
1941 case TYPE_SSEMOV:
1942 /* TDmode values are passed as TImode on the stack. Moving them
1943 to stack may result in unaligned memory access. */
1944 if (misaligned_operand (operands[0], TImode)
1945 || misaligned_operand (operands[1], TImode))
1946 {
1947 if (get_attr_mode (insn) == MODE_V4SF)
1948 return "%vmovups\t{%1, %0|%0, %1}";
1949 else
1950 return "%vmovdqu\t{%1, %0|%0, %1}";
1951 }
1952 else
1953 {
1954 if (get_attr_mode (insn) == MODE_V4SF)
1955 return "%vmovaps\t{%1, %0|%0, %1}";
1956 else
1957 return "%vmovdqa\t{%1, %0|%0, %1}";
1958 }
1959
1960 default:
1961 gcc_unreachable ();
1962 }
1963 }
1964 [(set_attr "isa" "x64,x64,*,*,*")
1965 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1966 (set (attr "prefix")
1967 (if_then_else (eq_attr "type" "sselog1,ssemov")
1968 (const_string "maybe_vex")
1969 (const_string "orig")))
1970 (set (attr "mode")
1971 (cond [(eq_attr "alternative" "0,1")
1972 (const_string "DI")
1973 (ior (not (match_test "TARGET_SSE2"))
1974 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1975 (const_string "V4SF")
1976 (and (eq_attr "alternative" "4")
1977 (match_test "TARGET_SSE_TYPELESS_STORES"))
1978 (const_string "V4SF")
1979 (match_test "TARGET_AVX")
1980 (const_string "TI")
1981 (match_test "optimize_function_for_size_p (cfun)")
1982 (const_string "V4SF")
1983 ]
1984 (const_string "TI")))])
1985
1986 (define_split
1987 [(set (match_operand:TI 0 "nonimmediate_operand")
1988 (match_operand:TI 1 "general_operand"))]
1989 "reload_completed
1990 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1991 [(const_int 0)]
1992 "ix86_split_long_move (operands); DONE;")
1993
1994 (define_insn "*movdi_internal"
1995 [(set (match_operand:DI 0 "nonimmediate_operand"
1996 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1997 (match_operand:DI 1 "general_operand"
1998 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn"))]
1999 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2000 {
2001 switch (get_attr_type (insn))
2002 {
2003 case TYPE_MULTI:
2004 return "#";
2005
2006 case TYPE_MMX:
2007 return "pxor\t%0, %0";
2008
2009 case TYPE_MMXMOV:
2010 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2011 /* Handle broken assemblers that require movd instead of movq. */
2012 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2013 return "movd\t{%1, %0|%0, %1}";
2014 #endif
2015 return "movq\t{%1, %0|%0, %1}";
2016
2017 case TYPE_SSELOG1:
2018 if (GENERAL_REG_P (operands[0]))
2019 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2020
2021 return standard_sse_constant_opcode (insn, operands[1]);
2022
2023 case TYPE_SSEMOV:
2024 switch (get_attr_mode (insn))
2025 {
2026 case MODE_DI:
2027 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2028 /* Handle broken assemblers that require movd instead of movq. */
2029 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2030 return "%vmovd\t{%1, %0|%0, %1}";
2031 #endif
2032 return "%vmovq\t{%1, %0|%0, %1}";
2033 case MODE_TI:
2034 return "%vmovdqa\t{%1, %0|%0, %1}";
2035 case MODE_XI:
2036 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2037
2038 case MODE_V2SF:
2039 gcc_assert (!TARGET_AVX);
2040 return "movlps\t{%1, %0|%0, %1}";
2041 case MODE_V4SF:
2042 return "%vmovaps\t{%1, %0|%0, %1}";
2043
2044 default:
2045 gcc_unreachable ();
2046 }
2047
2048 case TYPE_SSECVT:
2049 if (SSE_REG_P (operands[0]))
2050 return "movq2dq\t{%1, %0|%0, %1}";
2051 else
2052 return "movdq2q\t{%1, %0|%0, %1}";
2053
2054 case TYPE_LEA:
2055 return "lea{q}\t{%E1, %0|%0, %E1}";
2056
2057 case TYPE_IMOV:
2058 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2059 if (get_attr_mode (insn) == MODE_SI)
2060 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2061 else if (which_alternative == 4)
2062 return "movabs{q}\t{%1, %0|%0, %1}";
2063 else if (ix86_use_lea_for_mov (insn, operands))
2064 return "lea{q}\t{%E1, %0|%0, %E1}";
2065 else
2066 return "mov{q}\t{%1, %0|%0, %1}";
2067
2068 default:
2069 gcc_unreachable ();
2070 }
2071 }
2072 [(set (attr "isa")
2073 (cond [(eq_attr "alternative" "0,1")
2074 (const_string "nox64")
2075 (eq_attr "alternative" "2,3,4,5,10,11,16,18")
2076 (const_string "x64")
2077 (eq_attr "alternative" "17")
2078 (const_string "x64_sse4")
2079 ]
2080 (const_string "*")))
2081 (set (attr "type")
2082 (cond [(eq_attr "alternative" "0,1")
2083 (const_string "multi")
2084 (eq_attr "alternative" "6")
2085 (const_string "mmx")
2086 (eq_attr "alternative" "7,8,9,10,11")
2087 (const_string "mmxmov")
2088 (eq_attr "alternative" "12,17")
2089 (const_string "sselog1")
2090 (eq_attr "alternative" "13,14,15,16,18")
2091 (const_string "ssemov")
2092 (eq_attr "alternative" "19,20")
2093 (const_string "ssecvt")
2094 (match_operand 1 "pic_32bit_operand")
2095 (const_string "lea")
2096 ]
2097 (const_string "imov")))
2098 (set (attr "modrm")
2099 (if_then_else
2100 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2101 (const_string "0")
2102 (const_string "*")))
2103 (set (attr "length_immediate")
2104 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2105 (const_string "8")
2106 (eq_attr "alternative" "17")
2107 (const_string "1")
2108 ]
2109 (const_string "*")))
2110 (set (attr "prefix_rex")
2111 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2112 (const_string "1")
2113 (const_string "*")))
2114 (set (attr "prefix_extra")
2115 (if_then_else (eq_attr "alternative" "17")
2116 (const_string "1")
2117 (const_string "*")))
2118 (set (attr "prefix")
2119 (if_then_else (eq_attr "type" "sselog1,ssemov")
2120 (const_string "maybe_vex")
2121 (const_string "orig")))
2122 (set (attr "prefix_data16")
2123 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2124 (const_string "1")
2125 (const_string "*")))
2126 (set (attr "mode")
2127 (cond [(eq_attr "alternative" "2")
2128 (const_string "SI")
2129 (eq_attr "alternative" "12,13")
2130 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2131 (match_operand 1 "ext_sse_reg_operand"))
2132 (const_string "XI")
2133 (ior (not (match_test "TARGET_SSE2"))
2134 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2135 (const_string "V4SF")
2136 (match_test "TARGET_AVX")
2137 (const_string "TI")
2138 (match_test "optimize_function_for_size_p (cfun)")
2139 (const_string "V4SF")
2140 ]
2141 (const_string "TI"))
2142
2143 (and (eq_attr "alternative" "14,15")
2144 (not (match_test "TARGET_SSE2")))
2145 (const_string "V2SF")
2146 (eq_attr "alternative" "17")
2147 (const_string "TI")
2148 ]
2149 (const_string "DI")))])
2150
2151 (define_split
2152 [(set (match_operand:DI 0 "nonimmediate_operand")
2153 (match_operand:DI 1 "general_operand"))]
2154 "!TARGET_64BIT && reload_completed
2155 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2156 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2157 [(const_int 0)]
2158 "ix86_split_long_move (operands); DONE;")
2159
2160 (define_insn "*movsi_internal"
2161 [(set (match_operand:SI 0 "nonimmediate_operand"
2162 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi")
2163 (match_operand:SI 1 "general_operand"
2164 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r"))]
2165 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2166 {
2167 switch (get_attr_type (insn))
2168 {
2169 case TYPE_SSELOG1:
2170 if (GENERAL_REG_P (operands[0]))
2171 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2172
2173 return standard_sse_constant_opcode (insn, operands[1]);
2174
2175 case TYPE_SSEMOV:
2176 switch (get_attr_mode (insn))
2177 {
2178 case MODE_SI:
2179 return "%vmovd\t{%1, %0|%0, %1}";
2180 case MODE_TI:
2181 return "%vmovdqa\t{%1, %0|%0, %1}";
2182 case MODE_XI:
2183 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2184
2185 case MODE_V4SF:
2186 return "%vmovaps\t{%1, %0|%0, %1}";
2187
2188 case MODE_SF:
2189 gcc_assert (!TARGET_AVX);
2190 return "movss\t{%1, %0|%0, %1}";
2191
2192 default:
2193 gcc_unreachable ();
2194 }
2195
2196 case TYPE_MMX:
2197 return "pxor\t%0, %0";
2198
2199 case TYPE_MMXMOV:
2200 switch (get_attr_mode (insn))
2201 {
2202 case MODE_DI:
2203 return "movq\t{%1, %0|%0, %1}";
2204 case MODE_SI:
2205 return "movd\t{%1, %0|%0, %1}";
2206
2207 default:
2208 gcc_unreachable ();
2209 }
2210
2211 case TYPE_LEA:
2212 return "lea{l}\t{%E1, %0|%0, %E1}";
2213
2214 case TYPE_IMOV:
2215 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2216 if (ix86_use_lea_for_mov (insn, operands))
2217 return "lea{l}\t{%E1, %0|%0, %E1}";
2218 else
2219 return "mov{l}\t{%1, %0|%0, %1}";
2220
2221 default:
2222 gcc_unreachable ();
2223 }
2224 }
2225 [(set (attr "isa")
2226 (if_then_else (eq_attr "alternative" "11")
2227 (const_string "sse4")
2228 (const_string "*")))
2229 (set (attr "type")
2230 (cond [(eq_attr "alternative" "2")
2231 (const_string "mmx")
2232 (eq_attr "alternative" "3,4,5")
2233 (const_string "mmxmov")
2234 (eq_attr "alternative" "6,11")
2235 (const_string "sselog1")
2236 (eq_attr "alternative" "7,8,9,10,12")
2237 (const_string "ssemov")
2238 (match_operand 1 "pic_32bit_operand")
2239 (const_string "lea")
2240 ]
2241 (const_string "imov")))
2242 (set (attr "length_immediate")
2243 (if_then_else (eq_attr "alternative" "11")
2244 (const_string "1")
2245 (const_string "*")))
2246 (set (attr "prefix_extra")
2247 (if_then_else (eq_attr "alternative" "11")
2248 (const_string "1")
2249 (const_string "*")))
2250 (set (attr "prefix")
2251 (if_then_else (eq_attr "type" "sselog1,ssemov")
2252 (const_string "maybe_vex")
2253 (const_string "orig")))
2254 (set (attr "prefix_data16")
2255 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2256 (const_string "1")
2257 (const_string "*")))
2258 (set (attr "mode")
2259 (cond [(eq_attr "alternative" "2,3")
2260 (const_string "DI")
2261 (eq_attr "alternative" "6,7")
2262 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2263 (match_operand 1 "ext_sse_reg_operand"))
2264 (const_string "XI")
2265 (ior (not (match_test "TARGET_SSE2"))
2266 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2267 (const_string "V4SF")
2268 (match_test "TARGET_AVX")
2269 (const_string "TI")
2270 (match_test "optimize_function_for_size_p (cfun)")
2271 (const_string "V4SF")
2272 ]
2273 (const_string "TI"))
2274
2275 (and (eq_attr "alternative" "8,9")
2276 (not (match_test "TARGET_SSE2")))
2277 (const_string "SF")
2278 (eq_attr "alternative" "11")
2279 (const_string "TI")
2280 ]
2281 (const_string "SI")))])
2282
2283 (define_insn "*movhi_internal"
2284 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,Yk,Yk,rm")
2285 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,Yk,Yk"))]
2286 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2287 {
2288 switch (get_attr_type (insn))
2289 {
2290 case TYPE_IMOVX:
2291 /* movzwl is faster than movw on p2 due to partial word stalls,
2292 though not as fast as an aligned movl. */
2293 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2294
2295 case TYPE_MSKMOV:
2296 switch (which_alternative)
2297 {
2298 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2299 case 5: return "kmovw\t{%1, %0|%0, %1}";
2300 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2301 default: gcc_unreachable ();
2302 }
2303
2304 default:
2305 if (get_attr_mode (insn) == MODE_SI)
2306 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2307 else
2308 return "mov{w}\t{%1, %0|%0, %1}";
2309 }
2310 }
2311 [(set (attr "type")
2312 (cond [(match_test "optimize_function_for_size_p (cfun)")
2313 (const_string "imov")
2314 (and (eq_attr "alternative" "0")
2315 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2316 (not (match_test "TARGET_HIMODE_MATH"))))
2317 (const_string "imov")
2318 (and (eq_attr "alternative" "1,2")
2319 (match_operand:HI 1 "aligned_operand"))
2320 (const_string "imov")
2321 (eq_attr "alternative" "4,5,6")
2322 (const_string "mskmov")
2323 (and (match_test "TARGET_MOVX")
2324 (eq_attr "alternative" "0,2"))
2325 (const_string "imovx")
2326 ]
2327 (const_string "imov")))
2328 (set (attr "prefix")
2329 (if_then_else (eq_attr "alternative" "4,5,6")
2330 (const_string "vex")
2331 (const_string "orig")))
2332 (set (attr "mode")
2333 (cond [(eq_attr "type" "imovx")
2334 (const_string "SI")
2335 (and (eq_attr "alternative" "1,2")
2336 (match_operand:HI 1 "aligned_operand"))
2337 (const_string "SI")
2338 (and (eq_attr "alternative" "0")
2339 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2340 (not (match_test "TARGET_HIMODE_MATH"))))
2341 (const_string "SI")
2342 ]
2343 (const_string "HI")))])
2344
2345 ;; Situation is quite tricky about when to choose full sized (SImode) move
2346 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2347 ;; partial register dependency machines (such as AMD Athlon), where QImode
2348 ;; moves issue extra dependency and for partial register stalls machines
2349 ;; that don't use QImode patterns (and QImode move cause stall on the next
2350 ;; instruction).
2351 ;;
2352 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2353 ;; register stall machines with, where we use QImode instructions, since
2354 ;; partial register stall can be caused there. Then we use movzx.
2355
2356 (define_insn "*movqi_internal"
2357 [(set (match_operand:QI 0 "nonimmediate_operand"
2358 "=q,q ,q ,r,r ,?r,m ,Yk,Yk,r")
2359 (match_operand:QI 1 "general_operand"
2360 "q ,qn,qm,q,rn,qm,qn,r ,Yk,Yk"))]
2361 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2362 {
2363 switch (get_attr_type (insn))
2364 {
2365 case TYPE_IMOVX:
2366 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2367 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2368
2369 case TYPE_MSKMOV:
2370 switch (which_alternative)
2371 {
2372 case 7: return "kmovw\t{%k1, %0|%0, %k1}";
2373 case 8: return "kmovw\t{%1, %0|%0, %1}";
2374 case 9: return "kmovw\t{%1, %k0|%k0, %1}";
2375 default: gcc_unreachable ();
2376 }
2377
2378 default:
2379 if (get_attr_mode (insn) == MODE_SI)
2380 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2381 else
2382 return "mov{b}\t{%1, %0|%0, %1}";
2383 }
2384 }
2385 [(set (attr "type")
2386 (cond [(and (eq_attr "alternative" "5")
2387 (not (match_operand:QI 1 "aligned_operand")))
2388 (const_string "imovx")
2389 (match_test "optimize_function_for_size_p (cfun)")
2390 (const_string "imov")
2391 (and (eq_attr "alternative" "3")
2392 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2393 (not (match_test "TARGET_QIMODE_MATH"))))
2394 (const_string "imov")
2395 (eq_attr "alternative" "3,5")
2396 (const_string "imovx")
2397 (eq_attr "alternative" "7,8,9")
2398 (const_string "mskmov")
2399 (and (match_test "TARGET_MOVX")
2400 (eq_attr "alternative" "2"))
2401 (const_string "imovx")
2402 ]
2403 (const_string "imov")))
2404 (set (attr "prefix")
2405 (if_then_else (eq_attr "alternative" "7,8,9")
2406 (const_string "vex")
2407 (const_string "orig")))
2408 (set (attr "mode")
2409 (cond [(eq_attr "alternative" "3,4,5")
2410 (const_string "SI")
2411 (eq_attr "alternative" "6")
2412 (const_string "QI")
2413 (eq_attr "type" "imovx")
2414 (const_string "SI")
2415 (and (eq_attr "type" "imov")
2416 (and (eq_attr "alternative" "0,1")
2417 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2418 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2419 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2420 (const_string "SI")
2421 ;; Avoid partial register stalls when not using QImode arithmetic
2422 (and (eq_attr "type" "imov")
2423 (and (eq_attr "alternative" "0,1")
2424 (and (match_test "TARGET_PARTIAL_REG_STALL")
2425 (not (match_test "TARGET_QIMODE_MATH")))))
2426 (const_string "SI")
2427 ]
2428 (const_string "QI")))])
2429
2430 ;; Stores and loads of ax to arbitrary constant address.
2431 ;; We fake an second form of instruction to force reload to load address
2432 ;; into register when rax is not available
2433 (define_insn "*movabs<mode>_1"
2434 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2435 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2436 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2437 "@
2438 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2439 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2440 [(set_attr "type" "imov")
2441 (set_attr "modrm" "0,*")
2442 (set_attr "length_address" "8,0")
2443 (set_attr "length_immediate" "0,*")
2444 (set_attr "memory" "store")
2445 (set_attr "mode" "<MODE>")])
2446
2447 (define_insn "*movabs<mode>_2"
2448 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2449 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2450 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2451 "@
2452 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2453 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2454 [(set_attr "type" "imov")
2455 (set_attr "modrm" "0,*")
2456 (set_attr "length_address" "8,0")
2457 (set_attr "length_immediate" "0")
2458 (set_attr "memory" "load")
2459 (set_attr "mode" "<MODE>")])
2460
2461 (define_insn "swap<mode>"
2462 [(set (match_operand:SWI48 0 "register_operand" "+r")
2463 (match_operand:SWI48 1 "register_operand" "+r"))
2464 (set (match_dup 1)
2465 (match_dup 0))]
2466 ""
2467 "xchg{<imodesuffix>}\t%1, %0"
2468 [(set_attr "type" "imov")
2469 (set_attr "mode" "<MODE>")
2470 (set_attr "pent_pair" "np")
2471 (set_attr "athlon_decode" "vector")
2472 (set_attr "amdfam10_decode" "double")
2473 (set_attr "bdver1_decode" "double")])
2474
2475 (define_insn "*swap<mode>_1"
2476 [(set (match_operand:SWI12 0 "register_operand" "+r")
2477 (match_operand:SWI12 1 "register_operand" "+r"))
2478 (set (match_dup 1)
2479 (match_dup 0))]
2480 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2481 "xchg{l}\t%k1, %k0"
2482 [(set_attr "type" "imov")
2483 (set_attr "mode" "SI")
2484 (set_attr "pent_pair" "np")
2485 (set_attr "athlon_decode" "vector")
2486 (set_attr "amdfam10_decode" "double")
2487 (set_attr "bdver1_decode" "double")])
2488
2489 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2490 ;; is disabled for AMDFAM10
2491 (define_insn "*swap<mode>_2"
2492 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2493 (match_operand:SWI12 1 "register_operand" "+<r>"))
2494 (set (match_dup 1)
2495 (match_dup 0))]
2496 "TARGET_PARTIAL_REG_STALL"
2497 "xchg{<imodesuffix>}\t%1, %0"
2498 [(set_attr "type" "imov")
2499 (set_attr "mode" "<MODE>")
2500 (set_attr "pent_pair" "np")
2501 (set_attr "athlon_decode" "vector")])
2502
2503 (define_expand "movstrict<mode>"
2504 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2505 (match_operand:SWI12 1 "general_operand"))]
2506 ""
2507 {
2508 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2509 FAIL;
2510 if (GET_CODE (operands[0]) == SUBREG
2511 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2512 FAIL;
2513 /* Don't generate memory->memory moves, go through a register */
2514 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2515 operands[1] = force_reg (<MODE>mode, operands[1]);
2516 })
2517
2518 (define_insn "*movstrict<mode>_1"
2519 [(set (strict_low_part
2520 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2521 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2522 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2523 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2524 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2525 [(set_attr "type" "imov")
2526 (set_attr "mode" "<MODE>")])
2527
2528 (define_insn "*movstrict<mode>_xor"
2529 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2530 (match_operand:SWI12 1 "const0_operand"))
2531 (clobber (reg:CC FLAGS_REG))]
2532 "reload_completed"
2533 "xor{<imodesuffix>}\t%0, %0"
2534 [(set_attr "type" "alu1")
2535 (set_attr "mode" "<MODE>")
2536 (set_attr "length_immediate" "0")])
2537
2538 (define_insn "*mov<mode>_extv_1"
2539 [(set (match_operand:SWI24 0 "register_operand" "=R")
2540 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2541 (const_int 8)
2542 (const_int 8)))]
2543 ""
2544 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2545 [(set_attr "type" "imovx")
2546 (set_attr "mode" "SI")])
2547
2548 (define_insn "*movqi_extv_1"
2549 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2550 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2551 (const_int 8)
2552 (const_int 8)))]
2553 ""
2554 {
2555 switch (get_attr_type (insn))
2556 {
2557 case TYPE_IMOVX:
2558 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2559 default:
2560 return "mov{b}\t{%h1, %0|%0, %h1}";
2561 }
2562 }
2563 [(set_attr "isa" "*,*,nox64")
2564 (set (attr "type")
2565 (if_then_else (and (match_operand:QI 0 "register_operand")
2566 (ior (not (match_operand:QI 0 "QIreg_operand"))
2567 (match_test "TARGET_MOVX")))
2568 (const_string "imovx")
2569 (const_string "imov")))
2570 (set (attr "mode")
2571 (if_then_else (eq_attr "type" "imovx")
2572 (const_string "SI")
2573 (const_string "QI")))])
2574
2575 (define_insn "*mov<mode>_extzv_1"
2576 [(set (match_operand:SWI48 0 "register_operand" "=R")
2577 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2578 (const_int 8)
2579 (const_int 8)))]
2580 ""
2581 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2582 [(set_attr "type" "imovx")
2583 (set_attr "mode" "SI")])
2584
2585 (define_insn "*movqi_extzv_2"
2586 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2587 (subreg:QI
2588 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2589 (const_int 8)
2590 (const_int 8)) 0))]
2591 ""
2592 {
2593 switch (get_attr_type (insn))
2594 {
2595 case TYPE_IMOVX:
2596 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2597 default:
2598 return "mov{b}\t{%h1, %0|%0, %h1}";
2599 }
2600 }
2601 [(set_attr "isa" "*,*,nox64")
2602 (set (attr "type")
2603 (if_then_else (and (match_operand:QI 0 "register_operand")
2604 (ior (not (match_operand:QI 0 "QIreg_operand"))
2605 (match_test "TARGET_MOVX")))
2606 (const_string "imovx")
2607 (const_string "imov")))
2608 (set (attr "mode")
2609 (if_then_else (eq_attr "type" "imovx")
2610 (const_string "SI")
2611 (const_string "QI")))])
2612
2613 (define_insn "mov<mode>_insv_1"
2614 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2615 (const_int 8)
2616 (const_int 8))
2617 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2618 ""
2619 {
2620 if (CONST_INT_P (operands[1]))
2621 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2622 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2623 }
2624 [(set_attr "isa" "*,nox64")
2625 (set_attr "type" "imov")
2626 (set_attr "mode" "QI")])
2627
2628 (define_insn "*movqi_insv_2"
2629 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2630 (const_int 8)
2631 (const_int 8))
2632 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2633 (const_int 8)))]
2634 ""
2635 "mov{b}\t{%h1, %h0|%h0, %h1}"
2636 [(set_attr "type" "imov")
2637 (set_attr "mode" "QI")])
2638 \f
2639 ;; Floating point push instructions.
2640
2641 (define_insn "*pushtf"
2642 [(set (match_operand:TF 0 "push_operand" "=<,<")
2643 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2644 "TARGET_64BIT || TARGET_SSE"
2645 {
2646 /* This insn should be already split before reg-stack. */
2647 gcc_unreachable ();
2648 }
2649 [(set_attr "isa" "*,x64")
2650 (set_attr "type" "multi")
2651 (set_attr "unit" "sse,*")
2652 (set_attr "mode" "TF,DI")])
2653
2654 ;; %%% Kill this when call knows how to work this out.
2655 (define_split
2656 [(set (match_operand:TF 0 "push_operand")
2657 (match_operand:TF 1 "sse_reg_operand"))]
2658 "TARGET_SSE && reload_completed"
2659 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2660 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2661
2662 (define_insn "*pushxf"
2663 [(set (match_operand:XF 0 "push_operand" "=<,<")
2664 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2665 ""
2666 {
2667 /* This insn should be already split before reg-stack. */
2668 gcc_unreachable ();
2669 }
2670 [(set_attr "type" "multi")
2671 (set_attr "unit" "i387,*")
2672 (set (attr "mode")
2673 (cond [(eq_attr "alternative" "1")
2674 (if_then_else (match_test "TARGET_64BIT")
2675 (const_string "DI")
2676 (const_string "SI"))
2677 ]
2678 (const_string "XF")))])
2679
2680 ;; %%% Kill this when call knows how to work this out.
2681 (define_split
2682 [(set (match_operand:XF 0 "push_operand")
2683 (match_operand:XF 1 "fp_register_operand"))]
2684 "reload_completed"
2685 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2686 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2687 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2688
2689 (define_insn "*pushdf"
2690 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2691 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2692 ""
2693 {
2694 /* This insn should be already split before reg-stack. */
2695 gcc_unreachable ();
2696 }
2697 [(set_attr "isa" "*,nox64,x64,sse2")
2698 (set_attr "type" "multi")
2699 (set_attr "unit" "i387,*,*,sse")
2700 (set_attr "mode" "DF,SI,DI,DF")])
2701
2702 ;; %%% Kill this when call knows how to work this out.
2703 (define_split
2704 [(set (match_operand:DF 0 "push_operand")
2705 (match_operand:DF 1 "any_fp_register_operand"))]
2706 "reload_completed"
2707 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2708 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2709
2710 (define_insn "*pushsf_rex64"
2711 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2712 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2713 "TARGET_64BIT"
2714 {
2715 /* Anything else should be already split before reg-stack. */
2716 gcc_assert (which_alternative == 1);
2717 return "push{q}\t%q1";
2718 }
2719 [(set_attr "type" "multi,push,multi")
2720 (set_attr "unit" "i387,*,*")
2721 (set_attr "mode" "SF,DI,SF")])
2722
2723 (define_insn "*pushsf"
2724 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2725 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2726 "!TARGET_64BIT"
2727 {
2728 /* Anything else should be already split before reg-stack. */
2729 gcc_assert (which_alternative == 1);
2730 return "push{l}\t%1";
2731 }
2732 [(set_attr "type" "multi,push,multi")
2733 (set_attr "unit" "i387,*,*")
2734 (set_attr "mode" "SF,SI,SF")])
2735
2736 ;; %%% Kill this when call knows how to work this out.
2737 (define_split
2738 [(set (match_operand:SF 0 "push_operand")
2739 (match_operand:SF 1 "any_fp_register_operand"))]
2740 "reload_completed"
2741 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2742 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2743 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2744
2745 (define_split
2746 [(set (match_operand:SF 0 "push_operand")
2747 (match_operand:SF 1 "memory_operand"))]
2748 "reload_completed
2749 && (operands[2] = find_constant_src (insn))"
2750 [(set (match_dup 0) (match_dup 2))])
2751
2752 (define_split
2753 [(set (match_operand 0 "push_operand")
2754 (match_operand 1 "general_operand"))]
2755 "reload_completed
2756 && (GET_MODE (operands[0]) == TFmode
2757 || GET_MODE (operands[0]) == XFmode
2758 || GET_MODE (operands[0]) == DFmode)
2759 && !ANY_FP_REG_P (operands[1])"
2760 [(const_int 0)]
2761 "ix86_split_long_move (operands); DONE;")
2762 \f
2763 ;; Floating point move instructions.
2764
2765 (define_expand "movtf"
2766 [(set (match_operand:TF 0 "nonimmediate_operand")
2767 (match_operand:TF 1 "nonimmediate_operand"))]
2768 "TARGET_64BIT || TARGET_SSE"
2769 "ix86_expand_move (TFmode, operands); DONE;")
2770
2771 (define_expand "mov<mode>"
2772 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2773 (match_operand:X87MODEF 1 "general_operand"))]
2774 ""
2775 "ix86_expand_move (<MODE>mode, operands); DONE;")
2776
2777 (define_insn "*movtf_internal"
2778 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2779 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2780 "(TARGET_64BIT || TARGET_SSE)
2781 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2782 && (!can_create_pseudo_p ()
2783 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2784 || GET_CODE (operands[1]) != CONST_DOUBLE
2785 || (optimize_function_for_size_p (cfun)
2786 && standard_sse_constant_p (operands[1])
2787 && !memory_operand (operands[0], TFmode))
2788 || (!TARGET_MEMORY_MISMATCH_STALL
2789 && memory_operand (operands[0], TFmode)))"
2790 {
2791 switch (get_attr_type (insn))
2792 {
2793 case TYPE_SSELOG1:
2794 return standard_sse_constant_opcode (insn, operands[1]);
2795
2796 case TYPE_SSEMOV:
2797 /* Handle misaligned load/store since we
2798 don't have movmisaligntf pattern. */
2799 if (misaligned_operand (operands[0], TFmode)
2800 || misaligned_operand (operands[1], TFmode))
2801 {
2802 if (get_attr_mode (insn) == MODE_V4SF)
2803 return "%vmovups\t{%1, %0|%0, %1}";
2804 else
2805 return "%vmovdqu\t{%1, %0|%0, %1}";
2806 }
2807 else
2808 {
2809 if (get_attr_mode (insn) == MODE_V4SF)
2810 return "%vmovaps\t{%1, %0|%0, %1}";
2811 else
2812 return "%vmovdqa\t{%1, %0|%0, %1}";
2813 }
2814
2815 case TYPE_MULTI:
2816 return "#";
2817
2818 default:
2819 gcc_unreachable ();
2820 }
2821 }
2822 [(set_attr "isa" "*,*,*,x64,x64")
2823 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2824 (set (attr "prefix")
2825 (if_then_else (eq_attr "type" "sselog1,ssemov")
2826 (const_string "maybe_vex")
2827 (const_string "orig")))
2828 (set (attr "mode")
2829 (cond [(eq_attr "alternative" "3,4")
2830 (const_string "DI")
2831 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2832 (const_string "V4SF")
2833 (and (eq_attr "alternative" "2")
2834 (match_test "TARGET_SSE_TYPELESS_STORES"))
2835 (const_string "V4SF")
2836 (match_test "TARGET_AVX")
2837 (const_string "TI")
2838 (ior (not (match_test "TARGET_SSE2"))
2839 (match_test "optimize_function_for_size_p (cfun)"))
2840 (const_string "V4SF")
2841 ]
2842 (const_string "TI")))])
2843
2844 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2845 (define_insn "*movxf_internal"
2846 [(set (match_operand:XF 0 "nonimmediate_operand"
2847 "=f,m,f,?Yx*r ,!o ,!o")
2848 (match_operand:XF 1 "general_operand"
2849 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2850 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2851 && (!can_create_pseudo_p ()
2852 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2853 || GET_CODE (operands[1]) != CONST_DOUBLE
2854 || (optimize_function_for_size_p (cfun)
2855 && standard_80387_constant_p (operands[1]) > 0
2856 && !memory_operand (operands[0], XFmode))
2857 || (!TARGET_MEMORY_MISMATCH_STALL
2858 && memory_operand (operands[0], XFmode)))"
2859 {
2860 switch (get_attr_type (insn))
2861 {
2862 case TYPE_FMOV:
2863 if (which_alternative == 2)
2864 return standard_80387_constant_opcode (operands[1]);
2865 return output_387_reg_move (insn, operands);
2866
2867 case TYPE_MULTI:
2868 return "#";
2869
2870 default:
2871 gcc_unreachable ();
2872 }
2873 }
2874 [(set_attr "isa" "*,*,*,*,nox64,x64")
2875 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2876 (set (attr "mode")
2877 (cond [(eq_attr "alternative" "3,4,5")
2878 (if_then_else (match_test "TARGET_64BIT")
2879 (const_string "DI")
2880 (const_string "SI"))
2881 ]
2882 (const_string "XF")))])
2883
2884 ;; Possible store forwarding (partial memory) stall in alternative 4.
2885 (define_insn "*movdf_internal"
2886 [(set (match_operand:DF 0 "nonimmediate_operand"
2887 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
2888 (match_operand:DF 1 "general_operand"
2889 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
2890 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2891 && (!can_create_pseudo_p ()
2892 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2893 || GET_CODE (operands[1]) != CONST_DOUBLE
2894 || (optimize_function_for_size_p (cfun)
2895 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2896 && standard_80387_constant_p (operands[1]) > 0)
2897 || (TARGET_SSE2 && TARGET_SSE_MATH
2898 && standard_sse_constant_p (operands[1])))
2899 && !memory_operand (operands[0], DFmode))
2900 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2901 && memory_operand (operands[0], DFmode)))"
2902 {
2903 switch (get_attr_type (insn))
2904 {
2905 case TYPE_FMOV:
2906 if (which_alternative == 2)
2907 return standard_80387_constant_opcode (operands[1]);
2908 return output_387_reg_move (insn, operands);
2909
2910 case TYPE_MULTI:
2911 return "#";
2912
2913 case TYPE_IMOV:
2914 if (get_attr_mode (insn) == MODE_SI)
2915 return "mov{l}\t{%1, %k0|%k0, %1}";
2916 else if (which_alternative == 8)
2917 return "movabs{q}\t{%1, %0|%0, %1}";
2918 else
2919 return "mov{q}\t{%1, %0|%0, %1}";
2920
2921 case TYPE_SSELOG1:
2922 return standard_sse_constant_opcode (insn, operands[1]);
2923
2924 case TYPE_SSEMOV:
2925 switch (get_attr_mode (insn))
2926 {
2927 case MODE_DF:
2928 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2929 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2930 return "%vmovsd\t{%1, %0|%0, %1}";
2931
2932 case MODE_V4SF:
2933 return "%vmovaps\t{%1, %0|%0, %1}";
2934 case MODE_V8DF:
2935 return "vmovapd\t{%g1, %g0|%g0, %g1}";
2936 case MODE_V2DF:
2937 return "%vmovapd\t{%1, %0|%0, %1}";
2938
2939 case MODE_V2SF:
2940 gcc_assert (!TARGET_AVX);
2941 return "movlps\t{%1, %0|%0, %1}";
2942 case MODE_V1DF:
2943 gcc_assert (!TARGET_AVX);
2944 return "movlpd\t{%1, %0|%0, %1}";
2945
2946 case MODE_DI:
2947 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2948 /* Handle broken assemblers that require movd instead of movq. */
2949 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2950 return "%vmovd\t{%1, %0|%0, %1}";
2951 #endif
2952 return "%vmovq\t{%1, %0|%0, %1}";
2953
2954 default:
2955 gcc_unreachable ();
2956 }
2957
2958 default:
2959 gcc_unreachable ();
2960 }
2961 }
2962 [(set (attr "isa")
2963 (cond [(eq_attr "alternative" "3,4")
2964 (const_string "nox64")
2965 (eq_attr "alternative" "5,6,7,8,17,18")
2966 (const_string "x64")
2967 (eq_attr "alternative" "9,10,11,12")
2968 (const_string "sse2")
2969 ]
2970 (const_string "*")))
2971 (set (attr "type")
2972 (cond [(eq_attr "alternative" "0,1,2")
2973 (const_string "fmov")
2974 (eq_attr "alternative" "3,4")
2975 (const_string "multi")
2976 (eq_attr "alternative" "5,6,7,8")
2977 (const_string "imov")
2978 (eq_attr "alternative" "9,13")
2979 (const_string "sselog1")
2980 ]
2981 (const_string "ssemov")))
2982 (set (attr "modrm")
2983 (if_then_else (eq_attr "alternative" "8")
2984 (const_string "0")
2985 (const_string "*")))
2986 (set (attr "length_immediate")
2987 (if_then_else (eq_attr "alternative" "8")
2988 (const_string "8")
2989 (const_string "*")))
2990 (set (attr "prefix")
2991 (if_then_else (eq_attr "type" "sselog1,ssemov")
2992 (const_string "maybe_vex")
2993 (const_string "orig")))
2994 (set (attr "prefix_data16")
2995 (if_then_else
2996 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2997 (eq_attr "mode" "V1DF"))
2998 (const_string "1")
2999 (const_string "*")))
3000 (set (attr "mode")
3001 (cond [(eq_attr "alternative" "3,4,7")
3002 (const_string "SI")
3003 (eq_attr "alternative" "5,6,8,17,18")
3004 (const_string "DI")
3005
3006 /* xorps is one byte shorter for non-AVX targets. */
3007 (eq_attr "alternative" "9,13")
3008 (cond [(not (match_test "TARGET_SSE2"))
3009 (const_string "V4SF")
3010 (match_test "TARGET_AVX512F")
3011 (const_string "XI")
3012 (match_test "TARGET_AVX")
3013 (const_string "V2DF")
3014 (match_test "optimize_function_for_size_p (cfun)")
3015 (const_string "V4SF")
3016 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3017 (const_string "TI")
3018 ]
3019 (const_string "V2DF"))
3020
3021 /* For architectures resolving dependencies on
3022 whole SSE registers use movapd to break dependency
3023 chains, otherwise use short move to avoid extra work. */
3024
3025 /* movaps is one byte shorter for non-AVX targets. */
3026 (eq_attr "alternative" "10,14")
3027 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3028 (match_operand 1 "ext_sse_reg_operand"))
3029 (const_string "V8DF")
3030 (ior (not (match_test "TARGET_SSE2"))
3031 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3032 (const_string "V4SF")
3033 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3034 (const_string "V2DF")
3035 (match_test "TARGET_AVX")
3036 (const_string "DF")
3037 (match_test "optimize_function_for_size_p (cfun)")
3038 (const_string "V4SF")
3039 ]
3040 (const_string "DF"))
3041
3042 /* For architectures resolving dependencies on register
3043 parts we may avoid extra work to zero out upper part
3044 of register. */
3045 (eq_attr "alternative" "11,15")
3046 (cond [(not (match_test "TARGET_SSE2"))
3047 (const_string "V2SF")
3048 (match_test "TARGET_AVX")
3049 (const_string "DF")
3050 (match_test "TARGET_SSE_SPLIT_REGS")
3051 (const_string "V1DF")
3052 ]
3053 (const_string "DF"))
3054
3055 (and (eq_attr "alternative" "12,16")
3056 (not (match_test "TARGET_SSE2")))
3057 (const_string "V2SF")
3058 ]
3059 (const_string "DF")))])
3060
3061 (define_insn "*movsf_internal"
3062 [(set (match_operand:SF 0 "nonimmediate_operand"
3063 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3064 (match_operand:SF 1 "general_operand"
3065 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3066 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3067 && (!can_create_pseudo_p ()
3068 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3069 || GET_CODE (operands[1]) != CONST_DOUBLE
3070 || (optimize_function_for_size_p (cfun)
3071 && ((!TARGET_SSE_MATH
3072 && standard_80387_constant_p (operands[1]) > 0)
3073 || (TARGET_SSE_MATH
3074 && standard_sse_constant_p (operands[1]))))
3075 || memory_operand (operands[0], SFmode))"
3076 {
3077 switch (get_attr_type (insn))
3078 {
3079 case TYPE_FMOV:
3080 if (which_alternative == 2)
3081 return standard_80387_constant_opcode (operands[1]);
3082 return output_387_reg_move (insn, operands);
3083
3084 case TYPE_IMOV:
3085 return "mov{l}\t{%1, %0|%0, %1}";
3086
3087 case TYPE_SSELOG1:
3088 return standard_sse_constant_opcode (insn, operands[1]);
3089
3090 case TYPE_SSEMOV:
3091 switch (get_attr_mode (insn))
3092 {
3093 case MODE_SF:
3094 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3095 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3096 return "%vmovss\t{%1, %0|%0, %1}";
3097
3098 case MODE_V16SF:
3099 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3100 case MODE_V4SF:
3101 return "%vmovaps\t{%1, %0|%0, %1}";
3102
3103 case MODE_SI:
3104 return "%vmovd\t{%1, %0|%0, %1}";
3105
3106 default:
3107 gcc_unreachable ();
3108 }
3109
3110 case TYPE_MMXMOV:
3111 switch (get_attr_mode (insn))
3112 {
3113 case MODE_DI:
3114 return "movq\t{%1, %0|%0, %1}";
3115 case MODE_SI:
3116 return "movd\t{%1, %0|%0, %1}";
3117
3118 default:
3119 gcc_unreachable ();
3120 }
3121
3122 default:
3123 gcc_unreachable ();
3124 }
3125 }
3126 [(set (attr "type")
3127 (cond [(eq_attr "alternative" "0,1,2")
3128 (const_string "fmov")
3129 (eq_attr "alternative" "3,4")
3130 (const_string "imov")
3131 (eq_attr "alternative" "5")
3132 (const_string "sselog1")
3133 (eq_attr "alternative" "11,12,13,14,15")
3134 (const_string "mmxmov")
3135 ]
3136 (const_string "ssemov")))
3137 (set (attr "prefix")
3138 (if_then_else (eq_attr "type" "sselog1,ssemov")
3139 (const_string "maybe_vex")
3140 (const_string "orig")))
3141 (set (attr "prefix_data16")
3142 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3143 (const_string "1")
3144 (const_string "*")))
3145 (set (attr "mode")
3146 (cond [(eq_attr "alternative" "3,4,9,10,14,15")
3147 (const_string "SI")
3148 (eq_attr "alternative" "11")
3149 (const_string "DI")
3150 (eq_attr "alternative" "5")
3151 (cond [(not (match_test "TARGET_SSE2"))
3152 (const_string "V4SF")
3153 (match_test "TARGET_AVX512F")
3154 (const_string "V16SF")
3155 (match_test "TARGET_AVX")
3156 (const_string "V4SF")
3157 (match_test "optimize_function_for_size_p (cfun)")
3158 (const_string "V4SF")
3159 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3160 (const_string "TI")
3161 ]
3162 (const_string "V4SF"))
3163
3164 /* For architectures resolving dependencies on
3165 whole SSE registers use APS move to break dependency
3166 chains, otherwise use short move to avoid extra work.
3167
3168 Do the same for architectures resolving dependencies on
3169 the parts. While in DF mode it is better to always handle
3170 just register parts, the SF mode is different due to lack
3171 of instructions to load just part of the register. It is
3172 better to maintain the whole registers in single format
3173 to avoid problems on using packed logical operations. */
3174 (eq_attr "alternative" "6")
3175 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3176 (match_operand 1 "ext_sse_reg_operand"))
3177 (const_string "V16SF")
3178 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3179 (match_test "TARGET_SSE_SPLIT_REGS"))
3180 (const_string "V4SF")
3181 ]
3182 (const_string "SF"))
3183 ]
3184 (const_string "SF")))])
3185
3186 (define_split
3187 [(set (match_operand 0 "any_fp_register_operand")
3188 (match_operand 1 "memory_operand"))]
3189 "reload_completed
3190 && (GET_MODE (operands[0]) == TFmode
3191 || GET_MODE (operands[0]) == XFmode
3192 || GET_MODE (operands[0]) == DFmode
3193 || GET_MODE (operands[0]) == SFmode)
3194 && (operands[2] = find_constant_src (insn))"
3195 [(set (match_dup 0) (match_dup 2))]
3196 {
3197 rtx c = operands[2];
3198 int r = REGNO (operands[0]);
3199
3200 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3201 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3202 FAIL;
3203 })
3204
3205 (define_split
3206 [(set (match_operand 0 "any_fp_register_operand")
3207 (float_extend (match_operand 1 "memory_operand")))]
3208 "reload_completed
3209 && (GET_MODE (operands[0]) == TFmode
3210 || GET_MODE (operands[0]) == XFmode
3211 || GET_MODE (operands[0]) == DFmode)
3212 && (operands[2] = find_constant_src (insn))"
3213 [(set (match_dup 0) (match_dup 2))]
3214 {
3215 rtx c = operands[2];
3216 int r = REGNO (operands[0]);
3217
3218 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3219 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3220 FAIL;
3221 })
3222
3223 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3224 (define_split
3225 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3226 (match_operand:X87MODEF 1 "immediate_operand"))]
3227 "reload_completed
3228 && (standard_80387_constant_p (operands[1]) == 8
3229 || standard_80387_constant_p (operands[1]) == 9)"
3230 [(set (match_dup 0)(match_dup 1))
3231 (set (match_dup 0)
3232 (neg:X87MODEF (match_dup 0)))]
3233 {
3234 REAL_VALUE_TYPE r;
3235
3236 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3237 if (real_isnegzero (&r))
3238 operands[1] = CONST0_RTX (<MODE>mode);
3239 else
3240 operands[1] = CONST1_RTX (<MODE>mode);
3241 })
3242
3243 (define_split
3244 [(set (match_operand 0 "nonimmediate_operand")
3245 (match_operand 1 "general_operand"))]
3246 "reload_completed
3247 && (GET_MODE (operands[0]) == TFmode
3248 || GET_MODE (operands[0]) == XFmode
3249 || GET_MODE (operands[0]) == DFmode)
3250 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3251 [(const_int 0)]
3252 "ix86_split_long_move (operands); DONE;")
3253
3254 (define_insn "swapxf"
3255 [(set (match_operand:XF 0 "register_operand" "+f")
3256 (match_operand:XF 1 "register_operand" "+f"))
3257 (set (match_dup 1)
3258 (match_dup 0))]
3259 "TARGET_80387"
3260 {
3261 if (STACK_TOP_P (operands[0]))
3262 return "fxch\t%1";
3263 else
3264 return "fxch\t%0";
3265 }
3266 [(set_attr "type" "fxch")
3267 (set_attr "mode" "XF")])
3268
3269 (define_insn "*swap<mode>"
3270 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3271 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3272 (set (match_dup 1)
3273 (match_dup 0))]
3274 "TARGET_80387 || reload_completed"
3275 {
3276 if (STACK_TOP_P (operands[0]))
3277 return "fxch\t%1";
3278 else
3279 return "fxch\t%0";
3280 }
3281 [(set_attr "type" "fxch")
3282 (set_attr "mode" "<MODE>")])
3283 \f
3284 ;; Zero extension instructions
3285
3286 (define_expand "zero_extendsidi2"
3287 [(set (match_operand:DI 0 "nonimmediate_operand")
3288 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3289
3290 (define_insn "*zero_extendsidi2"
3291 [(set (match_operand:DI 0 "nonimmediate_operand"
3292 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3293 (zero_extend:DI
3294 (match_operand:SI 1 "x86_64_zext_operand"
3295 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3296 ""
3297 {
3298 switch (get_attr_type (insn))
3299 {
3300 case TYPE_IMOVX:
3301 if (ix86_use_lea_for_mov (insn, operands))
3302 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3303 else
3304 return "mov{l}\t{%1, %k0|%k0, %1}";
3305
3306 case TYPE_MULTI:
3307 return "#";
3308
3309 case TYPE_MMXMOV:
3310 return "movd\t{%1, %0|%0, %1}";
3311
3312 case TYPE_SSELOG1:
3313 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3314
3315 case TYPE_SSEMOV:
3316 if (GENERAL_REG_P (operands[0]))
3317 return "%vmovd\t{%1, %k0|%k0, %1}";
3318
3319 return "%vmovd\t{%1, %0|%0, %1}";
3320
3321 default:
3322 gcc_unreachable ();
3323 }
3324 }
3325 [(set (attr "isa")
3326 (cond [(eq_attr "alternative" "0,1,2")
3327 (const_string "nox64")
3328 (eq_attr "alternative" "3,7")
3329 (const_string "x64")
3330 (eq_attr "alternative" "8")
3331 (const_string "x64_sse4")
3332 (eq_attr "alternative" "10")
3333 (const_string "sse2")
3334 ]
3335 (const_string "*")))
3336 (set (attr "type")
3337 (cond [(eq_attr "alternative" "0,1,2,4")
3338 (const_string "multi")
3339 (eq_attr "alternative" "5,6")
3340 (const_string "mmxmov")
3341 (eq_attr "alternative" "7,9,10")
3342 (const_string "ssemov")
3343 (eq_attr "alternative" "8")
3344 (const_string "sselog1")
3345 ]
3346 (const_string "imovx")))
3347 (set (attr "prefix_extra")
3348 (if_then_else (eq_attr "alternative" "8")
3349 (const_string "1")
3350 (const_string "*")))
3351 (set (attr "length_immediate")
3352 (if_then_else (eq_attr "alternative" "8")
3353 (const_string "1")
3354 (const_string "*")))
3355 (set (attr "prefix")
3356 (if_then_else (eq_attr "type" "ssemov,sselog1")
3357 (const_string "maybe_vex")
3358 (const_string "orig")))
3359 (set (attr "prefix_0f")
3360 (if_then_else (eq_attr "type" "imovx")
3361 (const_string "0")
3362 (const_string "*")))
3363 (set (attr "mode")
3364 (cond [(eq_attr "alternative" "5,6")
3365 (const_string "DI")
3366 (eq_attr "alternative" "7,8,9")
3367 (const_string "TI")
3368 ]
3369 (const_string "SI")))])
3370
3371 (define_split
3372 [(set (match_operand:DI 0 "memory_operand")
3373 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3374 "reload_completed"
3375 [(set (match_dup 4) (const_int 0))]
3376 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3377
3378 (define_split
3379 [(set (match_operand:DI 0 "register_operand")
3380 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3381 "!TARGET_64BIT && reload_completed
3382 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3383 && true_regnum (operands[0]) == true_regnum (operands[1])"
3384 [(set (match_dup 4) (const_int 0))]
3385 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3386
3387 (define_split
3388 [(set (match_operand:DI 0 "nonimmediate_operand")
3389 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3390 "!TARGET_64BIT && reload_completed
3391 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3392 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3393 [(set (match_dup 3) (match_dup 1))
3394 (set (match_dup 4) (const_int 0))]
3395 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3396
3397 (define_insn "zero_extend<mode>di2"
3398 [(set (match_operand:DI 0 "register_operand" "=r")
3399 (zero_extend:DI
3400 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3401 "TARGET_64BIT"
3402 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3403 [(set_attr "type" "imovx")
3404 (set_attr "mode" "SI")])
3405
3406 (define_expand "zero_extend<mode>si2"
3407 [(set (match_operand:SI 0 "register_operand")
3408 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3409 ""
3410 {
3411 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3412 {
3413 operands[1] = force_reg (<MODE>mode, operands[1]);
3414 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3415 DONE;
3416 }
3417 })
3418
3419 (define_insn_and_split "zero_extend<mode>si2_and"
3420 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3421 (zero_extend:SI
3422 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3423 (clobber (reg:CC FLAGS_REG))]
3424 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3425 "#"
3426 "&& reload_completed"
3427 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3428 (clobber (reg:CC FLAGS_REG))])]
3429 {
3430 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3431 {
3432 ix86_expand_clear (operands[0]);
3433
3434 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3435 emit_insn (gen_movstrict<mode>
3436 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3437 DONE;
3438 }
3439
3440 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3441 }
3442 [(set_attr "type" "alu1")
3443 (set_attr "mode" "SI")])
3444
3445 (define_insn "*zero_extend<mode>si2"
3446 [(set (match_operand:SI 0 "register_operand" "=r")
3447 (zero_extend:SI
3448 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3449 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3450 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3451 [(set_attr "type" "imovx")
3452 (set_attr "mode" "SI")])
3453
3454 (define_expand "zero_extendqihi2"
3455 [(set (match_operand:HI 0 "register_operand")
3456 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3457 ""
3458 {
3459 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3460 {
3461 operands[1] = force_reg (QImode, operands[1]);
3462 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3463 DONE;
3464 }
3465 })
3466
3467 (define_insn_and_split "zero_extendqihi2_and"
3468 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3469 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3470 (clobber (reg:CC FLAGS_REG))]
3471 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3472 "#"
3473 "&& reload_completed"
3474 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3475 (clobber (reg:CC FLAGS_REG))])]
3476 {
3477 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3478 {
3479 ix86_expand_clear (operands[0]);
3480
3481 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3482 emit_insn (gen_movstrictqi
3483 (gen_lowpart (QImode, operands[0]), operands[1]));
3484 DONE;
3485 }
3486
3487 operands[0] = gen_lowpart (SImode, operands[0]);
3488 }
3489 [(set_attr "type" "alu1")
3490 (set_attr "mode" "SI")])
3491
3492 ; zero extend to SImode to avoid partial register stalls
3493 (define_insn "*zero_extendqihi2"
3494 [(set (match_operand:HI 0 "register_operand" "=r")
3495 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3496 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3497 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3498 [(set_attr "type" "imovx")
3499 (set_attr "mode" "SI")])
3500 \f
3501 ;; Sign extension instructions
3502
3503 (define_expand "extendsidi2"
3504 [(set (match_operand:DI 0 "register_operand")
3505 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3506 ""
3507 {
3508 if (!TARGET_64BIT)
3509 {
3510 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3511 DONE;
3512 }
3513 })
3514
3515 (define_insn "*extendsidi2_rex64"
3516 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3517 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3518 "TARGET_64BIT"
3519 "@
3520 {cltq|cdqe}
3521 movs{lq|x}\t{%1, %0|%0, %1}"
3522 [(set_attr "type" "imovx")
3523 (set_attr "mode" "DI")
3524 (set_attr "prefix_0f" "0")
3525 (set_attr "modrm" "0,1")])
3526
3527 (define_insn "extendsidi2_1"
3528 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3529 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3530 (clobber (reg:CC FLAGS_REG))
3531 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3532 "!TARGET_64BIT"
3533 "#")
3534
3535 ;; Split the memory case. If the source register doesn't die, it will stay
3536 ;; this way, if it does die, following peephole2s take care of it.
3537 (define_split
3538 [(set (match_operand:DI 0 "memory_operand")
3539 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3540 (clobber (reg:CC FLAGS_REG))
3541 (clobber (match_operand:SI 2 "register_operand"))]
3542 "reload_completed"
3543 [(const_int 0)]
3544 {
3545 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3546
3547 emit_move_insn (operands[3], operands[1]);
3548
3549 /* Generate a cltd if possible and doing so it profitable. */
3550 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3551 && true_regnum (operands[1]) == AX_REG
3552 && true_regnum (operands[2]) == DX_REG)
3553 {
3554 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3555 }
3556 else
3557 {
3558 emit_move_insn (operands[2], operands[1]);
3559 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3560 }
3561 emit_move_insn (operands[4], operands[2]);
3562 DONE;
3563 })
3564
3565 ;; Peepholes for the case where the source register does die, after
3566 ;; being split with the above splitter.
3567 (define_peephole2
3568 [(set (match_operand:SI 0 "memory_operand")
3569 (match_operand:SI 1 "register_operand"))
3570 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3571 (parallel [(set (match_dup 2)
3572 (ashiftrt:SI (match_dup 2) (const_int 31)))
3573 (clobber (reg:CC FLAGS_REG))])
3574 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3575 "REGNO (operands[1]) != REGNO (operands[2])
3576 && peep2_reg_dead_p (2, operands[1])
3577 && peep2_reg_dead_p (4, operands[2])
3578 && !reg_mentioned_p (operands[2], operands[3])"
3579 [(set (match_dup 0) (match_dup 1))
3580 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3581 (clobber (reg:CC FLAGS_REG))])
3582 (set (match_dup 3) (match_dup 1))])
3583
3584 (define_peephole2
3585 [(set (match_operand:SI 0 "memory_operand")
3586 (match_operand:SI 1 "register_operand"))
3587 (parallel [(set (match_operand:SI 2 "register_operand")
3588 (ashiftrt:SI (match_dup 1) (const_int 31)))
3589 (clobber (reg:CC FLAGS_REG))])
3590 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3591 "/* cltd is shorter than sarl $31, %eax */
3592 !optimize_function_for_size_p (cfun)
3593 && true_regnum (operands[1]) == AX_REG
3594 && true_regnum (operands[2]) == DX_REG
3595 && peep2_reg_dead_p (2, operands[1])
3596 && peep2_reg_dead_p (3, operands[2])
3597 && !reg_mentioned_p (operands[2], operands[3])"
3598 [(set (match_dup 0) (match_dup 1))
3599 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3600 (clobber (reg:CC FLAGS_REG))])
3601 (set (match_dup 3) (match_dup 1))])
3602
3603 ;; Extend to register case. Optimize case where source and destination
3604 ;; registers match and cases where we can use cltd.
3605 (define_split
3606 [(set (match_operand:DI 0 "register_operand")
3607 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3608 (clobber (reg:CC FLAGS_REG))
3609 (clobber (match_scratch:SI 2))]
3610 "reload_completed"
3611 [(const_int 0)]
3612 {
3613 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3614
3615 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3616 emit_move_insn (operands[3], operands[1]);
3617
3618 /* Generate a cltd if possible and doing so it profitable. */
3619 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3620 && true_regnum (operands[3]) == AX_REG
3621 && true_regnum (operands[4]) == DX_REG)
3622 {
3623 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3624 DONE;
3625 }
3626
3627 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3628 emit_move_insn (operands[4], operands[1]);
3629
3630 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3631 DONE;
3632 })
3633
3634 (define_insn "extend<mode>di2"
3635 [(set (match_operand:DI 0 "register_operand" "=r")
3636 (sign_extend:DI
3637 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3638 "TARGET_64BIT"
3639 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3640 [(set_attr "type" "imovx")
3641 (set_attr "mode" "DI")])
3642
3643 (define_insn "extendhisi2"
3644 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3645 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3646 ""
3647 {
3648 switch (get_attr_prefix_0f (insn))
3649 {
3650 case 0:
3651 return "{cwtl|cwde}";
3652 default:
3653 return "movs{wl|x}\t{%1, %0|%0, %1}";
3654 }
3655 }
3656 [(set_attr "type" "imovx")
3657 (set_attr "mode" "SI")
3658 (set (attr "prefix_0f")
3659 ;; movsx is short decodable while cwtl is vector decoded.
3660 (if_then_else (and (eq_attr "cpu" "!k6")
3661 (eq_attr "alternative" "0"))
3662 (const_string "0")
3663 (const_string "1")))
3664 (set (attr "modrm")
3665 (if_then_else (eq_attr "prefix_0f" "0")
3666 (const_string "0")
3667 (const_string "1")))])
3668
3669 (define_insn "*extendhisi2_zext"
3670 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3671 (zero_extend:DI
3672 (sign_extend:SI
3673 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3674 "TARGET_64BIT"
3675 {
3676 switch (get_attr_prefix_0f (insn))
3677 {
3678 case 0:
3679 return "{cwtl|cwde}";
3680 default:
3681 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3682 }
3683 }
3684 [(set_attr "type" "imovx")
3685 (set_attr "mode" "SI")
3686 (set (attr "prefix_0f")
3687 ;; movsx is short decodable while cwtl is vector decoded.
3688 (if_then_else (and (eq_attr "cpu" "!k6")
3689 (eq_attr "alternative" "0"))
3690 (const_string "0")
3691 (const_string "1")))
3692 (set (attr "modrm")
3693 (if_then_else (eq_attr "prefix_0f" "0")
3694 (const_string "0")
3695 (const_string "1")))])
3696
3697 (define_insn "extendqisi2"
3698 [(set (match_operand:SI 0 "register_operand" "=r")
3699 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3700 ""
3701 "movs{bl|x}\t{%1, %0|%0, %1}"
3702 [(set_attr "type" "imovx")
3703 (set_attr "mode" "SI")])
3704
3705 (define_insn "*extendqisi2_zext"
3706 [(set (match_operand:DI 0 "register_operand" "=r")
3707 (zero_extend:DI
3708 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3709 "TARGET_64BIT"
3710 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3711 [(set_attr "type" "imovx")
3712 (set_attr "mode" "SI")])
3713
3714 (define_insn "extendqihi2"
3715 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3716 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3717 ""
3718 {
3719 switch (get_attr_prefix_0f (insn))
3720 {
3721 case 0:
3722 return "{cbtw|cbw}";
3723 default:
3724 return "movs{bw|x}\t{%1, %0|%0, %1}";
3725 }
3726 }
3727 [(set_attr "type" "imovx")
3728 (set_attr "mode" "HI")
3729 (set (attr "prefix_0f")
3730 ;; movsx is short decodable while cwtl is vector decoded.
3731 (if_then_else (and (eq_attr "cpu" "!k6")
3732 (eq_attr "alternative" "0"))
3733 (const_string "0")
3734 (const_string "1")))
3735 (set (attr "modrm")
3736 (if_then_else (eq_attr "prefix_0f" "0")
3737 (const_string "0")
3738 (const_string "1")))])
3739 \f
3740 ;; Conversions between float and double.
3741
3742 ;; These are all no-ops in the model used for the 80387.
3743 ;; So just emit moves.
3744
3745 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3746 (define_split
3747 [(set (match_operand:DF 0 "push_operand")
3748 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3749 "reload_completed"
3750 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3751 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3752
3753 (define_split
3754 [(set (match_operand:XF 0 "push_operand")
3755 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3756 "reload_completed"
3757 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3758 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3759 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3760
3761 (define_expand "extendsfdf2"
3762 [(set (match_operand:DF 0 "nonimmediate_operand")
3763 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3764 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3765 {
3766 /* ??? Needed for compress_float_constant since all fp constants
3767 are TARGET_LEGITIMATE_CONSTANT_P. */
3768 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3769 {
3770 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3771 && standard_80387_constant_p (operands[1]) > 0)
3772 {
3773 operands[1] = simplify_const_unary_operation
3774 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3775 emit_move_insn_1 (operands[0], operands[1]);
3776 DONE;
3777 }
3778 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3779 }
3780 })
3781
3782 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3783 cvtss2sd:
3784 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3785 cvtps2pd xmm2,xmm1
3786 We do the conversion post reload to avoid producing of 128bit spills
3787 that might lead to ICE on 32bit target. The sequence unlikely combine
3788 anyway. */
3789 (define_split
3790 [(set (match_operand:DF 0 "register_operand")
3791 (float_extend:DF
3792 (match_operand:SF 1 "nonimmediate_operand")))]
3793 "TARGET_USE_VECTOR_FP_CONVERTS
3794 && optimize_insn_for_speed_p ()
3795 && reload_completed && SSE_REG_P (operands[0])"
3796 [(set (match_dup 2)
3797 (float_extend:V2DF
3798 (vec_select:V2SF
3799 (match_dup 3)
3800 (parallel [(const_int 0) (const_int 1)]))))]
3801 {
3802 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3803 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3804 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3805 Try to avoid move when unpacking can be done in source. */
3806 if (REG_P (operands[1]))
3807 {
3808 /* If it is unsafe to overwrite upper half of source, we need
3809 to move to destination and unpack there. */
3810 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3811 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3812 && true_regnum (operands[0]) != true_regnum (operands[1]))
3813 {
3814 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3815 emit_move_insn (tmp, operands[1]);
3816 }
3817 else
3818 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3819 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3820 operands[3]));
3821 }
3822 else
3823 emit_insn (gen_vec_setv4sf_0 (operands[3],
3824 CONST0_RTX (V4SFmode), operands[1]));
3825 })
3826
3827 ;; It's more profitable to split and then extend in the same register.
3828 (define_peephole2
3829 [(set (match_operand:DF 0 "register_operand")
3830 (float_extend:DF
3831 (match_operand:SF 1 "memory_operand")))]
3832 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3833 && optimize_insn_for_speed_p ()
3834 && SSE_REG_P (operands[0])"
3835 [(set (match_dup 2) (match_dup 1))
3836 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3837 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3838
3839 (define_insn "*extendsfdf2_mixed"
3840 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3841 (float_extend:DF
3842 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3843 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3844 {
3845 switch (which_alternative)
3846 {
3847 case 0:
3848 case 1:
3849 return output_387_reg_move (insn, operands);
3850
3851 case 2:
3852 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3853
3854 default:
3855 gcc_unreachable ();
3856 }
3857 }
3858 [(set_attr "type" "fmov,fmov,ssecvt")
3859 (set_attr "prefix" "orig,orig,maybe_vex")
3860 (set_attr "mode" "SF,XF,DF")])
3861
3862 (define_insn "*extendsfdf2_sse"
3863 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3864 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3865 "TARGET_SSE2 && TARGET_SSE_MATH"
3866 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3867 [(set_attr "type" "ssecvt")
3868 (set_attr "prefix" "maybe_vex")
3869 (set_attr "mode" "DF")])
3870
3871 (define_insn "*extendsfdf2_i387"
3872 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3873 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3874 "TARGET_80387"
3875 "* return output_387_reg_move (insn, operands);"
3876 [(set_attr "type" "fmov")
3877 (set_attr "mode" "SF,XF")])
3878
3879 (define_expand "extend<mode>xf2"
3880 [(set (match_operand:XF 0 "nonimmediate_operand")
3881 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3882 "TARGET_80387"
3883 {
3884 /* ??? Needed for compress_float_constant since all fp constants
3885 are TARGET_LEGITIMATE_CONSTANT_P. */
3886 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3887 {
3888 if (standard_80387_constant_p (operands[1]) > 0)
3889 {
3890 operands[1] = simplify_const_unary_operation
3891 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3892 emit_move_insn_1 (operands[0], operands[1]);
3893 DONE;
3894 }
3895 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3896 }
3897 })
3898
3899 (define_insn "*extend<mode>xf2_i387"
3900 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3901 (float_extend:XF
3902 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3903 "TARGET_80387"
3904 "* return output_387_reg_move (insn, operands);"
3905 [(set_attr "type" "fmov")
3906 (set_attr "mode" "<MODE>,XF")])
3907
3908 ;; %%% This seems bad bad news.
3909 ;; This cannot output into an f-reg because there is no way to be sure
3910 ;; of truncating in that case. Otherwise this is just like a simple move
3911 ;; insn. So we pretend we can output to a reg in order to get better
3912 ;; register preferencing, but we really use a stack slot.
3913
3914 ;; Conversion from DFmode to SFmode.
3915
3916 (define_expand "truncdfsf2"
3917 [(set (match_operand:SF 0 "nonimmediate_operand")
3918 (float_truncate:SF
3919 (match_operand:DF 1 "nonimmediate_operand")))]
3920 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3921 {
3922 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3923 ;
3924 else if (flag_unsafe_math_optimizations)
3925 ;
3926 else
3927 {
3928 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3929 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3930 DONE;
3931 }
3932 })
3933
3934 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3935 cvtsd2ss:
3936 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3937 cvtpd2ps xmm2,xmm1
3938 We do the conversion post reload to avoid producing of 128bit spills
3939 that might lead to ICE on 32bit target. The sequence unlikely combine
3940 anyway. */
3941 (define_split
3942 [(set (match_operand:SF 0 "register_operand")
3943 (float_truncate:SF
3944 (match_operand:DF 1 "nonimmediate_operand")))]
3945 "TARGET_USE_VECTOR_FP_CONVERTS
3946 && optimize_insn_for_speed_p ()
3947 && reload_completed && SSE_REG_P (operands[0])"
3948 [(set (match_dup 2)
3949 (vec_concat:V4SF
3950 (float_truncate:V2SF
3951 (match_dup 4))
3952 (match_dup 3)))]
3953 {
3954 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3955 operands[3] = CONST0_RTX (V2SFmode);
3956 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3957 /* Use movsd for loading from memory, unpcklpd for registers.
3958 Try to avoid move when unpacking can be done in source, or SSE3
3959 movddup is available. */
3960 if (REG_P (operands[1]))
3961 {
3962 if (!TARGET_SSE3
3963 && true_regnum (operands[0]) != true_regnum (operands[1])
3964 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3965 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3966 {
3967 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3968 emit_move_insn (tmp, operands[1]);
3969 operands[1] = tmp;
3970 }
3971 else if (!TARGET_SSE3)
3972 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3973 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3974 }
3975 else
3976 emit_insn (gen_sse2_loadlpd (operands[4],
3977 CONST0_RTX (V2DFmode), operands[1]));
3978 })
3979
3980 ;; It's more profitable to split and then extend in the same register.
3981 (define_peephole2
3982 [(set (match_operand:SF 0 "register_operand")
3983 (float_truncate:SF
3984 (match_operand:DF 1 "memory_operand")))]
3985 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3986 && optimize_insn_for_speed_p ()
3987 && SSE_REG_P (operands[0])"
3988 [(set (match_dup 2) (match_dup 1))
3989 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
3990 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
3991
3992 (define_expand "truncdfsf2_with_temp"
3993 [(parallel [(set (match_operand:SF 0)
3994 (float_truncate:SF (match_operand:DF 1)))
3995 (clobber (match_operand:SF 2))])])
3996
3997 (define_insn "*truncdfsf_fast_mixed"
3998 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
3999 (float_truncate:SF
4000 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4001 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4002 {
4003 switch (which_alternative)
4004 {
4005 case 0:
4006 return output_387_reg_move (insn, operands);
4007 case 1:
4008 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4009 default:
4010 gcc_unreachable ();
4011 }
4012 }
4013 [(set_attr "type" "fmov,ssecvt")
4014 (set_attr "prefix" "orig,maybe_vex")
4015 (set_attr "mode" "SF")])
4016
4017 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4018 ;; because nothing we do here is unsafe.
4019 (define_insn "*truncdfsf_fast_sse"
4020 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4021 (float_truncate:SF
4022 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4023 "TARGET_SSE2 && TARGET_SSE_MATH"
4024 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4025 [(set_attr "type" "ssecvt")
4026 (set_attr "prefix" "maybe_vex")
4027 (set_attr "mode" "SF")])
4028
4029 (define_insn "*truncdfsf_fast_i387"
4030 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4031 (float_truncate:SF
4032 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4033 "TARGET_80387 && flag_unsafe_math_optimizations"
4034 "* return output_387_reg_move (insn, operands);"
4035 [(set_attr "type" "fmov")
4036 (set_attr "mode" "SF")])
4037
4038 (define_insn "*truncdfsf_mixed"
4039 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4040 (float_truncate:SF
4041 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4042 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4043 "TARGET_MIX_SSE_I387"
4044 {
4045 switch (which_alternative)
4046 {
4047 case 0:
4048 return output_387_reg_move (insn, operands);
4049 case 1:
4050 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4051
4052 default:
4053 return "#";
4054 }
4055 }
4056 [(set_attr "isa" "*,sse2,*,*,*")
4057 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4058 (set_attr "unit" "*,*,i387,i387,i387")
4059 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4060 (set_attr "mode" "SF")])
4061
4062 (define_insn "*truncdfsf_i387"
4063 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4064 (float_truncate:SF
4065 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4066 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4067 "TARGET_80387"
4068 {
4069 switch (which_alternative)
4070 {
4071 case 0:
4072 return output_387_reg_move (insn, operands);
4073
4074 default:
4075 return "#";
4076 }
4077 }
4078 [(set_attr "type" "fmov,multi,multi,multi")
4079 (set_attr "unit" "*,i387,i387,i387")
4080 (set_attr "mode" "SF")])
4081
4082 (define_insn "*truncdfsf2_i387_1"
4083 [(set (match_operand:SF 0 "memory_operand" "=m")
4084 (float_truncate:SF
4085 (match_operand:DF 1 "register_operand" "f")))]
4086 "TARGET_80387
4087 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4088 && !TARGET_MIX_SSE_I387"
4089 "* return output_387_reg_move (insn, operands);"
4090 [(set_attr "type" "fmov")
4091 (set_attr "mode" "SF")])
4092
4093 (define_split
4094 [(set (match_operand:SF 0 "register_operand")
4095 (float_truncate:SF
4096 (match_operand:DF 1 "fp_register_operand")))
4097 (clobber (match_operand 2))]
4098 "reload_completed"
4099 [(set (match_dup 2) (match_dup 1))
4100 (set (match_dup 0) (match_dup 2))]
4101 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4102
4103 ;; Conversion from XFmode to {SF,DF}mode
4104
4105 (define_expand "truncxf<mode>2"
4106 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4107 (float_truncate:MODEF
4108 (match_operand:XF 1 "register_operand")))
4109 (clobber (match_dup 2))])]
4110 "TARGET_80387"
4111 {
4112 if (flag_unsafe_math_optimizations)
4113 {
4114 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4115 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4116 if (reg != operands[0])
4117 emit_move_insn (operands[0], reg);
4118 DONE;
4119 }
4120 else
4121 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4122 })
4123
4124 (define_insn "*truncxfsf2_mixed"
4125 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4126 (float_truncate:SF
4127 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4128 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4129 "TARGET_80387"
4130 {
4131 gcc_assert (!which_alternative);
4132 return output_387_reg_move (insn, operands);
4133 }
4134 [(set_attr "type" "fmov,multi,multi,multi")
4135 (set_attr "unit" "*,i387,i387,i387")
4136 (set_attr "mode" "SF")])
4137
4138 (define_insn "*truncxfdf2_mixed"
4139 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4140 (float_truncate:DF
4141 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4142 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4143 "TARGET_80387"
4144 {
4145 gcc_assert (!which_alternative);
4146 return output_387_reg_move (insn, operands);
4147 }
4148 [(set_attr "isa" "*,*,sse2,*")
4149 (set_attr "type" "fmov,multi,multi,multi")
4150 (set_attr "unit" "*,i387,i387,i387")
4151 (set_attr "mode" "DF")])
4152
4153 (define_insn "truncxf<mode>2_i387_noop"
4154 [(set (match_operand:MODEF 0 "register_operand" "=f")
4155 (float_truncate:MODEF
4156 (match_operand:XF 1 "register_operand" "f")))]
4157 "TARGET_80387 && flag_unsafe_math_optimizations"
4158 "* return output_387_reg_move (insn, operands);"
4159 [(set_attr "type" "fmov")
4160 (set_attr "mode" "<MODE>")])
4161
4162 (define_insn "*truncxf<mode>2_i387"
4163 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4164 (float_truncate:MODEF
4165 (match_operand:XF 1 "register_operand" "f")))]
4166 "TARGET_80387"
4167 "* return output_387_reg_move (insn, operands);"
4168 [(set_attr "type" "fmov")
4169 (set_attr "mode" "<MODE>")])
4170
4171 (define_split
4172 [(set (match_operand:MODEF 0 "register_operand")
4173 (float_truncate:MODEF
4174 (match_operand:XF 1 "register_operand")))
4175 (clobber (match_operand:MODEF 2 "memory_operand"))]
4176 "TARGET_80387 && reload_completed"
4177 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4178 (set (match_dup 0) (match_dup 2))])
4179
4180 (define_split
4181 [(set (match_operand:MODEF 0 "memory_operand")
4182 (float_truncate:MODEF
4183 (match_operand:XF 1 "register_operand")))
4184 (clobber (match_operand:MODEF 2 "memory_operand"))]
4185 "TARGET_80387"
4186 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4187 \f
4188 ;; Signed conversion to DImode.
4189
4190 (define_expand "fix_truncxfdi2"
4191 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4192 (fix:DI (match_operand:XF 1 "register_operand")))
4193 (clobber (reg:CC FLAGS_REG))])]
4194 "TARGET_80387"
4195 {
4196 if (TARGET_FISTTP)
4197 {
4198 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4199 DONE;
4200 }
4201 })
4202
4203 (define_expand "fix_trunc<mode>di2"
4204 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4205 (fix:DI (match_operand:MODEF 1 "register_operand")))
4206 (clobber (reg:CC FLAGS_REG))])]
4207 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4208 {
4209 if (TARGET_FISTTP
4210 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4211 {
4212 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4213 DONE;
4214 }
4215 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4216 {
4217 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4218 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4219 if (out != operands[0])
4220 emit_move_insn (operands[0], out);
4221 DONE;
4222 }
4223 })
4224
4225 ;; Signed conversion to SImode.
4226
4227 (define_expand "fix_truncxfsi2"
4228 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4229 (fix:SI (match_operand:XF 1 "register_operand")))
4230 (clobber (reg:CC FLAGS_REG))])]
4231 "TARGET_80387"
4232 {
4233 if (TARGET_FISTTP)
4234 {
4235 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4236 DONE;
4237 }
4238 })
4239
4240 (define_expand "fix_trunc<mode>si2"
4241 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4242 (fix:SI (match_operand:MODEF 1 "register_operand")))
4243 (clobber (reg:CC FLAGS_REG))])]
4244 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4245 {
4246 if (TARGET_FISTTP
4247 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4248 {
4249 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4250 DONE;
4251 }
4252 if (SSE_FLOAT_MODE_P (<MODE>mode))
4253 {
4254 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4255 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4256 if (out != operands[0])
4257 emit_move_insn (operands[0], out);
4258 DONE;
4259 }
4260 })
4261
4262 ;; Signed conversion to HImode.
4263
4264 (define_expand "fix_trunc<mode>hi2"
4265 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4266 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4267 (clobber (reg:CC FLAGS_REG))])]
4268 "TARGET_80387
4269 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4270 {
4271 if (TARGET_FISTTP)
4272 {
4273 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4274 DONE;
4275 }
4276 })
4277
4278 ;; Unsigned conversion to SImode.
4279
4280 (define_expand "fixuns_trunc<mode>si2"
4281 [(parallel
4282 [(set (match_operand:SI 0 "register_operand")
4283 (unsigned_fix:SI
4284 (match_operand:MODEF 1 "nonimmediate_operand")))
4285 (use (match_dup 2))
4286 (clobber (match_scratch:<ssevecmode> 3))
4287 (clobber (match_scratch:<ssevecmode> 4))])]
4288 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4289 {
4290 enum machine_mode mode = <MODE>mode;
4291 enum machine_mode vecmode = <ssevecmode>mode;
4292 REAL_VALUE_TYPE TWO31r;
4293 rtx two31;
4294
4295 if (optimize_insn_for_size_p ())
4296 FAIL;
4297
4298 real_ldexp (&TWO31r, &dconst1, 31);
4299 two31 = const_double_from_real_value (TWO31r, mode);
4300 two31 = ix86_build_const_vector (vecmode, true, two31);
4301 operands[2] = force_reg (vecmode, two31);
4302 })
4303
4304 (define_insn_and_split "*fixuns_trunc<mode>_1"
4305 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4306 (unsigned_fix:SI
4307 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4308 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4309 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4310 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4311 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4312 && optimize_function_for_speed_p (cfun)"
4313 "#"
4314 "&& reload_completed"
4315 [(const_int 0)]
4316 {
4317 ix86_split_convert_uns_si_sse (operands);
4318 DONE;
4319 })
4320
4321 ;; Unsigned conversion to HImode.
4322 ;; Without these patterns, we'll try the unsigned SI conversion which
4323 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4324
4325 (define_expand "fixuns_trunc<mode>hi2"
4326 [(set (match_dup 2)
4327 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4328 (set (match_operand:HI 0 "nonimmediate_operand")
4329 (subreg:HI (match_dup 2) 0))]
4330 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4331 "operands[2] = gen_reg_rtx (SImode);")
4332
4333 ;; When SSE is available, it is always faster to use it!
4334 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4335 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4336 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4337 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4338 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4339 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4340 [(set_attr "type" "sseicvt")
4341 (set_attr "prefix" "maybe_vex")
4342 (set (attr "prefix_rex")
4343 (if_then_else
4344 (match_test "<SWI48:MODE>mode == DImode")
4345 (const_string "1")
4346 (const_string "*")))
4347 (set_attr "mode" "<MODEF:MODE>")
4348 (set_attr "athlon_decode" "double,vector")
4349 (set_attr "amdfam10_decode" "double,double")
4350 (set_attr "bdver1_decode" "double,double")])
4351
4352 ;; Avoid vector decoded forms of the instruction.
4353 (define_peephole2
4354 [(match_scratch:MODEF 2 "x")
4355 (set (match_operand:SWI48 0 "register_operand")
4356 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4357 "TARGET_AVOID_VECTOR_DECODE
4358 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4359 && optimize_insn_for_speed_p ()"
4360 [(set (match_dup 2) (match_dup 1))
4361 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4362
4363 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4364 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4365 (fix:SWI248x (match_operand 1 "register_operand")))]
4366 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4367 && TARGET_FISTTP
4368 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4369 && (TARGET_64BIT || <MODE>mode != DImode))
4370 && TARGET_SSE_MATH)
4371 && can_create_pseudo_p ()"
4372 "#"
4373 "&& 1"
4374 [(const_int 0)]
4375 {
4376 if (memory_operand (operands[0], VOIDmode))
4377 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4378 else
4379 {
4380 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4381 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4382 operands[1],
4383 operands[2]));
4384 }
4385 DONE;
4386 }
4387 [(set_attr "type" "fisttp")
4388 (set_attr "mode" "<MODE>")])
4389
4390 (define_insn "fix_trunc<mode>_i387_fisttp"
4391 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4392 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4393 (clobber (match_scratch:XF 2 "=&1f"))]
4394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4395 && TARGET_FISTTP
4396 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4397 && (TARGET_64BIT || <MODE>mode != DImode))
4398 && TARGET_SSE_MATH)"
4399 "* return output_fix_trunc (insn, operands, true);"
4400 [(set_attr "type" "fisttp")
4401 (set_attr "mode" "<MODE>")])
4402
4403 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4404 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4405 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4406 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4407 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4408 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4409 && TARGET_FISTTP
4410 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4411 && (TARGET_64BIT || <MODE>mode != DImode))
4412 && TARGET_SSE_MATH)"
4413 "#"
4414 [(set_attr "type" "fisttp")
4415 (set_attr "mode" "<MODE>")])
4416
4417 (define_split
4418 [(set (match_operand:SWI248x 0 "register_operand")
4419 (fix:SWI248x (match_operand 1 "register_operand")))
4420 (clobber (match_operand:SWI248x 2 "memory_operand"))
4421 (clobber (match_scratch 3))]
4422 "reload_completed"
4423 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4424 (clobber (match_dup 3))])
4425 (set (match_dup 0) (match_dup 2))])
4426
4427 (define_split
4428 [(set (match_operand:SWI248x 0 "memory_operand")
4429 (fix:SWI248x (match_operand 1 "register_operand")))
4430 (clobber (match_operand:SWI248x 2 "memory_operand"))
4431 (clobber (match_scratch 3))]
4432 "reload_completed"
4433 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4434 (clobber (match_dup 3))])])
4435
4436 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4437 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4438 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4439 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4440 ;; function in i386.c.
4441 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4442 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4443 (fix:SWI248x (match_operand 1 "register_operand")))
4444 (clobber (reg:CC FLAGS_REG))]
4445 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4446 && !TARGET_FISTTP
4447 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4448 && (TARGET_64BIT || <MODE>mode != DImode))
4449 && can_create_pseudo_p ()"
4450 "#"
4451 "&& 1"
4452 [(const_int 0)]
4453 {
4454 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4455
4456 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4457 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4458 if (memory_operand (operands[0], VOIDmode))
4459 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4460 operands[2], operands[3]));
4461 else
4462 {
4463 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4464 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4465 operands[2], operands[3],
4466 operands[4]));
4467 }
4468 DONE;
4469 }
4470 [(set_attr "type" "fistp")
4471 (set_attr "i387_cw" "trunc")
4472 (set_attr "mode" "<MODE>")])
4473
4474 (define_insn "fix_truncdi_i387"
4475 [(set (match_operand:DI 0 "memory_operand" "=m")
4476 (fix:DI (match_operand 1 "register_operand" "f")))
4477 (use (match_operand:HI 2 "memory_operand" "m"))
4478 (use (match_operand:HI 3 "memory_operand" "m"))
4479 (clobber (match_scratch:XF 4 "=&1f"))]
4480 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4481 && !TARGET_FISTTP
4482 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4483 "* return output_fix_trunc (insn, operands, false);"
4484 [(set_attr "type" "fistp")
4485 (set_attr "i387_cw" "trunc")
4486 (set_attr "mode" "DI")])
4487
4488 (define_insn "fix_truncdi_i387_with_temp"
4489 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4490 (fix:DI (match_operand 1 "register_operand" "f,f")))
4491 (use (match_operand:HI 2 "memory_operand" "m,m"))
4492 (use (match_operand:HI 3 "memory_operand" "m,m"))
4493 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4494 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4495 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4496 && !TARGET_FISTTP
4497 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4498 "#"
4499 [(set_attr "type" "fistp")
4500 (set_attr "i387_cw" "trunc")
4501 (set_attr "mode" "DI")])
4502
4503 (define_split
4504 [(set (match_operand:DI 0 "register_operand")
4505 (fix:DI (match_operand 1 "register_operand")))
4506 (use (match_operand:HI 2 "memory_operand"))
4507 (use (match_operand:HI 3 "memory_operand"))
4508 (clobber (match_operand:DI 4 "memory_operand"))
4509 (clobber (match_scratch 5))]
4510 "reload_completed"
4511 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4512 (use (match_dup 2))
4513 (use (match_dup 3))
4514 (clobber (match_dup 5))])
4515 (set (match_dup 0) (match_dup 4))])
4516
4517 (define_split
4518 [(set (match_operand:DI 0 "memory_operand")
4519 (fix:DI (match_operand 1 "register_operand")))
4520 (use (match_operand:HI 2 "memory_operand"))
4521 (use (match_operand:HI 3 "memory_operand"))
4522 (clobber (match_operand:DI 4 "memory_operand"))
4523 (clobber (match_scratch 5))]
4524 "reload_completed"
4525 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4526 (use (match_dup 2))
4527 (use (match_dup 3))
4528 (clobber (match_dup 5))])])
4529
4530 (define_insn "fix_trunc<mode>_i387"
4531 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4532 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4533 (use (match_operand:HI 2 "memory_operand" "m"))
4534 (use (match_operand:HI 3 "memory_operand" "m"))]
4535 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4536 && !TARGET_FISTTP
4537 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4538 "* return output_fix_trunc (insn, operands, false);"
4539 [(set_attr "type" "fistp")
4540 (set_attr "i387_cw" "trunc")
4541 (set_attr "mode" "<MODE>")])
4542
4543 (define_insn "fix_trunc<mode>_i387_with_temp"
4544 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4545 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4546 (use (match_operand:HI 2 "memory_operand" "m,m"))
4547 (use (match_operand:HI 3 "memory_operand" "m,m"))
4548 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4549 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4550 && !TARGET_FISTTP
4551 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4552 "#"
4553 [(set_attr "type" "fistp")
4554 (set_attr "i387_cw" "trunc")
4555 (set_attr "mode" "<MODE>")])
4556
4557 (define_split
4558 [(set (match_operand:SWI24 0 "register_operand")
4559 (fix:SWI24 (match_operand 1 "register_operand")))
4560 (use (match_operand:HI 2 "memory_operand"))
4561 (use (match_operand:HI 3 "memory_operand"))
4562 (clobber (match_operand:SWI24 4 "memory_operand"))]
4563 "reload_completed"
4564 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4565 (use (match_dup 2))
4566 (use (match_dup 3))])
4567 (set (match_dup 0) (match_dup 4))])
4568
4569 (define_split
4570 [(set (match_operand:SWI24 0 "memory_operand")
4571 (fix:SWI24 (match_operand 1 "register_operand")))
4572 (use (match_operand:HI 2 "memory_operand"))
4573 (use (match_operand:HI 3 "memory_operand"))
4574 (clobber (match_operand:SWI24 4 "memory_operand"))]
4575 "reload_completed"
4576 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4577 (use (match_dup 2))
4578 (use (match_dup 3))])])
4579
4580 (define_insn "x86_fnstcw_1"
4581 [(set (match_operand:HI 0 "memory_operand" "=m")
4582 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4583 "TARGET_80387"
4584 "fnstcw\t%0"
4585 [(set (attr "length")
4586 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4587 (set_attr "mode" "HI")
4588 (set_attr "unit" "i387")
4589 (set_attr "bdver1_decode" "vector")])
4590
4591 (define_insn "x86_fldcw_1"
4592 [(set (reg:HI FPCR_REG)
4593 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4594 "TARGET_80387"
4595 "fldcw\t%0"
4596 [(set (attr "length")
4597 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4598 (set_attr "mode" "HI")
4599 (set_attr "unit" "i387")
4600 (set_attr "athlon_decode" "vector")
4601 (set_attr "amdfam10_decode" "vector")
4602 (set_attr "bdver1_decode" "vector")])
4603 \f
4604 ;; Conversion between fixed point and floating point.
4605
4606 ;; Even though we only accept memory inputs, the backend _really_
4607 ;; wants to be able to do this between registers.
4608
4609 (define_expand "floathi<mode>2"
4610 [(set (match_operand:X87MODEF 0 "register_operand")
4611 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4612 "TARGET_80387
4613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4614 || TARGET_MIX_SSE_I387)")
4615
4616 ;; Pre-reload splitter to add memory clobber to the pattern.
4617 (define_insn_and_split "*floathi<mode>2_1"
4618 [(set (match_operand:X87MODEF 0 "register_operand")
4619 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4620 "TARGET_80387
4621 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4622 || TARGET_MIX_SSE_I387)
4623 && can_create_pseudo_p ()"
4624 "#"
4625 "&& 1"
4626 [(parallel [(set (match_dup 0)
4627 (float:X87MODEF (match_dup 1)))
4628 (clobber (match_dup 2))])]
4629 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4630
4631 (define_insn "*floathi<mode>2_i387_with_temp"
4632 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4633 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4634 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4635 "TARGET_80387
4636 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4637 || TARGET_MIX_SSE_I387)"
4638 "#"
4639 [(set_attr "type" "fmov,multi")
4640 (set_attr "mode" "<MODE>")
4641 (set_attr "unit" "*,i387")
4642 (set_attr "fp_int_src" "true")])
4643
4644 (define_insn "*floathi<mode>2_i387"
4645 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4646 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4647 "TARGET_80387
4648 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4649 || TARGET_MIX_SSE_I387)"
4650 "fild%Z1\t%1"
4651 [(set_attr "type" "fmov")
4652 (set_attr "mode" "<MODE>")
4653 (set_attr "fp_int_src" "true")])
4654
4655 (define_split
4656 [(set (match_operand:X87MODEF 0 "register_operand")
4657 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4658 (clobber (match_operand:HI 2 "memory_operand"))]
4659 "TARGET_80387
4660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4661 || TARGET_MIX_SSE_I387)
4662 && reload_completed"
4663 [(set (match_dup 2) (match_dup 1))
4664 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4665
4666 (define_split
4667 [(set (match_operand:X87MODEF 0 "register_operand")
4668 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4669 (clobber (match_operand:HI 2 "memory_operand"))]
4670 "TARGET_80387
4671 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4672 || TARGET_MIX_SSE_I387)
4673 && reload_completed"
4674 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4675
4676 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4677 [(set (match_operand:X87MODEF 0 "register_operand")
4678 (float:X87MODEF
4679 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4680 "TARGET_80387
4681 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4682 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4683 {
4684 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4685 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4686 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4687 {
4688 rtx reg = gen_reg_rtx (XFmode);
4689 rtx (*insn)(rtx, rtx);
4690
4691 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4692
4693 if (<X87MODEF:MODE>mode == SFmode)
4694 insn = gen_truncxfsf2;
4695 else if (<X87MODEF:MODE>mode == DFmode)
4696 insn = gen_truncxfdf2;
4697 else
4698 gcc_unreachable ();
4699
4700 emit_insn (insn (operands[0], reg));
4701 DONE;
4702 }
4703 })
4704
4705 ;; Pre-reload splitter to add memory clobber to the pattern.
4706 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4707 [(set (match_operand:X87MODEF 0 "register_operand")
4708 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4709 "((TARGET_80387
4710 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4711 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4712 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4713 || TARGET_MIX_SSE_I387))
4714 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4715 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4716 && ((<SWI48x:MODE>mode == SImode
4717 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4718 && optimize_function_for_speed_p (cfun)
4719 && flag_trapping_math)
4720 || !(TARGET_INTER_UNIT_CONVERSIONS
4721 || optimize_function_for_size_p (cfun)))))
4722 && can_create_pseudo_p ()"
4723 "#"
4724 "&& 1"
4725 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4726 (clobber (match_dup 2))])]
4727 {
4728 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4729
4730 /* Avoid store forwarding (partial memory) stall penalty
4731 by passing DImode value through XMM registers. */
4732 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4733 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4734 && optimize_function_for_speed_p (cfun))
4735 {
4736 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4737 operands[1],
4738 operands[2]));
4739 DONE;
4740 }
4741 })
4742
4743 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4744 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4745 (float:MODEF
4746 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4747 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4748 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4749 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4750 "#"
4751 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4752 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4753 (set_attr "unit" "*,i387,*,*,*")
4754 (set_attr "athlon_decode" "*,*,double,direct,double")
4755 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4756 (set_attr "bdver1_decode" "*,*,double,direct,double")
4757 (set_attr "fp_int_src" "true")])
4758
4759 (define_insn "*floatsi<mode>2_vector_mixed"
4760 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4761 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4762 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4763 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4764 "@
4765 fild%Z1\t%1
4766 #"
4767 [(set_attr "type" "fmov,sseicvt")
4768 (set_attr "mode" "<MODE>,<ssevecmode>")
4769 (set_attr "unit" "i387,*")
4770 (set_attr "athlon_decode" "*,direct")
4771 (set_attr "amdfam10_decode" "*,double")
4772 (set_attr "bdver1_decode" "*,direct")
4773 (set_attr "fp_int_src" "true")])
4774
4775 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4776 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4777 (float:MODEF
4778 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4779 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4780 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4781 "#"
4782 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4783 (set_attr "mode" "<MODEF:MODE>")
4784 (set_attr "unit" "*,i387,*,*")
4785 (set_attr "athlon_decode" "*,*,double,direct")
4786 (set_attr "amdfam10_decode" "*,*,vector,double")
4787 (set_attr "bdver1_decode" "*,*,double,direct")
4788 (set_attr "fp_int_src" "true")])
4789
4790 (define_split
4791 [(set (match_operand:MODEF 0 "register_operand")
4792 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4793 (clobber (match_operand:SWI48 2 "memory_operand"))]
4794 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4795 && TARGET_INTER_UNIT_CONVERSIONS
4796 && reload_completed && SSE_REG_P (operands[0])"
4797 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4798
4799 (define_split
4800 [(set (match_operand:MODEF 0 "register_operand")
4801 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4802 (clobber (match_operand:SWI48 2 "memory_operand"))]
4803 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4804 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4805 && reload_completed && SSE_REG_P (operands[0])"
4806 [(set (match_dup 2) (match_dup 1))
4807 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4808
4809 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4810 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4811 (float:MODEF
4812 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4813 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4814 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4815 "@
4816 fild%Z1\t%1
4817 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4818 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4819 [(set_attr "type" "fmov,sseicvt,sseicvt")
4820 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4821 (set_attr "mode" "<MODEF:MODE>")
4822 (set (attr "prefix_rex")
4823 (if_then_else
4824 (and (eq_attr "prefix" "maybe_vex")
4825 (match_test "<SWI48:MODE>mode == DImode"))
4826 (const_string "1")
4827 (const_string "*")))
4828 (set_attr "unit" "i387,*,*")
4829 (set_attr "athlon_decode" "*,double,direct")
4830 (set_attr "amdfam10_decode" "*,vector,double")
4831 (set_attr "bdver1_decode" "*,double,direct")
4832 (set_attr "fp_int_src" "true")])
4833
4834 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4835 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4836 (float:MODEF
4837 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4838 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4839 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4840 "@
4841 fild%Z1\t%1
4842 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4843 [(set_attr "type" "fmov,sseicvt")
4844 (set_attr "prefix" "orig,maybe_vex")
4845 (set_attr "mode" "<MODEF:MODE>")
4846 (set (attr "prefix_rex")
4847 (if_then_else
4848 (and (eq_attr "prefix" "maybe_vex")
4849 (match_test "<SWI48:MODE>mode == DImode"))
4850 (const_string "1")
4851 (const_string "*")))
4852 (set_attr "athlon_decode" "*,direct")
4853 (set_attr "amdfam10_decode" "*,double")
4854 (set_attr "bdver1_decode" "*,direct")
4855 (set_attr "fp_int_src" "true")])
4856
4857 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4858 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4859 (float:MODEF
4860 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4861 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4862 "TARGET_SSE2 && TARGET_SSE_MATH
4863 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4864 "#"
4865 [(set_attr "type" "sseicvt")
4866 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4867 (set_attr "athlon_decode" "double,direct,double")
4868 (set_attr "amdfam10_decode" "vector,double,double")
4869 (set_attr "bdver1_decode" "double,direct,double")
4870 (set_attr "fp_int_src" "true")])
4871
4872 (define_insn "*floatsi<mode>2_vector_sse"
4873 [(set (match_operand:MODEF 0 "register_operand" "=x")
4874 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4875 "TARGET_SSE2 && TARGET_SSE_MATH
4876 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4877 "#"
4878 [(set_attr "type" "sseicvt")
4879 (set_attr "mode" "<MODE>")
4880 (set_attr "athlon_decode" "direct")
4881 (set_attr "amdfam10_decode" "double")
4882 (set_attr "bdver1_decode" "direct")
4883 (set_attr "fp_int_src" "true")])
4884
4885 (define_split
4886 [(set (match_operand:MODEF 0 "register_operand")
4887 (float:MODEF (match_operand:SI 1 "register_operand")))
4888 (clobber (match_operand:SI 2 "memory_operand"))]
4889 "TARGET_SSE2 && TARGET_SSE_MATH
4890 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4891 && reload_completed && SSE_REG_P (operands[0])"
4892 [(const_int 0)]
4893 {
4894 rtx op1 = operands[1];
4895
4896 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4897 <MODE>mode, 0);
4898 if (GET_CODE (op1) == SUBREG)
4899 op1 = SUBREG_REG (op1);
4900
4901 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4902 {
4903 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4904 emit_insn (gen_sse2_loadld (operands[4],
4905 CONST0_RTX (V4SImode), operands[1]));
4906 }
4907 /* We can ignore possible trapping value in the
4908 high part of SSE register for non-trapping math. */
4909 else if (SSE_REG_P (op1) && !flag_trapping_math)
4910 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4911 else
4912 {
4913 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4914 emit_move_insn (operands[2], operands[1]);
4915 emit_insn (gen_sse2_loadld (operands[4],
4916 CONST0_RTX (V4SImode), operands[2]));
4917 }
4918 if (<ssevecmode>mode == V4SFmode)
4919 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4920 else
4921 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4922 DONE;
4923 })
4924
4925 (define_split
4926 [(set (match_operand:MODEF 0 "register_operand")
4927 (float:MODEF (match_operand:SI 1 "memory_operand")))
4928 (clobber (match_operand:SI 2 "memory_operand"))]
4929 "TARGET_SSE2 && TARGET_SSE_MATH
4930 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4931 && reload_completed && SSE_REG_P (operands[0])"
4932 [(const_int 0)]
4933 {
4934 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4935 <MODE>mode, 0);
4936 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4937
4938 emit_insn (gen_sse2_loadld (operands[4],
4939 CONST0_RTX (V4SImode), operands[1]));
4940 if (<ssevecmode>mode == V4SFmode)
4941 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4942 else
4943 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4944 DONE;
4945 })
4946
4947 (define_split
4948 [(set (match_operand:MODEF 0 "register_operand")
4949 (float:MODEF (match_operand:SI 1 "register_operand")))]
4950 "TARGET_SSE2 && TARGET_SSE_MATH
4951 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4952 && reload_completed && SSE_REG_P (operands[0])"
4953 [(const_int 0)]
4954 {
4955 rtx op1 = operands[1];
4956
4957 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4958 <MODE>mode, 0);
4959 if (GET_CODE (op1) == SUBREG)
4960 op1 = SUBREG_REG (op1);
4961
4962 if (GENERAL_REG_P (op1))
4963 {
4964 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4965 if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4966 emit_insn (gen_sse2_loadld (operands[4],
4967 CONST0_RTX (V4SImode), operands[1]));
4968 else
4969 {
4970 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4971 operands[1]);
4972 emit_insn (gen_sse2_loadld (operands[4],
4973 CONST0_RTX (V4SImode), operands[5]));
4974 ix86_free_from_memory (GET_MODE (operands[1]));
4975 }
4976 }
4977 /* We can ignore possible trapping value in the
4978 high part of SSE register for non-trapping math. */
4979 else if (SSE_REG_P (op1) && !flag_trapping_math)
4980 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4981 else
4982 gcc_unreachable ();
4983 if (<ssevecmode>mode == V4SFmode)
4984 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4985 else
4986 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4987 DONE;
4988 })
4989
4990 (define_split
4991 [(set (match_operand:MODEF 0 "register_operand")
4992 (float:MODEF (match_operand:SI 1 "memory_operand")))]
4993 "TARGET_SSE2 && TARGET_SSE_MATH
4994 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4995 && reload_completed && SSE_REG_P (operands[0])"
4996 [(const_int 0)]
4997 {
4998 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4999 <MODE>mode, 0);
5000 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5001
5002 emit_insn (gen_sse2_loadld (operands[4],
5003 CONST0_RTX (V4SImode), operands[1]));
5004 if (<ssevecmode>mode == V4SFmode)
5005 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5006 else
5007 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5008 DONE;
5009 })
5010
5011 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
5012 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5013 (float:MODEF
5014 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
5015 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
5016 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5017 "#"
5018 [(set_attr "type" "sseicvt")
5019 (set_attr "mode" "<MODEF:MODE>")
5020 (set_attr "athlon_decode" "double,direct")
5021 (set_attr "amdfam10_decode" "vector,double")
5022 (set_attr "bdver1_decode" "double,direct")
5023 (set_attr "btver2_decode" "double,double")
5024 (set_attr "fp_int_src" "true")])
5025
5026 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
5027 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5028 (float:MODEF
5029 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
5030 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5031 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5032 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5033 [(set_attr "type" "sseicvt")
5034 (set_attr "prefix" "maybe_vex")
5035 (set_attr "mode" "<MODEF:MODE>")
5036 (set (attr "prefix_rex")
5037 (if_then_else
5038 (and (eq_attr "prefix" "maybe_vex")
5039 (match_test "<SWI48:MODE>mode == DImode"))
5040 (const_string "1")
5041 (const_string "*")))
5042 (set_attr "athlon_decode" "double,direct")
5043 (set_attr "amdfam10_decode" "vector,double")
5044 (set_attr "bdver1_decode" "double,direct")
5045 (set_attr "btver2_decode" "double,double")
5046 (set_attr "fp_int_src" "true")])
5047
5048 (define_split
5049 [(set (match_operand:MODEF 0 "register_operand")
5050 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
5051 (clobber (match_operand:SWI48 2 "memory_operand"))]
5052 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5053 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5054 && reload_completed && SSE_REG_P (operands[0])"
5055 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5056
5057 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
5058 [(set (match_operand:MODEF 0 "register_operand" "=x")
5059 (float:MODEF
5060 (match_operand:SWI48 1 "memory_operand" "m")))]
5061 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5062 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5063 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5064 [(set_attr "type" "sseicvt")
5065 (set_attr "prefix" "maybe_vex")
5066 (set_attr "mode" "<MODEF:MODE>")
5067 (set (attr "prefix_rex")
5068 (if_then_else
5069 (and (eq_attr "prefix" "maybe_vex")
5070 (match_test "<SWI48:MODE>mode == DImode"))
5071 (const_string "1")
5072 (const_string "*")))
5073 (set_attr "athlon_decode" "direct")
5074 (set_attr "amdfam10_decode" "double")
5075 (set_attr "bdver1_decode" "direct")
5076 (set_attr "fp_int_src" "true")])
5077
5078 (define_split
5079 [(set (match_operand:MODEF 0 "register_operand")
5080 (float:MODEF (match_operand:SWI48 1 "register_operand")))
5081 (clobber (match_operand:SWI48 2 "memory_operand"))]
5082 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5083 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5084 && reload_completed && SSE_REG_P (operands[0])"
5085 [(set (match_dup 2) (match_dup 1))
5086 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5087
5088 (define_split
5089 [(set (match_operand:MODEF 0 "register_operand")
5090 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
5091 (clobber (match_operand:SWI48 2 "memory_operand"))]
5092 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5093 && reload_completed && SSE_REG_P (operands[0])"
5094 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5095
5096 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5097 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5098 (float:X87MODEF
5099 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5100 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5101 "TARGET_80387
5102 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5103 "@
5104 fild%Z1\t%1
5105 #"
5106 [(set_attr "type" "fmov,multi")
5107 (set_attr "mode" "<X87MODEF:MODE>")
5108 (set_attr "unit" "*,i387")
5109 (set_attr "fp_int_src" "true")])
5110
5111 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5112 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5113 (float:X87MODEF
5114 (match_operand:SWI48x 1 "memory_operand" "m")))]
5115 "TARGET_80387
5116 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5117 "fild%Z1\t%1"
5118 [(set_attr "type" "fmov")
5119 (set_attr "mode" "<X87MODEF:MODE>")
5120 (set_attr "fp_int_src" "true")])
5121
5122 (define_split
5123 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5124 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5125 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5126 "TARGET_80387
5127 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5128 && reload_completed"
5129 [(set (match_dup 2) (match_dup 1))
5130 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5131
5132 (define_split
5133 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5134 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5135 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5136 "TARGET_80387
5137 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5138 && reload_completed"
5139 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5140
5141 ;; Avoid partial SSE register dependency stalls
5142
5143 (define_split
5144 [(set (match_operand:MODEF 0 "register_operand")
5145 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5146 "TARGET_SSE2 && TARGET_SSE_MATH
5147 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5148 && optimize_function_for_speed_p (cfun)
5149 && reload_completed && SSE_REG_P (operands[0])"
5150 [(set (match_dup 0)
5151 (vec_merge:<ssevecmode>
5152 (vec_duplicate:<ssevecmode>
5153 (float:MODEF (match_dup 1)))
5154 (match_dup 0)
5155 (const_int 1)))]
5156 {
5157 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5158 <MODE>mode, 0);
5159 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5160 })
5161
5162 (define_split
5163 [(set (match_operand:MODEF 0 "register_operand")
5164 (float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
5165 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5166 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5167 && optimize_function_for_speed_p (cfun)
5168 && reload_completed && SSE_REG_P (operands[0])"
5169 [(set (match_dup 0)
5170 (vec_merge:<ssevecmode>
5171 (vec_duplicate:<ssevecmode>
5172 (float:MODEF (match_dup 1)))
5173 (match_dup 0)
5174 (const_int 1)))]
5175 {
5176 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5177 <MODE>mode, 0);
5178 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5179 })
5180
5181 ;; Break partial reg stall for cvtsd2ss.
5182
5183 (define_peephole2
5184 [(set (match_operand:SF 0 "register_operand")
5185 (float_truncate:SF
5186 (match_operand:DF 1 "nonimmediate_operand")))]
5187 "TARGET_SSE2 && TARGET_SSE_MATH
5188 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5189 && optimize_function_for_speed_p (cfun)
5190 && SSE_REG_P (operands[0])
5191 && (!SSE_REG_P (operands[1])
5192 || REGNO (operands[0]) != REGNO (operands[1]))"
5193 [(set (match_dup 0)
5194 (vec_merge:V4SF
5195 (vec_duplicate:V4SF
5196 (float_truncate:V2SF
5197 (match_dup 1)))
5198 (match_dup 0)
5199 (const_int 1)))]
5200 {
5201 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5202 SFmode, 0);
5203 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5204 DFmode, 0);
5205 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5206 })
5207
5208 ;; Break partial reg stall for cvtss2sd.
5209
5210 (define_peephole2
5211 [(set (match_operand:DF 0 "register_operand")
5212 (float_extend:DF
5213 (match_operand:SF 1 "nonimmediate_operand")))]
5214 "TARGET_SSE2 && TARGET_SSE_MATH
5215 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5216 && optimize_function_for_speed_p (cfun)
5217 && SSE_REG_P (operands[0])
5218 && (!SSE_REG_P (operands[1])
5219 || REGNO (operands[0]) != REGNO (operands[1]))"
5220 [(set (match_dup 0)
5221 (vec_merge:V2DF
5222 (float_extend:V2DF
5223 (vec_select:V2SF
5224 (match_dup 1)
5225 (parallel [(const_int 0) (const_int 1)])))
5226 (match_dup 0)
5227 (const_int 1)))]
5228 {
5229 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5230 DFmode, 0);
5231 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5232 SFmode, 0);
5233 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5234 })
5235
5236 ;; Avoid store forwarding (partial memory) stall penalty
5237 ;; by passing DImode value through XMM registers. */
5238
5239 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5240 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5241 (float:X87MODEF
5242 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5243 (clobber (match_scratch:V4SI 3 "=X,x"))
5244 (clobber (match_scratch:V4SI 4 "=X,x"))
5245 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5246 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5247 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5248 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5249 "#"
5250 [(set_attr "type" "multi")
5251 (set_attr "mode" "<X87MODEF:MODE>")
5252 (set_attr "unit" "i387")
5253 (set_attr "fp_int_src" "true")])
5254
5255 (define_split
5256 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5257 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5258 (clobber (match_scratch:V4SI 3))
5259 (clobber (match_scratch:V4SI 4))
5260 (clobber (match_operand:DI 2 "memory_operand"))]
5261 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5262 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5263 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5264 && reload_completed"
5265 [(set (match_dup 2) (match_dup 3))
5266 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5267 {
5268 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5269 Assemble the 64-bit DImode value in an xmm register. */
5270 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5271 gen_rtx_SUBREG (SImode, operands[1], 0)));
5272 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5273 gen_rtx_SUBREG (SImode, operands[1], 4)));
5274 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5275 operands[4]));
5276
5277 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5278 })
5279
5280 (define_split
5281 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5282 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5283 (clobber (match_scratch:V4SI 3))
5284 (clobber (match_scratch:V4SI 4))
5285 (clobber (match_operand:DI 2 "memory_operand"))]
5286 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5287 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5288 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5289 && reload_completed"
5290 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5291
5292 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5293 [(set (match_operand:MODEF 0 "register_operand")
5294 (unsigned_float:MODEF
5295 (match_operand:SWI12 1 "nonimmediate_operand")))]
5296 "!TARGET_64BIT
5297 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5298 {
5299 operands[1] = convert_to_mode (SImode, operands[1], 1);
5300 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5301 DONE;
5302 })
5303
5304 ;; Avoid store forwarding (partial memory) stall penalty by extending
5305 ;; SImode value to DImode through XMM register instead of pushing two
5306 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5307 ;; targets benefit from this optimization. Also note that fild
5308 ;; loads from memory only.
5309
5310 (define_insn "*floatunssi<mode>2_1"
5311 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5312 (unsigned_float:X87MODEF
5313 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5314 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5315 (clobber (match_scratch:SI 3 "=X,x"))]
5316 "!TARGET_64BIT
5317 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5318 && TARGET_SSE"
5319 "#"
5320 [(set_attr "type" "multi")
5321 (set_attr "mode" "<MODE>")])
5322
5323 (define_split
5324 [(set (match_operand:X87MODEF 0 "register_operand")
5325 (unsigned_float:X87MODEF
5326 (match_operand:SI 1 "register_operand")))
5327 (clobber (match_operand:DI 2 "memory_operand"))
5328 (clobber (match_scratch:SI 3))]
5329 "!TARGET_64BIT
5330 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5331 && TARGET_SSE
5332 && reload_completed"
5333 [(set (match_dup 2) (match_dup 1))
5334 (set (match_dup 0)
5335 (float:X87MODEF (match_dup 2)))]
5336 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5337
5338 (define_split
5339 [(set (match_operand:X87MODEF 0 "register_operand")
5340 (unsigned_float:X87MODEF
5341 (match_operand:SI 1 "memory_operand")))
5342 (clobber (match_operand:DI 2 "memory_operand"))
5343 (clobber (match_scratch:SI 3))]
5344 "!TARGET_64BIT
5345 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5346 && TARGET_SSE
5347 && reload_completed"
5348 [(set (match_dup 2) (match_dup 3))
5349 (set (match_dup 0)
5350 (float:X87MODEF (match_dup 2)))]
5351 {
5352 emit_move_insn (operands[3], operands[1]);
5353 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5354 })
5355
5356 (define_expand "floatunssi<mode>2"
5357 [(parallel
5358 [(set (match_operand:X87MODEF 0 "register_operand")
5359 (unsigned_float:X87MODEF
5360 (match_operand:SI 1 "nonimmediate_operand")))
5361 (clobber (match_dup 2))
5362 (clobber (match_scratch:SI 3))])]
5363 "!TARGET_64BIT
5364 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5365 && TARGET_SSE)
5366 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5367 {
5368 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5369 {
5370 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5371 DONE;
5372 }
5373 else
5374 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5375 })
5376
5377 (define_expand "floatunsdisf2"
5378 [(use (match_operand:SF 0 "register_operand"))
5379 (use (match_operand:DI 1 "nonimmediate_operand"))]
5380 "TARGET_64BIT && TARGET_SSE_MATH"
5381 "x86_emit_floatuns (operands); DONE;")
5382
5383 (define_expand "floatunsdidf2"
5384 [(use (match_operand:DF 0 "register_operand"))
5385 (use (match_operand:DI 1 "nonimmediate_operand"))]
5386 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5387 && TARGET_SSE2 && TARGET_SSE_MATH"
5388 {
5389 if (TARGET_64BIT)
5390 x86_emit_floatuns (operands);
5391 else
5392 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5393 DONE;
5394 })
5395 \f
5396 ;; Load effective address instructions
5397
5398 (define_insn_and_split "*lea<mode>"
5399 [(set (match_operand:SWI48 0 "register_operand" "=r")
5400 (match_operand:SWI48 1 "address_no_seg_operand" "p"))]
5401 ""
5402 {
5403 if (SImode_address_operand (operands[1], VOIDmode))
5404 {
5405 gcc_assert (TARGET_64BIT);
5406 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5407 }
5408 else
5409 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5410 }
5411 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5412 [(const_int 0)]
5413 {
5414 enum machine_mode mode = <MODE>mode;
5415 rtx pat;
5416
5417 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5418 change operands[] array behind our back. */
5419 pat = PATTERN (curr_insn);
5420
5421 operands[0] = SET_DEST (pat);
5422 operands[1] = SET_SRC (pat);
5423
5424 /* Emit all operations in SImode for zero-extended addresses. Recall
5425 that x86_64 inheretly zero-extends SImode operations to DImode. */
5426 if (SImode_address_operand (operands[1], VOIDmode))
5427 mode = SImode;
5428
5429 ix86_split_lea_for_addr (curr_insn, operands, mode);
5430 DONE;
5431 }
5432 [(set_attr "type" "lea")
5433 (set (attr "mode")
5434 (if_then_else
5435 (match_operand 1 "SImode_address_operand")
5436 (const_string "SI")
5437 (const_string "<MODE>")))])
5438 \f
5439 ;; Add instructions
5440
5441 (define_expand "add<mode>3"
5442 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5443 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5444 (match_operand:SDWIM 2 "<general_operand>")))]
5445 ""
5446 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5447
5448 (define_insn_and_split "*add<dwi>3_doubleword"
5449 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5450 (plus:<DWI>
5451 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5452 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5453 (clobber (reg:CC FLAGS_REG))]
5454 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5455 "#"
5456 "reload_completed"
5457 [(parallel [(set (reg:CC FLAGS_REG)
5458 (unspec:CC [(match_dup 1) (match_dup 2)]
5459 UNSPEC_ADD_CARRY))
5460 (set (match_dup 0)
5461 (plus:DWIH (match_dup 1) (match_dup 2)))])
5462 (parallel [(set (match_dup 3)
5463 (plus:DWIH
5464 (match_dup 4)
5465 (plus:DWIH
5466 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5467 (match_dup 5))))
5468 (clobber (reg:CC FLAGS_REG))])]
5469 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5470
5471 (define_insn "*add<mode>3_cc"
5472 [(set (reg:CC FLAGS_REG)
5473 (unspec:CC
5474 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5475 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5476 UNSPEC_ADD_CARRY))
5477 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5478 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5479 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5480 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5481 [(set_attr "type" "alu")
5482 (set_attr "mode" "<MODE>")])
5483
5484 (define_insn "addqi3_cc"
5485 [(set (reg:CC FLAGS_REG)
5486 (unspec:CC
5487 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5488 (match_operand:QI 2 "general_operand" "qn,qm")]
5489 UNSPEC_ADD_CARRY))
5490 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5491 (plus:QI (match_dup 1) (match_dup 2)))]
5492 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5493 "add{b}\t{%2, %0|%0, %2}"
5494 [(set_attr "type" "alu")
5495 (set_attr "mode" "QI")])
5496
5497 (define_insn "*add<mode>_1"
5498 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5499 (plus:SWI48
5500 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5501 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5502 (clobber (reg:CC FLAGS_REG))]
5503 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5504 {
5505 switch (get_attr_type (insn))
5506 {
5507 case TYPE_LEA:
5508 return "#";
5509
5510 case TYPE_INCDEC:
5511 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5512 if (operands[2] == const1_rtx)
5513 return "inc{<imodesuffix>}\t%0";
5514 else
5515 {
5516 gcc_assert (operands[2] == constm1_rtx);
5517 return "dec{<imodesuffix>}\t%0";
5518 }
5519
5520 default:
5521 /* For most processors, ADD is faster than LEA. This alternative
5522 was added to use ADD as much as possible. */
5523 if (which_alternative == 2)
5524 {
5525 rtx tmp;
5526 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5527 }
5528
5529 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5530 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5531 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5532
5533 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5534 }
5535 }
5536 [(set (attr "type")
5537 (cond [(eq_attr "alternative" "3")
5538 (const_string "lea")
5539 (match_operand:SWI48 2 "incdec_operand")
5540 (const_string "incdec")
5541 ]
5542 (const_string "alu")))
5543 (set (attr "length_immediate")
5544 (if_then_else
5545 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5546 (const_string "1")
5547 (const_string "*")))
5548 (set_attr "mode" "<MODE>")])
5549
5550 ;; It may seem that nonimmediate operand is proper one for operand 1.
5551 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5552 ;; we take care in ix86_binary_operator_ok to not allow two memory
5553 ;; operands so proper swapping will be done in reload. This allow
5554 ;; patterns constructed from addsi_1 to match.
5555
5556 (define_insn "addsi_1_zext"
5557 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5558 (zero_extend:DI
5559 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5560 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5561 (clobber (reg:CC FLAGS_REG))]
5562 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5563 {
5564 switch (get_attr_type (insn))
5565 {
5566 case TYPE_LEA:
5567 return "#";
5568
5569 case TYPE_INCDEC:
5570 if (operands[2] == const1_rtx)
5571 return "inc{l}\t%k0";
5572 else
5573 {
5574 gcc_assert (operands[2] == constm1_rtx);
5575 return "dec{l}\t%k0";
5576 }
5577
5578 default:
5579 /* For most processors, ADD is faster than LEA. This alternative
5580 was added to use ADD as much as possible. */
5581 if (which_alternative == 1)
5582 {
5583 rtx tmp;
5584 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5585 }
5586
5587 if (x86_maybe_negate_const_int (&operands[2], SImode))
5588 return "sub{l}\t{%2, %k0|%k0, %2}";
5589
5590 return "add{l}\t{%2, %k0|%k0, %2}";
5591 }
5592 }
5593 [(set (attr "type")
5594 (cond [(eq_attr "alternative" "2")
5595 (const_string "lea")
5596 (match_operand:SI 2 "incdec_operand")
5597 (const_string "incdec")
5598 ]
5599 (const_string "alu")))
5600 (set (attr "length_immediate")
5601 (if_then_else
5602 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5603 (const_string "1")
5604 (const_string "*")))
5605 (set_attr "mode" "SI")])
5606
5607 (define_insn "*addhi_1"
5608 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5609 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5610 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5611 (clobber (reg:CC FLAGS_REG))]
5612 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5613 {
5614 switch (get_attr_type (insn))
5615 {
5616 case TYPE_LEA:
5617 return "#";
5618
5619 case TYPE_INCDEC:
5620 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5621 if (operands[2] == const1_rtx)
5622 return "inc{w}\t%0";
5623 else
5624 {
5625 gcc_assert (operands[2] == constm1_rtx);
5626 return "dec{w}\t%0";
5627 }
5628
5629 default:
5630 /* For most processors, ADD is faster than LEA. This alternative
5631 was added to use ADD as much as possible. */
5632 if (which_alternative == 2)
5633 {
5634 rtx tmp;
5635 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5636 }
5637
5638 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5639 if (x86_maybe_negate_const_int (&operands[2], HImode))
5640 return "sub{w}\t{%2, %0|%0, %2}";
5641
5642 return "add{w}\t{%2, %0|%0, %2}";
5643 }
5644 }
5645 [(set (attr "type")
5646 (cond [(eq_attr "alternative" "3")
5647 (const_string "lea")
5648 (match_operand:HI 2 "incdec_operand")
5649 (const_string "incdec")
5650 ]
5651 (const_string "alu")))
5652 (set (attr "length_immediate")
5653 (if_then_else
5654 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5655 (const_string "1")
5656 (const_string "*")))
5657 (set_attr "mode" "HI,HI,HI,SI")])
5658
5659 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5660 (define_insn "*addqi_1"
5661 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5662 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5663 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5664 (clobber (reg:CC FLAGS_REG))]
5665 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5666 {
5667 bool widen = (which_alternative == 3 || which_alternative == 4);
5668
5669 switch (get_attr_type (insn))
5670 {
5671 case TYPE_LEA:
5672 return "#";
5673
5674 case TYPE_INCDEC:
5675 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5676 if (operands[2] == const1_rtx)
5677 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5678 else
5679 {
5680 gcc_assert (operands[2] == constm1_rtx);
5681 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5682 }
5683
5684 default:
5685 /* For most processors, ADD is faster than LEA. These alternatives
5686 were added to use ADD as much as possible. */
5687 if (which_alternative == 2 || which_alternative == 4)
5688 {
5689 rtx tmp;
5690 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5691 }
5692
5693 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5694 if (x86_maybe_negate_const_int (&operands[2], QImode))
5695 {
5696 if (widen)
5697 return "sub{l}\t{%2, %k0|%k0, %2}";
5698 else
5699 return "sub{b}\t{%2, %0|%0, %2}";
5700 }
5701 if (widen)
5702 return "add{l}\t{%k2, %k0|%k0, %k2}";
5703 else
5704 return "add{b}\t{%2, %0|%0, %2}";
5705 }
5706 }
5707 [(set (attr "type")
5708 (cond [(eq_attr "alternative" "5")
5709 (const_string "lea")
5710 (match_operand:QI 2 "incdec_operand")
5711 (const_string "incdec")
5712 ]
5713 (const_string "alu")))
5714 (set (attr "length_immediate")
5715 (if_then_else
5716 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5717 (const_string "1")
5718 (const_string "*")))
5719 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5720
5721 (define_insn "*addqi_1_slp"
5722 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5723 (plus:QI (match_dup 0)
5724 (match_operand:QI 1 "general_operand" "qn,qm")))
5725 (clobber (reg:CC FLAGS_REG))]
5726 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5727 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5728 {
5729 switch (get_attr_type (insn))
5730 {
5731 case TYPE_INCDEC:
5732 if (operands[1] == const1_rtx)
5733 return "inc{b}\t%0";
5734 else
5735 {
5736 gcc_assert (operands[1] == constm1_rtx);
5737 return "dec{b}\t%0";
5738 }
5739
5740 default:
5741 if (x86_maybe_negate_const_int (&operands[1], QImode))
5742 return "sub{b}\t{%1, %0|%0, %1}";
5743
5744 return "add{b}\t{%1, %0|%0, %1}";
5745 }
5746 }
5747 [(set (attr "type")
5748 (if_then_else (match_operand:QI 1 "incdec_operand")
5749 (const_string "incdec")
5750 (const_string "alu1")))
5751 (set (attr "memory")
5752 (if_then_else (match_operand 1 "memory_operand")
5753 (const_string "load")
5754 (const_string "none")))
5755 (set_attr "mode" "QI")])
5756
5757 ;; Split non destructive adds if we cannot use lea.
5758 (define_split
5759 [(set (match_operand:SWI48 0 "register_operand")
5760 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5761 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5762 (clobber (reg:CC FLAGS_REG))]
5763 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5764 [(set (match_dup 0) (match_dup 1))
5765 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5766 (clobber (reg:CC FLAGS_REG))])])
5767
5768 ;; Convert add to the lea pattern to avoid flags dependency.
5769 (define_split
5770 [(set (match_operand:SWI 0 "register_operand")
5771 (plus:SWI (match_operand:SWI 1 "register_operand")
5772 (match_operand:SWI 2 "<nonmemory_operand>")))
5773 (clobber (reg:CC FLAGS_REG))]
5774 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5775 [(const_int 0)]
5776 {
5777 enum machine_mode mode = <MODE>mode;
5778 rtx pat;
5779
5780 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5781 {
5782 mode = SImode;
5783 operands[0] = gen_lowpart (mode, operands[0]);
5784 operands[1] = gen_lowpart (mode, operands[1]);
5785 operands[2] = gen_lowpart (mode, operands[2]);
5786 }
5787
5788 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5789
5790 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5791 DONE;
5792 })
5793
5794 ;; Split non destructive adds if we cannot use lea.
5795 (define_split
5796 [(set (match_operand:DI 0 "register_operand")
5797 (zero_extend:DI
5798 (plus:SI (match_operand:SI 1 "register_operand")
5799 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5800 (clobber (reg:CC FLAGS_REG))]
5801 "TARGET_64BIT
5802 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5803 [(set (match_dup 3) (match_dup 1))
5804 (parallel [(set (match_dup 0)
5805 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5806 (clobber (reg:CC FLAGS_REG))])]
5807 "operands[3] = gen_lowpart (SImode, operands[0]);")
5808
5809 ;; Convert add to the lea pattern to avoid flags dependency.
5810 (define_split
5811 [(set (match_operand:DI 0 "register_operand")
5812 (zero_extend:DI
5813 (plus:SI (match_operand:SI 1 "register_operand")
5814 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5815 (clobber (reg:CC FLAGS_REG))]
5816 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5817 [(set (match_dup 0)
5818 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5819
5820 (define_insn "*add<mode>_2"
5821 [(set (reg FLAGS_REG)
5822 (compare
5823 (plus:SWI
5824 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5825 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5826 (const_int 0)))
5827 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5828 (plus:SWI (match_dup 1) (match_dup 2)))]
5829 "ix86_match_ccmode (insn, CCGOCmode)
5830 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5831 {
5832 switch (get_attr_type (insn))
5833 {
5834 case TYPE_INCDEC:
5835 if (operands[2] == const1_rtx)
5836 return "inc{<imodesuffix>}\t%0";
5837 else
5838 {
5839 gcc_assert (operands[2] == constm1_rtx);
5840 return "dec{<imodesuffix>}\t%0";
5841 }
5842
5843 default:
5844 if (which_alternative == 2)
5845 {
5846 rtx tmp;
5847 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5848 }
5849
5850 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5851 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5852 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5853
5854 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5855 }
5856 }
5857 [(set (attr "type")
5858 (if_then_else (match_operand:SWI 2 "incdec_operand")
5859 (const_string "incdec")
5860 (const_string "alu")))
5861 (set (attr "length_immediate")
5862 (if_then_else
5863 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5864 (const_string "1")
5865 (const_string "*")))
5866 (set_attr "mode" "<MODE>")])
5867
5868 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5869 (define_insn "*addsi_2_zext"
5870 [(set (reg FLAGS_REG)
5871 (compare
5872 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5873 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5874 (const_int 0)))
5875 (set (match_operand:DI 0 "register_operand" "=r,r")
5876 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5877 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5878 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5879 {
5880 switch (get_attr_type (insn))
5881 {
5882 case TYPE_INCDEC:
5883 if (operands[2] == const1_rtx)
5884 return "inc{l}\t%k0";
5885 else
5886 {
5887 gcc_assert (operands[2] == constm1_rtx);
5888 return "dec{l}\t%k0";
5889 }
5890
5891 default:
5892 if (which_alternative == 1)
5893 {
5894 rtx tmp;
5895 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5896 }
5897
5898 if (x86_maybe_negate_const_int (&operands[2], SImode))
5899 return "sub{l}\t{%2, %k0|%k0, %2}";
5900
5901 return "add{l}\t{%2, %k0|%k0, %2}";
5902 }
5903 }
5904 [(set (attr "type")
5905 (if_then_else (match_operand:SI 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" "SI")])
5914
5915 (define_insn "*add<mode>_3"
5916 [(set (reg FLAGS_REG)
5917 (compare
5918 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5919 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5920 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5921 "ix86_match_ccmode (insn, CCZmode)
5922 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5923 {
5924 switch (get_attr_type (insn))
5925 {
5926 case TYPE_INCDEC:
5927 if (operands[2] == const1_rtx)
5928 return "inc{<imodesuffix>}\t%0";
5929 else
5930 {
5931 gcc_assert (operands[2] == constm1_rtx);
5932 return "dec{<imodesuffix>}\t%0";
5933 }
5934
5935 default:
5936 if (which_alternative == 1)
5937 {
5938 rtx tmp;
5939 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5940 }
5941
5942 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5943 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5944 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5945
5946 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5947 }
5948 }
5949 [(set (attr "type")
5950 (if_then_else (match_operand:SWI 2 "incdec_operand")
5951 (const_string "incdec")
5952 (const_string "alu")))
5953 (set (attr "length_immediate")
5954 (if_then_else
5955 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5956 (const_string "1")
5957 (const_string "*")))
5958 (set_attr "mode" "<MODE>")])
5959
5960 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5961 (define_insn "*addsi_3_zext"
5962 [(set (reg FLAGS_REG)
5963 (compare
5964 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5965 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5966 (set (match_operand:DI 0 "register_operand" "=r,r")
5967 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5968 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5969 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5970 {
5971 switch (get_attr_type (insn))
5972 {
5973 case TYPE_INCDEC:
5974 if (operands[2] == const1_rtx)
5975 return "inc{l}\t%k0";
5976 else
5977 {
5978 gcc_assert (operands[2] == constm1_rtx);
5979 return "dec{l}\t%k0";
5980 }
5981
5982 default:
5983 if (which_alternative == 1)
5984 {
5985 rtx tmp;
5986 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5987 }
5988
5989 if (x86_maybe_negate_const_int (&operands[2], SImode))
5990 return "sub{l}\t{%2, %k0|%k0, %2}";
5991
5992 return "add{l}\t{%2, %k0|%k0, %2}";
5993 }
5994 }
5995 [(set (attr "type")
5996 (if_then_else (match_operand:SI 2 "incdec_operand")
5997 (const_string "incdec")
5998 (const_string "alu")))
5999 (set (attr "length_immediate")
6000 (if_then_else
6001 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6002 (const_string "1")
6003 (const_string "*")))
6004 (set_attr "mode" "SI")])
6005
6006 ; For comparisons against 1, -1 and 128, we may generate better code
6007 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6008 ; is matched then. We can't accept general immediate, because for
6009 ; case of overflows, the result is messed up.
6010 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6011 ; only for comparisons not depending on it.
6012
6013 (define_insn "*adddi_4"
6014 [(set (reg FLAGS_REG)
6015 (compare
6016 (match_operand:DI 1 "nonimmediate_operand" "0")
6017 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6018 (clobber (match_scratch:DI 0 "=rm"))]
6019 "TARGET_64BIT
6020 && ix86_match_ccmode (insn, CCGCmode)"
6021 {
6022 switch (get_attr_type (insn))
6023 {
6024 case TYPE_INCDEC:
6025 if (operands[2] == constm1_rtx)
6026 return "inc{q}\t%0";
6027 else
6028 {
6029 gcc_assert (operands[2] == const1_rtx);
6030 return "dec{q}\t%0";
6031 }
6032
6033 default:
6034 if (x86_maybe_negate_const_int (&operands[2], DImode))
6035 return "add{q}\t{%2, %0|%0, %2}";
6036
6037 return "sub{q}\t{%2, %0|%0, %2}";
6038 }
6039 }
6040 [(set (attr "type")
6041 (if_then_else (match_operand:DI 2 "incdec_operand")
6042 (const_string "incdec")
6043 (const_string "alu")))
6044 (set (attr "length_immediate")
6045 (if_then_else
6046 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6047 (const_string "1")
6048 (const_string "*")))
6049 (set_attr "mode" "DI")])
6050
6051 ; For comparisons against 1, -1 and 128, we may generate better code
6052 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6053 ; is matched then. We can't accept general immediate, because for
6054 ; case of overflows, the result is messed up.
6055 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6056 ; only for comparisons not depending on it.
6057
6058 (define_insn "*add<mode>_4"
6059 [(set (reg FLAGS_REG)
6060 (compare
6061 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6062 (match_operand:SWI124 2 "const_int_operand" "n")))
6063 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6064 "ix86_match_ccmode (insn, CCGCmode)"
6065 {
6066 switch (get_attr_type (insn))
6067 {
6068 case TYPE_INCDEC:
6069 if (operands[2] == constm1_rtx)
6070 return "inc{<imodesuffix>}\t%0";
6071 else
6072 {
6073 gcc_assert (operands[2] == const1_rtx);
6074 return "dec{<imodesuffix>}\t%0";
6075 }
6076
6077 default:
6078 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6079 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6080
6081 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6082 }
6083 }
6084 [(set (attr "type")
6085 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6086 (const_string "incdec")
6087 (const_string "alu")))
6088 (set (attr "length_immediate")
6089 (if_then_else
6090 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6091 (const_string "1")
6092 (const_string "*")))
6093 (set_attr "mode" "<MODE>")])
6094
6095 (define_insn "*add<mode>_5"
6096 [(set (reg FLAGS_REG)
6097 (compare
6098 (plus:SWI
6099 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6100 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6101 (const_int 0)))
6102 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6103 "ix86_match_ccmode (insn, CCGOCmode)
6104 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6105 {
6106 switch (get_attr_type (insn))
6107 {
6108 case TYPE_INCDEC:
6109 if (operands[2] == const1_rtx)
6110 return "inc{<imodesuffix>}\t%0";
6111 else
6112 {
6113 gcc_assert (operands[2] == constm1_rtx);
6114 return "dec{<imodesuffix>}\t%0";
6115 }
6116
6117 default:
6118 if (which_alternative == 1)
6119 {
6120 rtx tmp;
6121 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6122 }
6123
6124 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6125 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6126 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6127
6128 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6129 }
6130 }
6131 [(set (attr "type")
6132 (if_then_else (match_operand:SWI 2 "incdec_operand")
6133 (const_string "incdec")
6134 (const_string "alu")))
6135 (set (attr "length_immediate")
6136 (if_then_else
6137 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6138 (const_string "1")
6139 (const_string "*")))
6140 (set_attr "mode" "<MODE>")])
6141
6142 (define_insn "addqi_ext_1"
6143 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6144 (const_int 8)
6145 (const_int 8))
6146 (plus:SI
6147 (zero_extract:SI
6148 (match_operand 1 "ext_register_operand" "0,0")
6149 (const_int 8)
6150 (const_int 8))
6151 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6152 (clobber (reg:CC FLAGS_REG))]
6153 ""
6154 {
6155 switch (get_attr_type (insn))
6156 {
6157 case TYPE_INCDEC:
6158 if (operands[2] == const1_rtx)
6159 return "inc{b}\t%h0";
6160 else
6161 {
6162 gcc_assert (operands[2] == constm1_rtx);
6163 return "dec{b}\t%h0";
6164 }
6165
6166 default:
6167 return "add{b}\t{%2, %h0|%h0, %2}";
6168 }
6169 }
6170 [(set_attr "isa" "*,nox64")
6171 (set (attr "type")
6172 (if_then_else (match_operand:QI 2 "incdec_operand")
6173 (const_string "incdec")
6174 (const_string "alu")))
6175 (set_attr "modrm" "1")
6176 (set_attr "mode" "QI")])
6177
6178 (define_insn "*addqi_ext_2"
6179 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6180 (const_int 8)
6181 (const_int 8))
6182 (plus:SI
6183 (zero_extract:SI
6184 (match_operand 1 "ext_register_operand" "%0")
6185 (const_int 8)
6186 (const_int 8))
6187 (zero_extract:SI
6188 (match_operand 2 "ext_register_operand" "Q")
6189 (const_int 8)
6190 (const_int 8))))
6191 (clobber (reg:CC FLAGS_REG))]
6192 ""
6193 "add{b}\t{%h2, %h0|%h0, %h2}"
6194 [(set_attr "type" "alu")
6195 (set_attr "mode" "QI")])
6196
6197 ;; The lea patterns for modes less than 32 bits need to be matched by
6198 ;; several insns converted to real lea by splitters.
6199
6200 (define_insn_and_split "*lea_general_1"
6201 [(set (match_operand 0 "register_operand" "=r")
6202 (plus (plus (match_operand 1 "index_register_operand" "l")
6203 (match_operand 2 "register_operand" "r"))
6204 (match_operand 3 "immediate_operand" "i")))]
6205 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6206 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6207 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6208 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6209 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6210 || GET_MODE (operands[3]) == VOIDmode)"
6211 "#"
6212 "&& reload_completed"
6213 [(const_int 0)]
6214 {
6215 enum machine_mode mode = SImode;
6216 rtx pat;
6217
6218 operands[0] = gen_lowpart (mode, operands[0]);
6219 operands[1] = gen_lowpart (mode, operands[1]);
6220 operands[2] = gen_lowpart (mode, operands[2]);
6221 operands[3] = gen_lowpart (mode, operands[3]);
6222
6223 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6224 operands[3]);
6225
6226 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6227 DONE;
6228 }
6229 [(set_attr "type" "lea")
6230 (set_attr "mode" "SI")])
6231
6232 (define_insn_and_split "*lea_general_2"
6233 [(set (match_operand 0 "register_operand" "=r")
6234 (plus (mult (match_operand 1 "index_register_operand" "l")
6235 (match_operand 2 "const248_operand" "n"))
6236 (match_operand 3 "nonmemory_operand" "ri")))]
6237 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6238 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6239 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6240 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6241 || GET_MODE (operands[3]) == VOIDmode)"
6242 "#"
6243 "&& reload_completed"
6244 [(const_int 0)]
6245 {
6246 enum machine_mode mode = SImode;
6247 rtx pat;
6248
6249 operands[0] = gen_lowpart (mode, operands[0]);
6250 operands[1] = gen_lowpart (mode, operands[1]);
6251 operands[3] = gen_lowpart (mode, operands[3]);
6252
6253 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6254 operands[3]);
6255
6256 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6257 DONE;
6258 }
6259 [(set_attr "type" "lea")
6260 (set_attr "mode" "SI")])
6261
6262 (define_insn_and_split "*lea_general_3"
6263 [(set (match_operand 0 "register_operand" "=r")
6264 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6265 (match_operand 2 "const248_operand" "n"))
6266 (match_operand 3 "register_operand" "r"))
6267 (match_operand 4 "immediate_operand" "i")))]
6268 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6269 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6270 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6271 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6272 "#"
6273 "&& reload_completed"
6274 [(const_int 0)]
6275 {
6276 enum machine_mode mode = SImode;
6277 rtx pat;
6278
6279 operands[0] = gen_lowpart (mode, operands[0]);
6280 operands[1] = gen_lowpart (mode, operands[1]);
6281 operands[3] = gen_lowpart (mode, operands[3]);
6282 operands[4] = gen_lowpart (mode, operands[4]);
6283
6284 pat = gen_rtx_PLUS (mode,
6285 gen_rtx_PLUS (mode,
6286 gen_rtx_MULT (mode, operands[1],
6287 operands[2]),
6288 operands[3]),
6289 operands[4]);
6290
6291 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6292 DONE;
6293 }
6294 [(set_attr "type" "lea")
6295 (set_attr "mode" "SI")])
6296
6297 (define_insn_and_split "*lea_general_4"
6298 [(set (match_operand 0 "register_operand" "=r")
6299 (any_or (ashift
6300 (match_operand 1 "index_register_operand" "l")
6301 (match_operand 2 "const_int_operand" "n"))
6302 (match_operand 3 "const_int_operand" "n")))]
6303 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6304 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6305 || GET_MODE (operands[0]) == SImode
6306 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6307 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6308 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6309 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6310 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6311 "#"
6312 "&& reload_completed"
6313 [(const_int 0)]
6314 {
6315 enum machine_mode mode = GET_MODE (operands[0]);
6316 rtx pat;
6317
6318 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6319 {
6320 mode = SImode;
6321 operands[0] = gen_lowpart (mode, operands[0]);
6322 operands[1] = gen_lowpart (mode, operands[1]);
6323 }
6324
6325 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6326
6327 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6328 INTVAL (operands[3]));
6329
6330 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6331 DONE;
6332 }
6333 [(set_attr "type" "lea")
6334 (set (attr "mode")
6335 (if_then_else (match_operand:DI 0)
6336 (const_string "DI")
6337 (const_string "SI")))])
6338 \f
6339 ;; Subtract instructions
6340
6341 (define_expand "sub<mode>3"
6342 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6343 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6344 (match_operand:SDWIM 2 "<general_operand>")))]
6345 ""
6346 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6347
6348 (define_insn_and_split "*sub<dwi>3_doubleword"
6349 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6350 (minus:<DWI>
6351 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6352 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6353 (clobber (reg:CC FLAGS_REG))]
6354 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6355 "#"
6356 "reload_completed"
6357 [(parallel [(set (reg:CC FLAGS_REG)
6358 (compare:CC (match_dup 1) (match_dup 2)))
6359 (set (match_dup 0)
6360 (minus:DWIH (match_dup 1) (match_dup 2)))])
6361 (parallel [(set (match_dup 3)
6362 (minus:DWIH
6363 (match_dup 4)
6364 (plus:DWIH
6365 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6366 (match_dup 5))))
6367 (clobber (reg:CC FLAGS_REG))])]
6368 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6369
6370 (define_insn "*sub<mode>_1"
6371 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6372 (minus:SWI
6373 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6374 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6375 (clobber (reg:CC FLAGS_REG))]
6376 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6377 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6378 [(set_attr "type" "alu")
6379 (set_attr "mode" "<MODE>")])
6380
6381 (define_insn "*subsi_1_zext"
6382 [(set (match_operand:DI 0 "register_operand" "=r")
6383 (zero_extend:DI
6384 (minus:SI (match_operand:SI 1 "register_operand" "0")
6385 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6386 (clobber (reg:CC FLAGS_REG))]
6387 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6388 "sub{l}\t{%2, %k0|%k0, %2}"
6389 [(set_attr "type" "alu")
6390 (set_attr "mode" "SI")])
6391
6392 (define_insn "*subqi_1_slp"
6393 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6394 (minus:QI (match_dup 0)
6395 (match_operand:QI 1 "general_operand" "qn,qm")))
6396 (clobber (reg:CC FLAGS_REG))]
6397 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6398 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6399 "sub{b}\t{%1, %0|%0, %1}"
6400 [(set_attr "type" "alu1")
6401 (set_attr "mode" "QI")])
6402
6403 (define_insn "*sub<mode>_2"
6404 [(set (reg FLAGS_REG)
6405 (compare
6406 (minus:SWI
6407 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6408 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6409 (const_int 0)))
6410 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6411 (minus:SWI (match_dup 1) (match_dup 2)))]
6412 "ix86_match_ccmode (insn, CCGOCmode)
6413 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6414 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6415 [(set_attr "type" "alu")
6416 (set_attr "mode" "<MODE>")])
6417
6418 (define_insn "*subsi_2_zext"
6419 [(set (reg FLAGS_REG)
6420 (compare
6421 (minus:SI (match_operand:SI 1 "register_operand" "0")
6422 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6423 (const_int 0)))
6424 (set (match_operand:DI 0 "register_operand" "=r")
6425 (zero_extend:DI
6426 (minus:SI (match_dup 1)
6427 (match_dup 2))))]
6428 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6429 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6430 "sub{l}\t{%2, %k0|%k0, %2}"
6431 [(set_attr "type" "alu")
6432 (set_attr "mode" "SI")])
6433
6434 (define_insn "*sub<mode>_3"
6435 [(set (reg FLAGS_REG)
6436 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6437 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6438 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6439 (minus:SWI (match_dup 1) (match_dup 2)))]
6440 "ix86_match_ccmode (insn, CCmode)
6441 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6442 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6443 [(set_attr "type" "alu")
6444 (set_attr "mode" "<MODE>")])
6445
6446 (define_insn "*subsi_3_zext"
6447 [(set (reg FLAGS_REG)
6448 (compare (match_operand:SI 1 "register_operand" "0")
6449 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6450 (set (match_operand:DI 0 "register_operand" "=r")
6451 (zero_extend:DI
6452 (minus:SI (match_dup 1)
6453 (match_dup 2))))]
6454 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6455 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6456 "sub{l}\t{%2, %1|%1, %2}"
6457 [(set_attr "type" "alu")
6458 (set_attr "mode" "SI")])
6459 \f
6460 ;; Add with carry and subtract with borrow
6461
6462 (define_expand "<plusminus_insn><mode>3_carry"
6463 [(parallel
6464 [(set (match_operand:SWI 0 "nonimmediate_operand")
6465 (plusminus:SWI
6466 (match_operand:SWI 1 "nonimmediate_operand")
6467 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6468 [(match_operand 3 "flags_reg_operand")
6469 (const_int 0)])
6470 (match_operand:SWI 2 "<general_operand>"))))
6471 (clobber (reg:CC FLAGS_REG))])]
6472 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6473
6474 (define_insn "*<plusminus_insn><mode>3_carry"
6475 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6476 (plusminus:SWI
6477 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6478 (plus:SWI
6479 (match_operator 3 "ix86_carry_flag_operator"
6480 [(reg FLAGS_REG) (const_int 0)])
6481 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6482 (clobber (reg:CC FLAGS_REG))]
6483 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6484 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6485 [(set_attr "type" "alu")
6486 (set_attr "use_carry" "1")
6487 (set_attr "pent_pair" "pu")
6488 (set_attr "mode" "<MODE>")])
6489
6490 (define_insn "*addsi3_carry_zext"
6491 [(set (match_operand:DI 0 "register_operand" "=r")
6492 (zero_extend:DI
6493 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6494 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6495 [(reg FLAGS_REG) (const_int 0)])
6496 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6497 (clobber (reg:CC FLAGS_REG))]
6498 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6499 "adc{l}\t{%2, %k0|%k0, %2}"
6500 [(set_attr "type" "alu")
6501 (set_attr "use_carry" "1")
6502 (set_attr "pent_pair" "pu")
6503 (set_attr "mode" "SI")])
6504
6505 (define_insn "*subsi3_carry_zext"
6506 [(set (match_operand:DI 0 "register_operand" "=r")
6507 (zero_extend:DI
6508 (minus:SI (match_operand:SI 1 "register_operand" "0")
6509 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6510 [(reg FLAGS_REG) (const_int 0)])
6511 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6512 (clobber (reg:CC FLAGS_REG))]
6513 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6514 "sbb{l}\t{%2, %k0|%k0, %2}"
6515 [(set_attr "type" "alu")
6516 (set_attr "pent_pair" "pu")
6517 (set_attr "mode" "SI")])
6518 \f
6519 ;; ADCX instruction
6520
6521 (define_insn "adcx<mode>3"
6522 [(set (reg:CCC FLAGS_REG)
6523 (compare:CCC
6524 (plus:SWI48
6525 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6526 (plus:SWI48
6527 (match_operator 4 "ix86_carry_flag_operator"
6528 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6529 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6530 (const_int 0)))
6531 (set (match_operand:SWI48 0 "register_operand" "=r")
6532 (plus:SWI48 (match_dup 1)
6533 (plus:SWI48 (match_op_dup 4
6534 [(match_dup 3) (const_int 0)])
6535 (match_dup 2))))]
6536 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6537 "adcx\t{%2, %0|%0, %2}"
6538 [(set_attr "type" "alu")
6539 (set_attr "use_carry" "1")
6540 (set_attr "mode" "<MODE>")])
6541 \f
6542 ;; Overflow setting add instructions
6543
6544 (define_insn "*add<mode>3_cconly_overflow"
6545 [(set (reg:CCC FLAGS_REG)
6546 (compare:CCC
6547 (plus:SWI
6548 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6549 (match_operand:SWI 2 "<general_operand>" "<g>"))
6550 (match_dup 1)))
6551 (clobber (match_scratch:SWI 0 "=<r>"))]
6552 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6553 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6554 [(set_attr "type" "alu")
6555 (set_attr "mode" "<MODE>")])
6556
6557 (define_insn "*add<mode>3_cc_overflow"
6558 [(set (reg:CCC FLAGS_REG)
6559 (compare:CCC
6560 (plus:SWI
6561 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6562 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6563 (match_dup 1)))
6564 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6565 (plus:SWI (match_dup 1) (match_dup 2)))]
6566 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6567 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6568 [(set_attr "type" "alu")
6569 (set_attr "mode" "<MODE>")])
6570
6571 (define_insn "*addsi3_zext_cc_overflow"
6572 [(set (reg:CCC FLAGS_REG)
6573 (compare:CCC
6574 (plus:SI
6575 (match_operand:SI 1 "nonimmediate_operand" "%0")
6576 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6577 (match_dup 1)))
6578 (set (match_operand:DI 0 "register_operand" "=r")
6579 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6580 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6581 "add{l}\t{%2, %k0|%k0, %2}"
6582 [(set_attr "type" "alu")
6583 (set_attr "mode" "SI")])
6584
6585 ;; The patterns that match these are at the end of this file.
6586
6587 (define_expand "<plusminus_insn>xf3"
6588 [(set (match_operand:XF 0 "register_operand")
6589 (plusminus:XF
6590 (match_operand:XF 1 "register_operand")
6591 (match_operand:XF 2 "register_operand")))]
6592 "TARGET_80387")
6593
6594 (define_expand "<plusminus_insn><mode>3"
6595 [(set (match_operand:MODEF 0 "register_operand")
6596 (plusminus:MODEF
6597 (match_operand:MODEF 1 "register_operand")
6598 (match_operand:MODEF 2 "nonimmediate_operand")))]
6599 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6600 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6601 \f
6602 ;; Multiply instructions
6603
6604 (define_expand "mul<mode>3"
6605 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6606 (mult:SWIM248
6607 (match_operand:SWIM248 1 "register_operand")
6608 (match_operand:SWIM248 2 "<general_operand>")))
6609 (clobber (reg:CC FLAGS_REG))])])
6610
6611 (define_expand "mulqi3"
6612 [(parallel [(set (match_operand:QI 0 "register_operand")
6613 (mult:QI
6614 (match_operand:QI 1 "register_operand")
6615 (match_operand:QI 2 "nonimmediate_operand")))
6616 (clobber (reg:CC FLAGS_REG))])]
6617 "TARGET_QIMODE_MATH")
6618
6619 ;; On AMDFAM10
6620 ;; IMUL reg32/64, reg32/64, imm8 Direct
6621 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6622 ;; IMUL reg32/64, reg32/64, imm32 Direct
6623 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6624 ;; IMUL reg32/64, reg32/64 Direct
6625 ;; IMUL reg32/64, mem32/64 Direct
6626 ;;
6627 ;; On BDVER1, all above IMULs use DirectPath
6628
6629 (define_insn "*mul<mode>3_1"
6630 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6631 (mult:SWI48
6632 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6633 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6634 (clobber (reg:CC FLAGS_REG))]
6635 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6636 "@
6637 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6638 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6639 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6640 [(set_attr "type" "imul")
6641 (set_attr "prefix_0f" "0,0,1")
6642 (set (attr "athlon_decode")
6643 (cond [(eq_attr "cpu" "athlon")
6644 (const_string "vector")
6645 (eq_attr "alternative" "1")
6646 (const_string "vector")
6647 (and (eq_attr "alternative" "2")
6648 (match_operand 1 "memory_operand"))
6649 (const_string "vector")]
6650 (const_string "direct")))
6651 (set (attr "amdfam10_decode")
6652 (cond [(and (eq_attr "alternative" "0,1")
6653 (match_operand 1 "memory_operand"))
6654 (const_string "vector")]
6655 (const_string "direct")))
6656 (set_attr "bdver1_decode" "direct")
6657 (set_attr "mode" "<MODE>")])
6658
6659 (define_insn "*mulsi3_1_zext"
6660 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6661 (zero_extend:DI
6662 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6663 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6664 (clobber (reg:CC FLAGS_REG))]
6665 "TARGET_64BIT
6666 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6667 "@
6668 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6669 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6670 imul{l}\t{%2, %k0|%k0, %2}"
6671 [(set_attr "type" "imul")
6672 (set_attr "prefix_0f" "0,0,1")
6673 (set (attr "athlon_decode")
6674 (cond [(eq_attr "cpu" "athlon")
6675 (const_string "vector")
6676 (eq_attr "alternative" "1")
6677 (const_string "vector")
6678 (and (eq_attr "alternative" "2")
6679 (match_operand 1 "memory_operand"))
6680 (const_string "vector")]
6681 (const_string "direct")))
6682 (set (attr "amdfam10_decode")
6683 (cond [(and (eq_attr "alternative" "0,1")
6684 (match_operand 1 "memory_operand"))
6685 (const_string "vector")]
6686 (const_string "direct")))
6687 (set_attr "bdver1_decode" "direct")
6688 (set_attr "mode" "SI")])
6689
6690 ;; On AMDFAM10
6691 ;; IMUL reg16, reg16, imm8 VectorPath
6692 ;; IMUL reg16, mem16, imm8 VectorPath
6693 ;; IMUL reg16, reg16, imm16 VectorPath
6694 ;; IMUL reg16, mem16, imm16 VectorPath
6695 ;; IMUL reg16, reg16 Direct
6696 ;; IMUL reg16, mem16 Direct
6697 ;;
6698 ;; On BDVER1, all HI MULs use DoublePath
6699
6700 (define_insn "*mulhi3_1"
6701 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6702 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6703 (match_operand:HI 2 "general_operand" "K,n,mr")))
6704 (clobber (reg:CC FLAGS_REG))]
6705 "TARGET_HIMODE_MATH
6706 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6707 "@
6708 imul{w}\t{%2, %1, %0|%0, %1, %2}
6709 imul{w}\t{%2, %1, %0|%0, %1, %2}
6710 imul{w}\t{%2, %0|%0, %2}"
6711 [(set_attr "type" "imul")
6712 (set_attr "prefix_0f" "0,0,1")
6713 (set (attr "athlon_decode")
6714 (cond [(eq_attr "cpu" "athlon")
6715 (const_string "vector")
6716 (eq_attr "alternative" "1,2")
6717 (const_string "vector")]
6718 (const_string "direct")))
6719 (set (attr "amdfam10_decode")
6720 (cond [(eq_attr "alternative" "0,1")
6721 (const_string "vector")]
6722 (const_string "direct")))
6723 (set_attr "bdver1_decode" "double")
6724 (set_attr "mode" "HI")])
6725
6726 ;;On AMDFAM10 and BDVER1
6727 ;; MUL reg8 Direct
6728 ;; MUL mem8 Direct
6729
6730 (define_insn "*mulqi3_1"
6731 [(set (match_operand:QI 0 "register_operand" "=a")
6732 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6733 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6734 (clobber (reg:CC FLAGS_REG))]
6735 "TARGET_QIMODE_MATH
6736 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6737 "mul{b}\t%2"
6738 [(set_attr "type" "imul")
6739 (set_attr "length_immediate" "0")
6740 (set (attr "athlon_decode")
6741 (if_then_else (eq_attr "cpu" "athlon")
6742 (const_string "vector")
6743 (const_string "direct")))
6744 (set_attr "amdfam10_decode" "direct")
6745 (set_attr "bdver1_decode" "direct")
6746 (set_attr "mode" "QI")])
6747
6748 (define_expand "<u>mul<mode><dwi>3"
6749 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6750 (mult:<DWI>
6751 (any_extend:<DWI>
6752 (match_operand:DWIH 1 "nonimmediate_operand"))
6753 (any_extend:<DWI>
6754 (match_operand:DWIH 2 "register_operand"))))
6755 (clobber (reg:CC FLAGS_REG))])])
6756
6757 (define_expand "<u>mulqihi3"
6758 [(parallel [(set (match_operand:HI 0 "register_operand")
6759 (mult:HI
6760 (any_extend:HI
6761 (match_operand:QI 1 "nonimmediate_operand"))
6762 (any_extend:HI
6763 (match_operand:QI 2 "register_operand"))))
6764 (clobber (reg:CC FLAGS_REG))])]
6765 "TARGET_QIMODE_MATH")
6766
6767 (define_insn "*bmi2_umulditi3_1"
6768 [(set (match_operand:DI 0 "register_operand" "=r")
6769 (mult:DI
6770 (match_operand:DI 2 "nonimmediate_operand" "%d")
6771 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6772 (set (match_operand:DI 1 "register_operand" "=r")
6773 (truncate:DI
6774 (lshiftrt:TI
6775 (mult:TI (zero_extend:TI (match_dup 2))
6776 (zero_extend:TI (match_dup 3)))
6777 (const_int 64))))]
6778 "TARGET_64BIT && TARGET_BMI2
6779 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6780 "mulx\t{%3, %0, %1|%1, %0, %3}"
6781 [(set_attr "type" "imulx")
6782 (set_attr "prefix" "vex")
6783 (set_attr "mode" "DI")])
6784
6785 (define_insn "*bmi2_umulsidi3_1"
6786 [(set (match_operand:SI 0 "register_operand" "=r")
6787 (mult:SI
6788 (match_operand:SI 2 "nonimmediate_operand" "%d")
6789 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6790 (set (match_operand:SI 1 "register_operand" "=r")
6791 (truncate:SI
6792 (lshiftrt:DI
6793 (mult:DI (zero_extend:DI (match_dup 2))
6794 (zero_extend:DI (match_dup 3)))
6795 (const_int 32))))]
6796 "!TARGET_64BIT && TARGET_BMI2
6797 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6798 "mulx\t{%3, %0, %1|%1, %0, %3}"
6799 [(set_attr "type" "imulx")
6800 (set_attr "prefix" "vex")
6801 (set_attr "mode" "SI")])
6802
6803 (define_insn "*umul<mode><dwi>3_1"
6804 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6805 (mult:<DWI>
6806 (zero_extend:<DWI>
6807 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6808 (zero_extend:<DWI>
6809 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6810 (clobber (reg:CC FLAGS_REG))]
6811 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6812 "@
6813 #
6814 mul{<imodesuffix>}\t%2"
6815 [(set_attr "isa" "bmi2,*")
6816 (set_attr "type" "imulx,imul")
6817 (set_attr "length_immediate" "*,0")
6818 (set (attr "athlon_decode")
6819 (cond [(eq_attr "alternative" "1")
6820 (if_then_else (eq_attr "cpu" "athlon")
6821 (const_string "vector")
6822 (const_string "double"))]
6823 (const_string "*")))
6824 (set_attr "amdfam10_decode" "*,double")
6825 (set_attr "bdver1_decode" "*,direct")
6826 (set_attr "prefix" "vex,orig")
6827 (set_attr "mode" "<MODE>")])
6828
6829 ;; Convert mul to the mulx pattern to avoid flags dependency.
6830 (define_split
6831 [(set (match_operand:<DWI> 0 "register_operand")
6832 (mult:<DWI>
6833 (zero_extend:<DWI>
6834 (match_operand:DWIH 1 "register_operand"))
6835 (zero_extend:<DWI>
6836 (match_operand:DWIH 2 "nonimmediate_operand"))))
6837 (clobber (reg:CC FLAGS_REG))]
6838 "TARGET_BMI2 && reload_completed
6839 && true_regnum (operands[1]) == DX_REG"
6840 [(parallel [(set (match_dup 3)
6841 (mult:DWIH (match_dup 1) (match_dup 2)))
6842 (set (match_dup 4)
6843 (truncate:DWIH
6844 (lshiftrt:<DWI>
6845 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6846 (zero_extend:<DWI> (match_dup 2)))
6847 (match_dup 5))))])]
6848 {
6849 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6850
6851 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6852 })
6853
6854 (define_insn "*mul<mode><dwi>3_1"
6855 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6856 (mult:<DWI>
6857 (sign_extend:<DWI>
6858 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6859 (sign_extend:<DWI>
6860 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6861 (clobber (reg:CC FLAGS_REG))]
6862 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6863 "imul{<imodesuffix>}\t%2"
6864 [(set_attr "type" "imul")
6865 (set_attr "length_immediate" "0")
6866 (set (attr "athlon_decode")
6867 (if_then_else (eq_attr "cpu" "athlon")
6868 (const_string "vector")
6869 (const_string "double")))
6870 (set_attr "amdfam10_decode" "double")
6871 (set_attr "bdver1_decode" "direct")
6872 (set_attr "mode" "<MODE>")])
6873
6874 (define_insn "*<u>mulqihi3_1"
6875 [(set (match_operand:HI 0 "register_operand" "=a")
6876 (mult:HI
6877 (any_extend:HI
6878 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6879 (any_extend:HI
6880 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6881 (clobber (reg:CC FLAGS_REG))]
6882 "TARGET_QIMODE_MATH
6883 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6884 "<sgnprefix>mul{b}\t%2"
6885 [(set_attr "type" "imul")
6886 (set_attr "length_immediate" "0")
6887 (set (attr "athlon_decode")
6888 (if_then_else (eq_attr "cpu" "athlon")
6889 (const_string "vector")
6890 (const_string "direct")))
6891 (set_attr "amdfam10_decode" "direct")
6892 (set_attr "bdver1_decode" "direct")
6893 (set_attr "mode" "QI")])
6894
6895 (define_expand "<s>mul<mode>3_highpart"
6896 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6897 (truncate:SWI48
6898 (lshiftrt:<DWI>
6899 (mult:<DWI>
6900 (any_extend:<DWI>
6901 (match_operand:SWI48 1 "nonimmediate_operand"))
6902 (any_extend:<DWI>
6903 (match_operand:SWI48 2 "register_operand")))
6904 (match_dup 4))))
6905 (clobber (match_scratch:SWI48 3))
6906 (clobber (reg:CC FLAGS_REG))])]
6907 ""
6908 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6909
6910 (define_insn "*<s>muldi3_highpart_1"
6911 [(set (match_operand:DI 0 "register_operand" "=d")
6912 (truncate:DI
6913 (lshiftrt:TI
6914 (mult:TI
6915 (any_extend:TI
6916 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6917 (any_extend:TI
6918 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6919 (const_int 64))))
6920 (clobber (match_scratch:DI 3 "=1"))
6921 (clobber (reg:CC FLAGS_REG))]
6922 "TARGET_64BIT
6923 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6924 "<sgnprefix>mul{q}\t%2"
6925 [(set_attr "type" "imul")
6926 (set_attr "length_immediate" "0")
6927 (set (attr "athlon_decode")
6928 (if_then_else (eq_attr "cpu" "athlon")
6929 (const_string "vector")
6930 (const_string "double")))
6931 (set_attr "amdfam10_decode" "double")
6932 (set_attr "bdver1_decode" "direct")
6933 (set_attr "mode" "DI")])
6934
6935 (define_insn "*<s>mulsi3_highpart_1"
6936 [(set (match_operand:SI 0 "register_operand" "=d")
6937 (truncate:SI
6938 (lshiftrt:DI
6939 (mult:DI
6940 (any_extend:DI
6941 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6942 (any_extend:DI
6943 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6944 (const_int 32))))
6945 (clobber (match_scratch:SI 3 "=1"))
6946 (clobber (reg:CC FLAGS_REG))]
6947 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6948 "<sgnprefix>mul{l}\t%2"
6949 [(set_attr "type" "imul")
6950 (set_attr "length_immediate" "0")
6951 (set (attr "athlon_decode")
6952 (if_then_else (eq_attr "cpu" "athlon")
6953 (const_string "vector")
6954 (const_string "double")))
6955 (set_attr "amdfam10_decode" "double")
6956 (set_attr "bdver1_decode" "direct")
6957 (set_attr "mode" "SI")])
6958
6959 (define_insn "*<s>mulsi3_highpart_zext"
6960 [(set (match_operand:DI 0 "register_operand" "=d")
6961 (zero_extend:DI (truncate:SI
6962 (lshiftrt:DI
6963 (mult:DI (any_extend:DI
6964 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6965 (any_extend:DI
6966 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6967 (const_int 32)))))
6968 (clobber (match_scratch:SI 3 "=1"))
6969 (clobber (reg:CC FLAGS_REG))]
6970 "TARGET_64BIT
6971 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6972 "<sgnprefix>mul{l}\t%2"
6973 [(set_attr "type" "imul")
6974 (set_attr "length_immediate" "0")
6975 (set (attr "athlon_decode")
6976 (if_then_else (eq_attr "cpu" "athlon")
6977 (const_string "vector")
6978 (const_string "double")))
6979 (set_attr "amdfam10_decode" "double")
6980 (set_attr "bdver1_decode" "direct")
6981 (set_attr "mode" "SI")])
6982
6983 ;; The patterns that match these are at the end of this file.
6984
6985 (define_expand "mulxf3"
6986 [(set (match_operand:XF 0 "register_operand")
6987 (mult:XF (match_operand:XF 1 "register_operand")
6988 (match_operand:XF 2 "register_operand")))]
6989 "TARGET_80387")
6990
6991 (define_expand "mul<mode>3"
6992 [(set (match_operand:MODEF 0 "register_operand")
6993 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6994 (match_operand:MODEF 2 "nonimmediate_operand")))]
6995 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6996 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6997 \f
6998 ;; Divide instructions
6999
7000 ;; The patterns that match these are at the end of this file.
7001
7002 (define_expand "divxf3"
7003 [(set (match_operand:XF 0 "register_operand")
7004 (div:XF (match_operand:XF 1 "register_operand")
7005 (match_operand:XF 2 "register_operand")))]
7006 "TARGET_80387")
7007
7008 (define_expand "divdf3"
7009 [(set (match_operand:DF 0 "register_operand")
7010 (div:DF (match_operand:DF 1 "register_operand")
7011 (match_operand:DF 2 "nonimmediate_operand")))]
7012 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7013 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7014
7015 (define_expand "divsf3"
7016 [(set (match_operand:SF 0 "register_operand")
7017 (div:SF (match_operand:SF 1 "register_operand")
7018 (match_operand:SF 2 "nonimmediate_operand")))]
7019 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7020 || TARGET_SSE_MATH"
7021 {
7022 if (TARGET_SSE_MATH
7023 && TARGET_RECIP_DIV
7024 && optimize_insn_for_speed_p ()
7025 && flag_finite_math_only && !flag_trapping_math
7026 && flag_unsafe_math_optimizations)
7027 {
7028 ix86_emit_swdivsf (operands[0], operands[1],
7029 operands[2], SFmode);
7030 DONE;
7031 }
7032 })
7033 \f
7034 ;; Divmod instructions.
7035
7036 (define_expand "divmod<mode>4"
7037 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7038 (div:SWIM248
7039 (match_operand:SWIM248 1 "register_operand")
7040 (match_operand:SWIM248 2 "nonimmediate_operand")))
7041 (set (match_operand:SWIM248 3 "register_operand")
7042 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7043 (clobber (reg:CC FLAGS_REG))])])
7044
7045 ;; Split with 8bit unsigned divide:
7046 ;; if (dividend an divisor are in [0-255])
7047 ;; use 8bit unsigned integer divide
7048 ;; else
7049 ;; use original integer divide
7050 (define_split
7051 [(set (match_operand:SWI48 0 "register_operand")
7052 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7053 (match_operand:SWI48 3 "nonimmediate_operand")))
7054 (set (match_operand:SWI48 1 "register_operand")
7055 (mod:SWI48 (match_dup 2) (match_dup 3)))
7056 (clobber (reg:CC FLAGS_REG))]
7057 "TARGET_USE_8BIT_IDIV
7058 && TARGET_QIMODE_MATH
7059 && can_create_pseudo_p ()
7060 && !optimize_insn_for_size_p ()"
7061 [(const_int 0)]
7062 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7063
7064 (define_insn_and_split "divmod<mode>4_1"
7065 [(set (match_operand:SWI48 0 "register_operand" "=a")
7066 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7067 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7068 (set (match_operand:SWI48 1 "register_operand" "=&d")
7069 (mod:SWI48 (match_dup 2) (match_dup 3)))
7070 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7071 (clobber (reg:CC FLAGS_REG))]
7072 ""
7073 "#"
7074 "reload_completed"
7075 [(parallel [(set (match_dup 1)
7076 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7077 (clobber (reg:CC FLAGS_REG))])
7078 (parallel [(set (match_dup 0)
7079 (div:SWI48 (match_dup 2) (match_dup 3)))
7080 (set (match_dup 1)
7081 (mod:SWI48 (match_dup 2) (match_dup 3)))
7082 (use (match_dup 1))
7083 (clobber (reg:CC FLAGS_REG))])]
7084 {
7085 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7086
7087 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7088 operands[4] = operands[2];
7089 else
7090 {
7091 /* Avoid use of cltd in favor of a mov+shift. */
7092 emit_move_insn (operands[1], operands[2]);
7093 operands[4] = operands[1];
7094 }
7095 }
7096 [(set_attr "type" "multi")
7097 (set_attr "mode" "<MODE>")])
7098
7099 (define_insn_and_split "*divmod<mode>4"
7100 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7101 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7102 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7103 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7104 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7105 (clobber (reg:CC FLAGS_REG))]
7106 ""
7107 "#"
7108 "reload_completed"
7109 [(parallel [(set (match_dup 1)
7110 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7111 (clobber (reg:CC FLAGS_REG))])
7112 (parallel [(set (match_dup 0)
7113 (div:SWIM248 (match_dup 2) (match_dup 3)))
7114 (set (match_dup 1)
7115 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7116 (use (match_dup 1))
7117 (clobber (reg:CC FLAGS_REG))])]
7118 {
7119 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7120
7121 if (<MODE>mode != HImode
7122 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7123 operands[4] = operands[2];
7124 else
7125 {
7126 /* Avoid use of cltd in favor of a mov+shift. */
7127 emit_move_insn (operands[1], operands[2]);
7128 operands[4] = operands[1];
7129 }
7130 }
7131 [(set_attr "type" "multi")
7132 (set_attr "mode" "<MODE>")])
7133
7134 (define_insn "*divmod<mode>4_noext"
7135 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7136 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7137 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7138 (set (match_operand:SWIM248 1 "register_operand" "=d")
7139 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7140 (use (match_operand:SWIM248 4 "register_operand" "1"))
7141 (clobber (reg:CC FLAGS_REG))]
7142 ""
7143 "idiv{<imodesuffix>}\t%3"
7144 [(set_attr "type" "idiv")
7145 (set_attr "mode" "<MODE>")])
7146
7147 (define_expand "divmodqi4"
7148 [(parallel [(set (match_operand:QI 0 "register_operand")
7149 (div:QI
7150 (match_operand:QI 1 "register_operand")
7151 (match_operand:QI 2 "nonimmediate_operand")))
7152 (set (match_operand:QI 3 "register_operand")
7153 (mod:QI (match_dup 1) (match_dup 2)))
7154 (clobber (reg:CC FLAGS_REG))])]
7155 "TARGET_QIMODE_MATH"
7156 {
7157 rtx div, mod, insn;
7158 rtx tmp0, tmp1;
7159
7160 tmp0 = gen_reg_rtx (HImode);
7161 tmp1 = gen_reg_rtx (HImode);
7162
7163 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7164 in AX. */
7165 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7166 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7167
7168 /* Extract remainder from AH. */
7169 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7170 insn = emit_move_insn (operands[3], tmp1);
7171
7172 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7173 set_unique_reg_note (insn, REG_EQUAL, mod);
7174
7175 /* Extract quotient from AL. */
7176 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7177
7178 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7179 set_unique_reg_note (insn, REG_EQUAL, div);
7180
7181 DONE;
7182 })
7183
7184 ;; Divide AX by r/m8, with result stored in
7185 ;; AL <- Quotient
7186 ;; AH <- Remainder
7187 ;; Change div/mod to HImode and extend the second argument to HImode
7188 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7189 ;; combine may fail.
7190 (define_insn "divmodhiqi3"
7191 [(set (match_operand:HI 0 "register_operand" "=a")
7192 (ior:HI
7193 (ashift:HI
7194 (zero_extend:HI
7195 (truncate:QI
7196 (mod:HI (match_operand:HI 1 "register_operand" "0")
7197 (sign_extend:HI
7198 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7199 (const_int 8))
7200 (zero_extend:HI
7201 (truncate:QI
7202 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7203 (clobber (reg:CC FLAGS_REG))]
7204 "TARGET_QIMODE_MATH"
7205 "idiv{b}\t%2"
7206 [(set_attr "type" "idiv")
7207 (set_attr "mode" "QI")])
7208
7209 (define_expand "udivmod<mode>4"
7210 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7211 (udiv:SWIM248
7212 (match_operand:SWIM248 1 "register_operand")
7213 (match_operand:SWIM248 2 "nonimmediate_operand")))
7214 (set (match_operand:SWIM248 3 "register_operand")
7215 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7216 (clobber (reg:CC FLAGS_REG))])])
7217
7218 ;; Split with 8bit unsigned divide:
7219 ;; if (dividend an divisor are in [0-255])
7220 ;; use 8bit unsigned integer divide
7221 ;; else
7222 ;; use original integer divide
7223 (define_split
7224 [(set (match_operand:SWI48 0 "register_operand")
7225 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7226 (match_operand:SWI48 3 "nonimmediate_operand")))
7227 (set (match_operand:SWI48 1 "register_operand")
7228 (umod:SWI48 (match_dup 2) (match_dup 3)))
7229 (clobber (reg:CC FLAGS_REG))]
7230 "TARGET_USE_8BIT_IDIV
7231 && TARGET_QIMODE_MATH
7232 && can_create_pseudo_p ()
7233 && !optimize_insn_for_size_p ()"
7234 [(const_int 0)]
7235 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7236
7237 (define_insn_and_split "udivmod<mode>4_1"
7238 [(set (match_operand:SWI48 0 "register_operand" "=a")
7239 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7240 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7241 (set (match_operand:SWI48 1 "register_operand" "=&d")
7242 (umod:SWI48 (match_dup 2) (match_dup 3)))
7243 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7244 (clobber (reg:CC FLAGS_REG))]
7245 ""
7246 "#"
7247 "reload_completed"
7248 [(set (match_dup 1) (const_int 0))
7249 (parallel [(set (match_dup 0)
7250 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7251 (set (match_dup 1)
7252 (umod:SWI48 (match_dup 2) (match_dup 3)))
7253 (use (match_dup 1))
7254 (clobber (reg:CC FLAGS_REG))])]
7255 ""
7256 [(set_attr "type" "multi")
7257 (set_attr "mode" "<MODE>")])
7258
7259 (define_insn_and_split "*udivmod<mode>4"
7260 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7261 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7262 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7263 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7264 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7265 (clobber (reg:CC FLAGS_REG))]
7266 ""
7267 "#"
7268 "reload_completed"
7269 [(set (match_dup 1) (const_int 0))
7270 (parallel [(set (match_dup 0)
7271 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7272 (set (match_dup 1)
7273 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7274 (use (match_dup 1))
7275 (clobber (reg:CC FLAGS_REG))])]
7276 ""
7277 [(set_attr "type" "multi")
7278 (set_attr "mode" "<MODE>")])
7279
7280 (define_insn "*udivmod<mode>4_noext"
7281 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7282 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7283 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7284 (set (match_operand:SWIM248 1 "register_operand" "=d")
7285 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7286 (use (match_operand:SWIM248 4 "register_operand" "1"))
7287 (clobber (reg:CC FLAGS_REG))]
7288 ""
7289 "div{<imodesuffix>}\t%3"
7290 [(set_attr "type" "idiv")
7291 (set_attr "mode" "<MODE>")])
7292
7293 (define_expand "udivmodqi4"
7294 [(parallel [(set (match_operand:QI 0 "register_operand")
7295 (udiv:QI
7296 (match_operand:QI 1 "register_operand")
7297 (match_operand:QI 2 "nonimmediate_operand")))
7298 (set (match_operand:QI 3 "register_operand")
7299 (umod:QI (match_dup 1) (match_dup 2)))
7300 (clobber (reg:CC FLAGS_REG))])]
7301 "TARGET_QIMODE_MATH"
7302 {
7303 rtx div, mod, insn;
7304 rtx tmp0, tmp1;
7305
7306 tmp0 = gen_reg_rtx (HImode);
7307 tmp1 = gen_reg_rtx (HImode);
7308
7309 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7310 in AX. */
7311 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7312 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7313
7314 /* Extract remainder from AH. */
7315 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7316 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7317 insn = emit_move_insn (operands[3], tmp1);
7318
7319 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7320 set_unique_reg_note (insn, REG_EQUAL, mod);
7321
7322 /* Extract quotient from AL. */
7323 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7324
7325 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7326 set_unique_reg_note (insn, REG_EQUAL, div);
7327
7328 DONE;
7329 })
7330
7331 (define_insn "udivmodhiqi3"
7332 [(set (match_operand:HI 0 "register_operand" "=a")
7333 (ior:HI
7334 (ashift:HI
7335 (zero_extend:HI
7336 (truncate:QI
7337 (mod:HI (match_operand:HI 1 "register_operand" "0")
7338 (zero_extend:HI
7339 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7340 (const_int 8))
7341 (zero_extend:HI
7342 (truncate:QI
7343 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7344 (clobber (reg:CC FLAGS_REG))]
7345 "TARGET_QIMODE_MATH"
7346 "div{b}\t%2"
7347 [(set_attr "type" "idiv")
7348 (set_attr "mode" "QI")])
7349
7350 ;; We cannot use div/idiv for double division, because it causes
7351 ;; "division by zero" on the overflow and that's not what we expect
7352 ;; from truncate. Because true (non truncating) double division is
7353 ;; never generated, we can't create this insn anyway.
7354 ;
7355 ;(define_insn ""
7356 ; [(set (match_operand:SI 0 "register_operand" "=a")
7357 ; (truncate:SI
7358 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7359 ; (zero_extend:DI
7360 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7361 ; (set (match_operand:SI 3 "register_operand" "=d")
7362 ; (truncate:SI
7363 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7364 ; (clobber (reg:CC FLAGS_REG))]
7365 ; ""
7366 ; "div{l}\t{%2, %0|%0, %2}"
7367 ; [(set_attr "type" "idiv")])
7368 \f
7369 ;;- Logical AND instructions
7370
7371 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7372 ;; Note that this excludes ah.
7373
7374 (define_expand "testsi_ccno_1"
7375 [(set (reg:CCNO FLAGS_REG)
7376 (compare:CCNO
7377 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7378 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7379 (const_int 0)))])
7380
7381 (define_expand "testqi_ccz_1"
7382 [(set (reg:CCZ FLAGS_REG)
7383 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7384 (match_operand:QI 1 "nonmemory_operand"))
7385 (const_int 0)))])
7386
7387 (define_expand "testdi_ccno_1"
7388 [(set (reg:CCNO FLAGS_REG)
7389 (compare:CCNO
7390 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7391 (match_operand:DI 1 "x86_64_szext_general_operand"))
7392 (const_int 0)))]
7393 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7394
7395 (define_insn "*testdi_1"
7396 [(set (reg FLAGS_REG)
7397 (compare
7398 (and:DI
7399 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7400 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7401 (const_int 0)))]
7402 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7403 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7404 "@
7405 test{l}\t{%k1, %k0|%k0, %k1}
7406 test{l}\t{%k1, %k0|%k0, %k1}
7407 test{q}\t{%1, %0|%0, %1}
7408 test{q}\t{%1, %0|%0, %1}
7409 test{q}\t{%1, %0|%0, %1}"
7410 [(set_attr "type" "test")
7411 (set_attr "modrm" "0,1,0,1,1")
7412 (set_attr "mode" "SI,SI,DI,DI,DI")])
7413
7414 (define_insn "*testqi_1_maybe_si"
7415 [(set (reg FLAGS_REG)
7416 (compare
7417 (and:QI
7418 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7419 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7420 (const_int 0)))]
7421 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7422 && ix86_match_ccmode (insn,
7423 CONST_INT_P (operands[1])
7424 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7425 {
7426 if (which_alternative == 3)
7427 {
7428 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7429 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7430 return "test{l}\t{%1, %k0|%k0, %1}";
7431 }
7432 return "test{b}\t{%1, %0|%0, %1}";
7433 }
7434 [(set_attr "type" "test")
7435 (set_attr "modrm" "0,1,1,1")
7436 (set_attr "mode" "QI,QI,QI,SI")
7437 (set_attr "pent_pair" "uv,np,uv,np")])
7438
7439 (define_insn "*test<mode>_1"
7440 [(set (reg FLAGS_REG)
7441 (compare
7442 (and:SWI124
7443 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7444 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7445 (const_int 0)))]
7446 "ix86_match_ccmode (insn, CCNOmode)
7447 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7448 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7449 [(set_attr "type" "test")
7450 (set_attr "modrm" "0,1,1")
7451 (set_attr "mode" "<MODE>")
7452 (set_attr "pent_pair" "uv,np,uv")])
7453
7454 (define_expand "testqi_ext_ccno_0"
7455 [(set (reg:CCNO FLAGS_REG)
7456 (compare:CCNO
7457 (and:SI
7458 (zero_extract:SI
7459 (match_operand 0 "ext_register_operand")
7460 (const_int 8)
7461 (const_int 8))
7462 (match_operand 1 "const_int_operand"))
7463 (const_int 0)))])
7464
7465 (define_insn "*testqi_ext_0"
7466 [(set (reg FLAGS_REG)
7467 (compare
7468 (and:SI
7469 (zero_extract:SI
7470 (match_operand 0 "ext_register_operand" "Q")
7471 (const_int 8)
7472 (const_int 8))
7473 (match_operand 1 "const_int_operand" "n"))
7474 (const_int 0)))]
7475 "ix86_match_ccmode (insn, CCNOmode)"
7476 "test{b}\t{%1, %h0|%h0, %1}"
7477 [(set_attr "type" "test")
7478 (set_attr "mode" "QI")
7479 (set_attr "length_immediate" "1")
7480 (set_attr "modrm" "1")
7481 (set_attr "pent_pair" "np")])
7482
7483 (define_insn "*testqi_ext_1"
7484 [(set (reg FLAGS_REG)
7485 (compare
7486 (and:SI
7487 (zero_extract:SI
7488 (match_operand 0 "ext_register_operand" "Q,Q")
7489 (const_int 8)
7490 (const_int 8))
7491 (zero_extend:SI
7492 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7493 (const_int 0)))]
7494 "ix86_match_ccmode (insn, CCNOmode)"
7495 "test{b}\t{%1, %h0|%h0, %1}"
7496 [(set_attr "isa" "*,nox64")
7497 (set_attr "type" "test")
7498 (set_attr "mode" "QI")])
7499
7500 (define_insn "*testqi_ext_2"
7501 [(set (reg FLAGS_REG)
7502 (compare
7503 (and:SI
7504 (zero_extract:SI
7505 (match_operand 0 "ext_register_operand" "Q")
7506 (const_int 8)
7507 (const_int 8))
7508 (zero_extract:SI
7509 (match_operand 1 "ext_register_operand" "Q")
7510 (const_int 8)
7511 (const_int 8)))
7512 (const_int 0)))]
7513 "ix86_match_ccmode (insn, CCNOmode)"
7514 "test{b}\t{%h1, %h0|%h0, %h1}"
7515 [(set_attr "type" "test")
7516 (set_attr "mode" "QI")])
7517
7518 ;; Combine likes to form bit extractions for some tests. Humor it.
7519 (define_insn "*testqi_ext_3"
7520 [(set (reg FLAGS_REG)
7521 (compare (zero_extract:SWI48
7522 (match_operand 0 "nonimmediate_operand" "rm")
7523 (match_operand:SWI48 1 "const_int_operand")
7524 (match_operand:SWI48 2 "const_int_operand"))
7525 (const_int 0)))]
7526 "ix86_match_ccmode (insn, CCNOmode)
7527 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7528 || GET_MODE (operands[0]) == SImode
7529 || GET_MODE (operands[0]) == HImode
7530 || GET_MODE (operands[0]) == QImode)
7531 /* Ensure that resulting mask is zero or sign extended operand. */
7532 && INTVAL (operands[2]) >= 0
7533 && ((INTVAL (operands[1]) > 0
7534 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7535 || (<MODE>mode == DImode
7536 && INTVAL (operands[1]) > 32
7537 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7538 "#")
7539
7540 (define_split
7541 [(set (match_operand 0 "flags_reg_operand")
7542 (match_operator 1 "compare_operator"
7543 [(zero_extract
7544 (match_operand 2 "nonimmediate_operand")
7545 (match_operand 3 "const_int_operand")
7546 (match_operand 4 "const_int_operand"))
7547 (const_int 0)]))]
7548 "ix86_match_ccmode (insn, CCNOmode)"
7549 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7550 {
7551 rtx val = operands[2];
7552 HOST_WIDE_INT len = INTVAL (operands[3]);
7553 HOST_WIDE_INT pos = INTVAL (operands[4]);
7554 HOST_WIDE_INT mask;
7555 enum machine_mode mode, submode;
7556
7557 mode = GET_MODE (val);
7558 if (MEM_P (val))
7559 {
7560 /* ??? Combine likes to put non-volatile mem extractions in QImode
7561 no matter the size of the test. So find a mode that works. */
7562 if (! MEM_VOLATILE_P (val))
7563 {
7564 mode = smallest_mode_for_size (pos + len, MODE_INT);
7565 val = adjust_address (val, mode, 0);
7566 }
7567 }
7568 else if (GET_CODE (val) == SUBREG
7569 && (submode = GET_MODE (SUBREG_REG (val)),
7570 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7571 && pos + len <= GET_MODE_BITSIZE (submode)
7572 && GET_MODE_CLASS (submode) == MODE_INT)
7573 {
7574 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7575 mode = submode;
7576 val = SUBREG_REG (val);
7577 }
7578 else if (mode == HImode && pos + len <= 8)
7579 {
7580 /* Small HImode tests can be converted to QImode. */
7581 mode = QImode;
7582 val = gen_lowpart (QImode, val);
7583 }
7584
7585 if (len == HOST_BITS_PER_WIDE_INT)
7586 mask = -1;
7587 else
7588 mask = ((HOST_WIDE_INT)1 << len) - 1;
7589 mask <<= pos;
7590
7591 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7592 })
7593
7594 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7595 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7596 ;; this is relatively important trick.
7597 ;; Do the conversion only post-reload to avoid limiting of the register class
7598 ;; to QI regs.
7599 (define_split
7600 [(set (match_operand 0 "flags_reg_operand")
7601 (match_operator 1 "compare_operator"
7602 [(and (match_operand 2 "register_operand")
7603 (match_operand 3 "const_int_operand"))
7604 (const_int 0)]))]
7605 "reload_completed
7606 && QI_REG_P (operands[2])
7607 && GET_MODE (operands[2]) != QImode
7608 && ((ix86_match_ccmode (insn, CCZmode)
7609 && !(INTVAL (operands[3]) & ~(255 << 8)))
7610 || (ix86_match_ccmode (insn, CCNOmode)
7611 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7612 [(set (match_dup 0)
7613 (match_op_dup 1
7614 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7615 (match_dup 3))
7616 (const_int 0)]))]
7617 {
7618 operands[2] = gen_lowpart (SImode, operands[2]);
7619 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7620 })
7621
7622 (define_split
7623 [(set (match_operand 0 "flags_reg_operand")
7624 (match_operator 1 "compare_operator"
7625 [(and (match_operand 2 "nonimmediate_operand")
7626 (match_operand 3 "const_int_operand"))
7627 (const_int 0)]))]
7628 "reload_completed
7629 && GET_MODE (operands[2]) != QImode
7630 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7631 && ((ix86_match_ccmode (insn, CCZmode)
7632 && !(INTVAL (operands[3]) & ~255))
7633 || (ix86_match_ccmode (insn, CCNOmode)
7634 && !(INTVAL (operands[3]) & ~127)))"
7635 [(set (match_dup 0)
7636 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7637 (const_int 0)]))]
7638 {
7639 operands[2] = gen_lowpart (QImode, operands[2]);
7640 operands[3] = gen_lowpart (QImode, operands[3]);
7641 })
7642
7643 (define_split
7644 [(set (match_operand:SWI12 0 "mask_reg_operand")
7645 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand")
7646 (match_operand:SWI12 2 "mask_reg_operand")))
7647 (clobber (reg:CC FLAGS_REG))]
7648 "TARGET_AVX512F && reload_completed"
7649 [(set (match_dup 0)
7650 (any_logic:SWI12 (match_dup 1)
7651 (match_dup 2)))])
7652
7653 (define_insn "*k<logic><mode>"
7654 [(set (match_operand:SWI12 0 "mask_reg_operand" "=Yk")
7655 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand" "Yk")
7656 (match_operand:SWI12 2 "mask_reg_operand" "Yk")))]
7657 "TARGET_AVX512F"
7658 "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7659 [(set_attr "mode" "<MODE>")
7660 (set_attr "type" "msklog")
7661 (set_attr "prefix" "vex")])
7662
7663 ;; %%% This used to optimize known byte-wide and operations to memory,
7664 ;; and sometimes to QImode registers. If this is considered useful,
7665 ;; it should be done with splitters.
7666
7667 (define_expand "and<mode>3"
7668 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7669 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7670 (match_operand:SWIM 2 "<general_szext_operand>")))]
7671 ""
7672 {
7673 enum machine_mode mode = <MODE>mode;
7674 rtx (*insn) (rtx, rtx);
7675
7676 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7677 {
7678 HOST_WIDE_INT ival = INTVAL (operands[2]);
7679
7680 if (ival == (HOST_WIDE_INT) 0xffffffff)
7681 mode = SImode;
7682 else if (ival == 0xffff)
7683 mode = HImode;
7684 else if (ival == 0xff)
7685 mode = QImode;
7686 }
7687
7688 if (mode == <MODE>mode)
7689 {
7690 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7691 DONE;
7692 }
7693
7694 if (<MODE>mode == DImode)
7695 insn = (mode == SImode)
7696 ? gen_zero_extendsidi2
7697 : (mode == HImode)
7698 ? gen_zero_extendhidi2
7699 : gen_zero_extendqidi2;
7700 else if (<MODE>mode == SImode)
7701 insn = (mode == HImode)
7702 ? gen_zero_extendhisi2
7703 : gen_zero_extendqisi2;
7704 else if (<MODE>mode == HImode)
7705 insn = gen_zero_extendqihi2;
7706 else
7707 gcc_unreachable ();
7708
7709 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7710 DONE;
7711 })
7712
7713 (define_insn "*anddi_1"
7714 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7715 (and:DI
7716 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7717 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7718 (clobber (reg:CC FLAGS_REG))]
7719 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7720 {
7721 switch (get_attr_type (insn))
7722 {
7723 case TYPE_IMOVX:
7724 return "#";
7725
7726 default:
7727 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7728 if (get_attr_mode (insn) == MODE_SI)
7729 return "and{l}\t{%k2, %k0|%k0, %k2}";
7730 else
7731 return "and{q}\t{%2, %0|%0, %2}";
7732 }
7733 }
7734 [(set_attr "type" "alu,alu,alu,imovx")
7735 (set_attr "length_immediate" "*,*,*,0")
7736 (set (attr "prefix_rex")
7737 (if_then_else
7738 (and (eq_attr "type" "imovx")
7739 (and (match_test "INTVAL (operands[2]) == 0xff")
7740 (match_operand 1 "ext_QIreg_operand")))
7741 (const_string "1")
7742 (const_string "*")))
7743 (set_attr "mode" "SI,DI,DI,SI")])
7744
7745 (define_insn "*andsi_1"
7746 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7747 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7748 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7749 (clobber (reg:CC FLAGS_REG))]
7750 "ix86_binary_operator_ok (AND, SImode, operands)"
7751 {
7752 switch (get_attr_type (insn))
7753 {
7754 case TYPE_IMOVX:
7755 return "#";
7756
7757 default:
7758 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7759 return "and{l}\t{%2, %0|%0, %2}";
7760 }
7761 }
7762 [(set_attr "type" "alu,alu,imovx")
7763 (set (attr "prefix_rex")
7764 (if_then_else
7765 (and (eq_attr "type" "imovx")
7766 (and (match_test "INTVAL (operands[2]) == 0xff")
7767 (match_operand 1 "ext_QIreg_operand")))
7768 (const_string "1")
7769 (const_string "*")))
7770 (set_attr "length_immediate" "*,*,0")
7771 (set_attr "mode" "SI")])
7772
7773 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7774 (define_insn "*andsi_1_zext"
7775 [(set (match_operand:DI 0 "register_operand" "=r")
7776 (zero_extend:DI
7777 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7778 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7779 (clobber (reg:CC FLAGS_REG))]
7780 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7781 "and{l}\t{%2, %k0|%k0, %2}"
7782 [(set_attr "type" "alu")
7783 (set_attr "mode" "SI")])
7784
7785 (define_insn "*andhi_1"
7786 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!Yk")
7787 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,Yk")
7788 (match_operand:HI 2 "general_operand" "rn,rm,L,Yk")))
7789 (clobber (reg:CC FLAGS_REG))]
7790 "ix86_binary_operator_ok (AND, HImode, operands)"
7791 {
7792 switch (get_attr_type (insn))
7793 {
7794 case TYPE_IMOVX:
7795 return "#";
7796
7797 case TYPE_MSKLOG:
7798 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7799
7800 default:
7801 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7802 return "and{w}\t{%2, %0|%0, %2}";
7803 }
7804 }
7805 [(set_attr "type" "alu,alu,imovx,msklog")
7806 (set_attr "length_immediate" "*,*,0,*")
7807 (set (attr "prefix_rex")
7808 (if_then_else
7809 (and (eq_attr "type" "imovx")
7810 (match_operand 1 "ext_QIreg_operand"))
7811 (const_string "1")
7812 (const_string "*")))
7813 (set_attr "mode" "HI,HI,SI,HI")])
7814
7815 ;; %%% Potential partial reg stall on alternative 2. What to do?
7816 (define_insn "*andqi_1"
7817 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!Yk")
7818 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
7819 (match_operand:QI 2 "general_operand" "qn,qmn,rn,Yk")))
7820 (clobber (reg:CC FLAGS_REG))]
7821 "ix86_binary_operator_ok (AND, QImode, operands)"
7822 "@
7823 and{b}\t{%2, %0|%0, %2}
7824 and{b}\t{%2, %0|%0, %2}
7825 and{l}\t{%k2, %k0|%k0, %k2}
7826 kandw\t{%2, %1, %0|%0, %1, %2}"
7827 [(set_attr "type" "alu,alu,alu,msklog")
7828 (set_attr "mode" "QI,QI,SI,HI")])
7829
7830 (define_insn "*andqi_1_slp"
7831 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7832 (and:QI (match_dup 0)
7833 (match_operand:QI 1 "general_operand" "qn,qmn")))
7834 (clobber (reg:CC FLAGS_REG))]
7835 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7836 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7837 "and{b}\t{%1, %0|%0, %1}"
7838 [(set_attr "type" "alu1")
7839 (set_attr "mode" "QI")])
7840
7841 (define_insn "kandn<mode>"
7842 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!Yk")
7843 (and:SWI12
7844 (not:SWI12
7845 (match_operand:SWI12 1 "register_operand" "r,0,Yk"))
7846 (match_operand:SWI12 2 "register_operand" "r,r,Yk")))
7847 (clobber (reg:CC FLAGS_REG))]
7848 "TARGET_AVX512F"
7849 "@
7850 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
7851 #
7852 kandnw\t{%2, %1, %0|%0, %1, %2}"
7853 [(set_attr "isa" "bmi,*,avx512f")
7854 (set_attr "type" "bitmanip,*,msklog")
7855 (set_attr "prefix" "*,*,vex")
7856 (set_attr "btver2_decode" "direct,*,*")
7857 (set_attr "mode" "<MODE>")])
7858
7859 (define_split
7860 [(set (match_operand:SWI12 0 "general_reg_operand")
7861 (and:SWI12
7862 (not:SWI12
7863 (match_dup 0))
7864 (match_operand:SWI12 1 "general_reg_operand")))
7865 (clobber (reg:CC FLAGS_REG))]
7866 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7867 [(set (match_dup 0)
7868 (not:HI (match_dup 0)))
7869 (parallel [(set (match_dup 0)
7870 (and:HI (match_dup 0)
7871 (match_dup 1)))
7872 (clobber (reg:CC FLAGS_REG))])])
7873
7874 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7875 (define_split
7876 [(set (match_operand:DI 0 "register_operand")
7877 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7878 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7879 (clobber (reg:CC FLAGS_REG))]
7880 "TARGET_64BIT"
7881 [(parallel [(set (match_dup 0)
7882 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7883 (clobber (reg:CC FLAGS_REG))])]
7884 "operands[2] = gen_lowpart (SImode, operands[2]);")
7885
7886 (define_split
7887 [(set (match_operand:SWI248 0 "register_operand")
7888 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7889 (match_operand:SWI248 2 "const_int_operand")))
7890 (clobber (reg:CC FLAGS_REG))]
7891 "reload_completed
7892 && true_regnum (operands[0]) != true_regnum (operands[1])"
7893 [(const_int 0)]
7894 {
7895 HOST_WIDE_INT ival = INTVAL (operands[2]);
7896 enum machine_mode mode;
7897 rtx (*insn) (rtx, rtx);
7898
7899 if (ival == (HOST_WIDE_INT) 0xffffffff)
7900 mode = SImode;
7901 else if (ival == 0xffff)
7902 mode = HImode;
7903 else
7904 {
7905 gcc_assert (ival == 0xff);
7906 mode = QImode;
7907 }
7908
7909 if (<MODE>mode == DImode)
7910 insn = (mode == SImode)
7911 ? gen_zero_extendsidi2
7912 : (mode == HImode)
7913 ? gen_zero_extendhidi2
7914 : gen_zero_extendqidi2;
7915 else
7916 {
7917 if (<MODE>mode != SImode)
7918 /* Zero extend to SImode to avoid partial register stalls. */
7919 operands[0] = gen_lowpart (SImode, operands[0]);
7920
7921 insn = (mode == HImode)
7922 ? gen_zero_extendhisi2
7923 : gen_zero_extendqisi2;
7924 }
7925 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7926 DONE;
7927 })
7928
7929 (define_split
7930 [(set (match_operand 0 "register_operand")
7931 (and (match_dup 0)
7932 (const_int -65536)))
7933 (clobber (reg:CC FLAGS_REG))]
7934 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7935 || optimize_function_for_size_p (cfun)"
7936 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7937 "operands[1] = gen_lowpart (HImode, operands[0]);")
7938
7939 (define_split
7940 [(set (match_operand 0 "ext_register_operand")
7941 (and (match_dup 0)
7942 (const_int -256)))
7943 (clobber (reg:CC FLAGS_REG))]
7944 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7945 && reload_completed"
7946 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7947 "operands[1] = gen_lowpart (QImode, operands[0]);")
7948
7949 (define_split
7950 [(set (match_operand 0 "ext_register_operand")
7951 (and (match_dup 0)
7952 (const_int -65281)))
7953 (clobber (reg:CC FLAGS_REG))]
7954 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7955 && reload_completed"
7956 [(parallel [(set (zero_extract:SI (match_dup 0)
7957 (const_int 8)
7958 (const_int 8))
7959 (xor:SI
7960 (zero_extract:SI (match_dup 0)
7961 (const_int 8)
7962 (const_int 8))
7963 (zero_extract:SI (match_dup 0)
7964 (const_int 8)
7965 (const_int 8))))
7966 (clobber (reg:CC FLAGS_REG))])]
7967 "operands[0] = gen_lowpart (SImode, operands[0]);")
7968
7969 (define_insn "*anddi_2"
7970 [(set (reg FLAGS_REG)
7971 (compare
7972 (and:DI
7973 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7974 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7975 (const_int 0)))
7976 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7977 (and:DI (match_dup 1) (match_dup 2)))]
7978 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7979 && ix86_binary_operator_ok (AND, DImode, operands)"
7980 "@
7981 and{l}\t{%k2, %k0|%k0, %k2}
7982 and{q}\t{%2, %0|%0, %2}
7983 and{q}\t{%2, %0|%0, %2}"
7984 [(set_attr "type" "alu")
7985 (set_attr "mode" "SI,DI,DI")])
7986
7987 (define_insn "*andqi_2_maybe_si"
7988 [(set (reg FLAGS_REG)
7989 (compare (and:QI
7990 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7991 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7992 (const_int 0)))
7993 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7994 (and:QI (match_dup 1) (match_dup 2)))]
7995 "ix86_binary_operator_ok (AND, QImode, operands)
7996 && ix86_match_ccmode (insn,
7997 CONST_INT_P (operands[2])
7998 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7999 {
8000 if (which_alternative == 2)
8001 {
8002 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8003 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8004 return "and{l}\t{%2, %k0|%k0, %2}";
8005 }
8006 return "and{b}\t{%2, %0|%0, %2}";
8007 }
8008 [(set_attr "type" "alu")
8009 (set_attr "mode" "QI,QI,SI")])
8010
8011 (define_insn "*and<mode>_2"
8012 [(set (reg FLAGS_REG)
8013 (compare (and:SWI124
8014 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8015 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8016 (const_int 0)))
8017 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8018 (and:SWI124 (match_dup 1) (match_dup 2)))]
8019 "ix86_match_ccmode (insn, CCNOmode)
8020 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8021 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8022 [(set_attr "type" "alu")
8023 (set_attr "mode" "<MODE>")])
8024
8025 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8026 (define_insn "*andsi_2_zext"
8027 [(set (reg FLAGS_REG)
8028 (compare (and:SI
8029 (match_operand:SI 1 "nonimmediate_operand" "%0")
8030 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8031 (const_int 0)))
8032 (set (match_operand:DI 0 "register_operand" "=r")
8033 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8034 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8035 && ix86_binary_operator_ok (AND, SImode, operands)"
8036 "and{l}\t{%2, %k0|%k0, %2}"
8037 [(set_attr "type" "alu")
8038 (set_attr "mode" "SI")])
8039
8040 (define_insn "*andqi_2_slp"
8041 [(set (reg FLAGS_REG)
8042 (compare (and:QI
8043 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8044 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8045 (const_int 0)))
8046 (set (strict_low_part (match_dup 0))
8047 (and:QI (match_dup 0) (match_dup 1)))]
8048 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8049 && ix86_match_ccmode (insn, CCNOmode)
8050 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8051 "and{b}\t{%1, %0|%0, %1}"
8052 [(set_attr "type" "alu1")
8053 (set_attr "mode" "QI")])
8054
8055 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8056 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8057 ;; for a QImode operand, which of course failed.
8058 (define_insn "andqi_ext_0"
8059 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8060 (const_int 8)
8061 (const_int 8))
8062 (and:SI
8063 (zero_extract:SI
8064 (match_operand 1 "ext_register_operand" "0")
8065 (const_int 8)
8066 (const_int 8))
8067 (match_operand 2 "const_int_operand" "n")))
8068 (clobber (reg:CC FLAGS_REG))]
8069 ""
8070 "and{b}\t{%2, %h0|%h0, %2}"
8071 [(set_attr "type" "alu")
8072 (set_attr "length_immediate" "1")
8073 (set_attr "modrm" "1")
8074 (set_attr "mode" "QI")])
8075
8076 ;; Generated by peephole translating test to and. This shows up
8077 ;; often in fp comparisons.
8078 (define_insn "*andqi_ext_0_cc"
8079 [(set (reg FLAGS_REG)
8080 (compare
8081 (and:SI
8082 (zero_extract:SI
8083 (match_operand 1 "ext_register_operand" "0")
8084 (const_int 8)
8085 (const_int 8))
8086 (match_operand 2 "const_int_operand" "n"))
8087 (const_int 0)))
8088 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8089 (const_int 8)
8090 (const_int 8))
8091 (and:SI
8092 (zero_extract:SI
8093 (match_dup 1)
8094 (const_int 8)
8095 (const_int 8))
8096 (match_dup 2)))]
8097 "ix86_match_ccmode (insn, CCNOmode)"
8098 "and{b}\t{%2, %h0|%h0, %2}"
8099 [(set_attr "type" "alu")
8100 (set_attr "length_immediate" "1")
8101 (set_attr "modrm" "1")
8102 (set_attr "mode" "QI")])
8103
8104 (define_insn "*andqi_ext_1"
8105 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8106 (const_int 8)
8107 (const_int 8))
8108 (and:SI
8109 (zero_extract:SI
8110 (match_operand 1 "ext_register_operand" "0,0")
8111 (const_int 8)
8112 (const_int 8))
8113 (zero_extend:SI
8114 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8115 (clobber (reg:CC FLAGS_REG))]
8116 ""
8117 "and{b}\t{%2, %h0|%h0, %2}"
8118 [(set_attr "isa" "*,nox64")
8119 (set_attr "type" "alu")
8120 (set_attr "length_immediate" "0")
8121 (set_attr "mode" "QI")])
8122
8123 (define_insn "*andqi_ext_2"
8124 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8125 (const_int 8)
8126 (const_int 8))
8127 (and:SI
8128 (zero_extract:SI
8129 (match_operand 1 "ext_register_operand" "%0")
8130 (const_int 8)
8131 (const_int 8))
8132 (zero_extract:SI
8133 (match_operand 2 "ext_register_operand" "Q")
8134 (const_int 8)
8135 (const_int 8))))
8136 (clobber (reg:CC FLAGS_REG))]
8137 ""
8138 "and{b}\t{%h2, %h0|%h0, %h2}"
8139 [(set_attr "type" "alu")
8140 (set_attr "length_immediate" "0")
8141 (set_attr "mode" "QI")])
8142
8143 ;; Convert wide AND instructions with immediate operand to shorter QImode
8144 ;; equivalents when possible.
8145 ;; Don't do the splitting with memory operands, since it introduces risk
8146 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8147 ;; for size, but that can (should?) be handled by generic code instead.
8148 (define_split
8149 [(set (match_operand 0 "register_operand")
8150 (and (match_operand 1 "register_operand")
8151 (match_operand 2 "const_int_operand")))
8152 (clobber (reg:CC FLAGS_REG))]
8153 "reload_completed
8154 && QI_REG_P (operands[0])
8155 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8156 && !(~INTVAL (operands[2]) & ~(255 << 8))
8157 && GET_MODE (operands[0]) != QImode"
8158 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8159 (and:SI (zero_extract:SI (match_dup 1)
8160 (const_int 8) (const_int 8))
8161 (match_dup 2)))
8162 (clobber (reg:CC FLAGS_REG))])]
8163 {
8164 operands[0] = gen_lowpart (SImode, operands[0]);
8165 operands[1] = gen_lowpart (SImode, operands[1]);
8166 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8167 })
8168
8169 ;; Since AND can be encoded with sign extended immediate, this is only
8170 ;; profitable when 7th bit is not set.
8171 (define_split
8172 [(set (match_operand 0 "register_operand")
8173 (and (match_operand 1 "general_operand")
8174 (match_operand 2 "const_int_operand")))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "reload_completed
8177 && ANY_QI_REG_P (operands[0])
8178 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8179 && !(~INTVAL (operands[2]) & ~255)
8180 && !(INTVAL (operands[2]) & 128)
8181 && GET_MODE (operands[0]) != QImode"
8182 [(parallel [(set (strict_low_part (match_dup 0))
8183 (and:QI (match_dup 1)
8184 (match_dup 2)))
8185 (clobber (reg:CC FLAGS_REG))])]
8186 {
8187 operands[0] = gen_lowpart (QImode, operands[0]);
8188 operands[1] = gen_lowpart (QImode, operands[1]);
8189 operands[2] = gen_lowpart (QImode, operands[2]);
8190 })
8191 \f
8192 ;; Logical inclusive and exclusive OR instructions
8193
8194 ;; %%% This used to optimize known byte-wide and operations to memory.
8195 ;; If this is considered useful, it should be done with splitters.
8196
8197 (define_expand "<code><mode>3"
8198 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8199 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8200 (match_operand:SWIM 2 "<general_operand>")))]
8201 ""
8202 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8203
8204 (define_insn "*<code><mode>_1"
8205 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
8206 (any_or:SWI48
8207 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
8208 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>")))
8209 (clobber (reg:CC FLAGS_REG))]
8210 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8211 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8212 [(set_attr "type" "alu")
8213 (set_attr "mode" "<MODE>")])
8214
8215 (define_insn "*<code>hi_1"
8216 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!Yk")
8217 (any_or:HI
8218 (match_operand:HI 1 "nonimmediate_operand" "%0,0,Yk")
8219 (match_operand:HI 2 "general_operand" "<g>,r<i>,Yk")))
8220 (clobber (reg:CC FLAGS_REG))]
8221 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8222 "@
8223 <logic>{w}\t{%2, %0|%0, %2}
8224 <logic>{w}\t{%2, %0|%0, %2}
8225 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8226 [(set_attr "type" "alu,alu,msklog")
8227 (set_attr "mode" "HI")])
8228
8229 ;; %%% Potential partial reg stall on alternative 2. What to do?
8230 (define_insn "*<code>qi_1"
8231 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!Yk")
8232 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
8233 (match_operand:QI 2 "general_operand" "qmn,qn,rn,Yk")))
8234 (clobber (reg:CC FLAGS_REG))]
8235 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8236 "@
8237 <logic>{b}\t{%2, %0|%0, %2}
8238 <logic>{b}\t{%2, %0|%0, %2}
8239 <logic>{l}\t{%k2, %k0|%k0, %k2}
8240 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8241 [(set_attr "type" "alu,alu,alu,msklog")
8242 (set_attr "mode" "QI,QI,SI,HI")])
8243
8244 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8245 (define_insn "*<code>si_1_zext"
8246 [(set (match_operand:DI 0 "register_operand" "=r")
8247 (zero_extend:DI
8248 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8249 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8250 (clobber (reg:CC FLAGS_REG))]
8251 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8252 "<logic>{l}\t{%2, %k0|%k0, %2}"
8253 [(set_attr "type" "alu")
8254 (set_attr "mode" "SI")])
8255
8256 (define_insn "*<code>si_1_zext_imm"
8257 [(set (match_operand:DI 0 "register_operand" "=r")
8258 (any_or:DI
8259 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8260 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8261 (clobber (reg:CC FLAGS_REG))]
8262 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8263 "<logic>{l}\t{%2, %k0|%k0, %2}"
8264 [(set_attr "type" "alu")
8265 (set_attr "mode" "SI")])
8266
8267 (define_insn "*<code>qi_1_slp"
8268 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8269 (any_or:QI (match_dup 0)
8270 (match_operand:QI 1 "general_operand" "qmn,qn")))
8271 (clobber (reg:CC FLAGS_REG))]
8272 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8273 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8274 "<logic>{b}\t{%1, %0|%0, %1}"
8275 [(set_attr "type" "alu1")
8276 (set_attr "mode" "QI")])
8277
8278 (define_insn "*<code><mode>_2"
8279 [(set (reg FLAGS_REG)
8280 (compare (any_or:SWI
8281 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8282 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8283 (const_int 0)))
8284 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8285 (any_or:SWI (match_dup 1) (match_dup 2)))]
8286 "ix86_match_ccmode (insn, CCNOmode)
8287 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8288 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8289 [(set_attr "type" "alu")
8290 (set_attr "mode" "<MODE>")])
8291
8292 (define_insn "kxnor<mode>"
8293 [(set (match_operand:SWI12 0 "register_operand" "=r,!Yk")
8294 (not:SWI12
8295 (xor:SWI12
8296 (match_operand:SWI12 1 "register_operand" "0,Yk")
8297 (match_operand:SWI12 2 "register_operand" "r,Yk"))))
8298 (clobber (reg:CC FLAGS_REG))]
8299 "TARGET_AVX512F"
8300 "@
8301 #
8302 kxnorw\t{%2, %1, %0|%0, %1, %2}"
8303 [(set_attr "type" "*,msklog")
8304 (set_attr "prefix" "*,vex")
8305 (set_attr "mode" "<MODE>")])
8306
8307 (define_split
8308 [(set (match_operand:SWI12 0 "general_reg_operand")
8309 (not:SWI12
8310 (xor:SWI12
8311 (match_dup 0)
8312 (match_operand:SWI12 1 "general_reg_operand"))))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "TARGET_AVX512F && reload_completed"
8315 [(parallel [(set (match_dup 0)
8316 (xor:HI (match_dup 0)
8317 (match_dup 1)))
8318 (clobber (reg:CC FLAGS_REG))])
8319 (set (match_dup 0)
8320 (not:HI (match_dup 0)))])
8321
8322 (define_insn "kortestzhi"
8323 [(set (reg:CCZ FLAGS_REG)
8324 (compare:CCZ
8325 (ior:HI
8326 (match_operand:HI 0 "register_operand" "Yk")
8327 (match_operand:HI 1 "register_operand" "Yk"))
8328 (const_int 0)))]
8329 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8330 "kortestw\t{%1, %0|%0, %1}"
8331 [(set_attr "mode" "HI")
8332 (set_attr "type" "msklog")
8333 (set_attr "prefix" "vex")])
8334
8335 (define_insn "kortestchi"
8336 [(set (reg:CCC FLAGS_REG)
8337 (compare:CCC
8338 (ior:HI
8339 (match_operand:HI 0 "register_operand" "Yk")
8340 (match_operand:HI 1 "register_operand" "Yk"))
8341 (const_int -1)))]
8342 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8343 "kortestw\t{%1, %0|%0, %1}"
8344 [(set_attr "mode" "HI")
8345 (set_attr "type" "msklog")
8346 (set_attr "prefix" "vex")])
8347
8348 (define_insn "kunpckhi"
8349 [(set (match_operand:HI 0 "register_operand" "=Yk")
8350 (ior:HI
8351 (ashift:HI
8352 (match_operand:HI 1 "register_operand" "Yk")
8353 (const_int 8))
8354 (zero_extend:HI (match_operand:QI 2 "register_operand" "Yk"))))]
8355 "TARGET_AVX512F"
8356 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8357 [(set_attr "mode" "HI")
8358 (set_attr "type" "msklog")
8359 (set_attr "prefix" "vex")])
8360
8361 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8362 ;; ??? Special case for immediate operand is missing - it is tricky.
8363 (define_insn "*<code>si_2_zext"
8364 [(set (reg FLAGS_REG)
8365 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8366 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8367 (const_int 0)))
8368 (set (match_operand:DI 0 "register_operand" "=r")
8369 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8370 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8371 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8372 "<logic>{l}\t{%2, %k0|%k0, %2}"
8373 [(set_attr "type" "alu")
8374 (set_attr "mode" "SI")])
8375
8376 (define_insn "*<code>si_2_zext_imm"
8377 [(set (reg FLAGS_REG)
8378 (compare (any_or:SI
8379 (match_operand:SI 1 "nonimmediate_operand" "%0")
8380 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8381 (const_int 0)))
8382 (set (match_operand:DI 0 "register_operand" "=r")
8383 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8384 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8385 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8386 "<logic>{l}\t{%2, %k0|%k0, %2}"
8387 [(set_attr "type" "alu")
8388 (set_attr "mode" "SI")])
8389
8390 (define_insn "*<code>qi_2_slp"
8391 [(set (reg FLAGS_REG)
8392 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8393 (match_operand:QI 1 "general_operand" "qmn,qn"))
8394 (const_int 0)))
8395 (set (strict_low_part (match_dup 0))
8396 (any_or:QI (match_dup 0) (match_dup 1)))]
8397 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8398 && ix86_match_ccmode (insn, CCNOmode)
8399 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8400 "<logic>{b}\t{%1, %0|%0, %1}"
8401 [(set_attr "type" "alu1")
8402 (set_attr "mode" "QI")])
8403
8404 (define_insn "*<code><mode>_3"
8405 [(set (reg FLAGS_REG)
8406 (compare (any_or:SWI
8407 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8408 (match_operand:SWI 2 "<general_operand>" "<g>"))
8409 (const_int 0)))
8410 (clobber (match_scratch:SWI 0 "=<r>"))]
8411 "ix86_match_ccmode (insn, CCNOmode)
8412 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8413 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "<MODE>")])
8416
8417 (define_insn "*<code>qi_ext_0"
8418 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8419 (const_int 8)
8420 (const_int 8))
8421 (any_or:SI
8422 (zero_extract:SI
8423 (match_operand 1 "ext_register_operand" "0")
8424 (const_int 8)
8425 (const_int 8))
8426 (match_operand 2 "const_int_operand" "n")))
8427 (clobber (reg:CC FLAGS_REG))]
8428 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8429 "<logic>{b}\t{%2, %h0|%h0, %2}"
8430 [(set_attr "type" "alu")
8431 (set_attr "length_immediate" "1")
8432 (set_attr "modrm" "1")
8433 (set_attr "mode" "QI")])
8434
8435 (define_insn "*<code>qi_ext_1"
8436 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8437 (const_int 8)
8438 (const_int 8))
8439 (any_or:SI
8440 (zero_extract:SI
8441 (match_operand 1 "ext_register_operand" "0,0")
8442 (const_int 8)
8443 (const_int 8))
8444 (zero_extend:SI
8445 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8446 (clobber (reg:CC FLAGS_REG))]
8447 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8448 "<logic>{b}\t{%2, %h0|%h0, %2}"
8449 [(set_attr "isa" "*,nox64")
8450 (set_attr "type" "alu")
8451 (set_attr "length_immediate" "0")
8452 (set_attr "mode" "QI")])
8453
8454 (define_insn "*<code>qi_ext_2"
8455 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8456 (const_int 8)
8457 (const_int 8))
8458 (any_or:SI
8459 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8460 (const_int 8)
8461 (const_int 8))
8462 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8463 (const_int 8)
8464 (const_int 8))))
8465 (clobber (reg:CC FLAGS_REG))]
8466 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8467 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8468 [(set_attr "type" "alu")
8469 (set_attr "length_immediate" "0")
8470 (set_attr "mode" "QI")])
8471
8472 (define_split
8473 [(set (match_operand 0 "register_operand")
8474 (any_or (match_operand 1 "register_operand")
8475 (match_operand 2 "const_int_operand")))
8476 (clobber (reg:CC FLAGS_REG))]
8477 "reload_completed
8478 && QI_REG_P (operands[0])
8479 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8480 && !(INTVAL (operands[2]) & ~(255 << 8))
8481 && GET_MODE (operands[0]) != QImode"
8482 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8483 (any_or:SI (zero_extract:SI (match_dup 1)
8484 (const_int 8) (const_int 8))
8485 (match_dup 2)))
8486 (clobber (reg:CC FLAGS_REG))])]
8487 {
8488 operands[0] = gen_lowpart (SImode, operands[0]);
8489 operands[1] = gen_lowpart (SImode, operands[1]);
8490 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8491 })
8492
8493 ;; Since OR can be encoded with sign extended immediate, this is only
8494 ;; profitable when 7th bit is set.
8495 (define_split
8496 [(set (match_operand 0 "register_operand")
8497 (any_or (match_operand 1 "general_operand")
8498 (match_operand 2 "const_int_operand")))
8499 (clobber (reg:CC FLAGS_REG))]
8500 "reload_completed
8501 && ANY_QI_REG_P (operands[0])
8502 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8503 && !(INTVAL (operands[2]) & ~255)
8504 && (INTVAL (operands[2]) & 128)
8505 && GET_MODE (operands[0]) != QImode"
8506 [(parallel [(set (strict_low_part (match_dup 0))
8507 (any_or:QI (match_dup 1)
8508 (match_dup 2)))
8509 (clobber (reg:CC FLAGS_REG))])]
8510 {
8511 operands[0] = gen_lowpart (QImode, operands[0]);
8512 operands[1] = gen_lowpart (QImode, operands[1]);
8513 operands[2] = gen_lowpart (QImode, operands[2]);
8514 })
8515
8516 (define_expand "xorqi_cc_ext_1"
8517 [(parallel [
8518 (set (reg:CCNO FLAGS_REG)
8519 (compare:CCNO
8520 (xor:SI
8521 (zero_extract:SI
8522 (match_operand 1 "ext_register_operand")
8523 (const_int 8)
8524 (const_int 8))
8525 (match_operand:QI 2 "const_int_operand"))
8526 (const_int 0)))
8527 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8528 (const_int 8)
8529 (const_int 8))
8530 (xor:SI
8531 (zero_extract:SI
8532 (match_dup 1)
8533 (const_int 8)
8534 (const_int 8))
8535 (match_dup 2)))])])
8536
8537 (define_insn "*xorqi_cc_ext_1"
8538 [(set (reg FLAGS_REG)
8539 (compare
8540 (xor:SI
8541 (zero_extract:SI
8542 (match_operand 1 "ext_register_operand" "0,0")
8543 (const_int 8)
8544 (const_int 8))
8545 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8546 (const_int 0)))
8547 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8548 (const_int 8)
8549 (const_int 8))
8550 (xor:SI
8551 (zero_extract:SI
8552 (match_dup 1)
8553 (const_int 8)
8554 (const_int 8))
8555 (match_dup 2)))]
8556 "ix86_match_ccmode (insn, CCNOmode)"
8557 "xor{b}\t{%2, %h0|%h0, %2}"
8558 [(set_attr "isa" "*,nox64")
8559 (set_attr "type" "alu")
8560 (set_attr "modrm" "1")
8561 (set_attr "mode" "QI")])
8562 \f
8563 ;; Negation instructions
8564
8565 (define_expand "neg<mode>2"
8566 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8567 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8568 ""
8569 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8570
8571 (define_insn_and_split "*neg<dwi>2_doubleword"
8572 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8573 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8574 (clobber (reg:CC FLAGS_REG))]
8575 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8576 "#"
8577 "reload_completed"
8578 [(parallel
8579 [(set (reg:CCZ FLAGS_REG)
8580 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8581 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8582 (parallel
8583 [(set (match_dup 2)
8584 (plus:DWIH (match_dup 3)
8585 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8586 (const_int 0))))
8587 (clobber (reg:CC FLAGS_REG))])
8588 (parallel
8589 [(set (match_dup 2)
8590 (neg:DWIH (match_dup 2)))
8591 (clobber (reg:CC FLAGS_REG))])]
8592 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8593
8594 (define_insn "*neg<mode>2_1"
8595 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8596 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8597 (clobber (reg:CC FLAGS_REG))]
8598 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8599 "neg{<imodesuffix>}\t%0"
8600 [(set_attr "type" "negnot")
8601 (set_attr "mode" "<MODE>")])
8602
8603 ;; Combine is quite creative about this pattern.
8604 (define_insn "*negsi2_1_zext"
8605 [(set (match_operand:DI 0 "register_operand" "=r")
8606 (lshiftrt:DI
8607 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8608 (const_int 32)))
8609 (const_int 32)))
8610 (clobber (reg:CC FLAGS_REG))]
8611 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8612 "neg{l}\t%k0"
8613 [(set_attr "type" "negnot")
8614 (set_attr "mode" "SI")])
8615
8616 ;; The problem with neg is that it does not perform (compare x 0),
8617 ;; it really performs (compare 0 x), which leaves us with the zero
8618 ;; flag being the only useful item.
8619
8620 (define_insn "*neg<mode>2_cmpz"
8621 [(set (reg:CCZ FLAGS_REG)
8622 (compare:CCZ
8623 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8624 (const_int 0)))
8625 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8626 (neg:SWI (match_dup 1)))]
8627 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8628 "neg{<imodesuffix>}\t%0"
8629 [(set_attr "type" "negnot")
8630 (set_attr "mode" "<MODE>")])
8631
8632 (define_insn "*negsi2_cmpz_zext"
8633 [(set (reg:CCZ FLAGS_REG)
8634 (compare:CCZ
8635 (lshiftrt:DI
8636 (neg:DI (ashift:DI
8637 (match_operand:DI 1 "register_operand" "0")
8638 (const_int 32)))
8639 (const_int 32))
8640 (const_int 0)))
8641 (set (match_operand:DI 0 "register_operand" "=r")
8642 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8643 (const_int 32)))
8644 (const_int 32)))]
8645 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8646 "neg{l}\t%k0"
8647 [(set_attr "type" "negnot")
8648 (set_attr "mode" "SI")])
8649
8650 ;; Changing of sign for FP values is doable using integer unit too.
8651
8652 (define_expand "<code><mode>2"
8653 [(set (match_operand:X87MODEF 0 "register_operand")
8654 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8655 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8656 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8657
8658 (define_insn "*absneg<mode>2_mixed"
8659 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8660 (match_operator:MODEF 3 "absneg_operator"
8661 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8662 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8663 (clobber (reg:CC FLAGS_REG))]
8664 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8665 "#")
8666
8667 (define_insn "*absneg<mode>2_sse"
8668 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8669 (match_operator:MODEF 3 "absneg_operator"
8670 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8671 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8672 (clobber (reg:CC FLAGS_REG))]
8673 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8674 "#")
8675
8676 (define_insn "*absneg<mode>2_i387"
8677 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8678 (match_operator:X87MODEF 3 "absneg_operator"
8679 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8680 (use (match_operand 2))
8681 (clobber (reg:CC FLAGS_REG))]
8682 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8683 "#")
8684
8685 (define_expand "<code>tf2"
8686 [(set (match_operand:TF 0 "register_operand")
8687 (absneg:TF (match_operand:TF 1 "register_operand")))]
8688 "TARGET_SSE"
8689 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8690
8691 (define_insn "*absnegtf2_sse"
8692 [(set (match_operand:TF 0 "register_operand" "=x,x")
8693 (match_operator:TF 3 "absneg_operator"
8694 [(match_operand:TF 1 "register_operand" "0,x")]))
8695 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8696 (clobber (reg:CC FLAGS_REG))]
8697 "TARGET_SSE"
8698 "#")
8699
8700 ;; Splitters for fp abs and neg.
8701
8702 (define_split
8703 [(set (match_operand 0 "fp_register_operand")
8704 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8705 (use (match_operand 2))
8706 (clobber (reg:CC FLAGS_REG))]
8707 "reload_completed"
8708 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8709
8710 (define_split
8711 [(set (match_operand 0 "register_operand")
8712 (match_operator 3 "absneg_operator"
8713 [(match_operand 1 "register_operand")]))
8714 (use (match_operand 2 "nonimmediate_operand"))
8715 (clobber (reg:CC FLAGS_REG))]
8716 "reload_completed && SSE_REG_P (operands[0])"
8717 [(set (match_dup 0) (match_dup 3))]
8718 {
8719 enum machine_mode mode = GET_MODE (operands[0]);
8720 enum machine_mode vmode = GET_MODE (operands[2]);
8721 rtx tmp;
8722
8723 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8724 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8725 if (operands_match_p (operands[0], operands[2]))
8726 {
8727 tmp = operands[1];
8728 operands[1] = operands[2];
8729 operands[2] = tmp;
8730 }
8731 if (GET_CODE (operands[3]) == ABS)
8732 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8733 else
8734 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8735 operands[3] = tmp;
8736 })
8737
8738 (define_split
8739 [(set (match_operand:SF 0 "register_operand")
8740 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8741 (use (match_operand:V4SF 2))
8742 (clobber (reg:CC FLAGS_REG))]
8743 "reload_completed"
8744 [(parallel [(set (match_dup 0) (match_dup 1))
8745 (clobber (reg:CC FLAGS_REG))])]
8746 {
8747 rtx tmp;
8748 operands[0] = gen_lowpart (SImode, operands[0]);
8749 if (GET_CODE (operands[1]) == ABS)
8750 {
8751 tmp = gen_int_mode (0x7fffffff, SImode);
8752 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8753 }
8754 else
8755 {
8756 tmp = gen_int_mode (0x80000000, SImode);
8757 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8758 }
8759 operands[1] = tmp;
8760 })
8761
8762 (define_split
8763 [(set (match_operand:DF 0 "register_operand")
8764 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8765 (use (match_operand 2))
8766 (clobber (reg:CC FLAGS_REG))]
8767 "reload_completed"
8768 [(parallel [(set (match_dup 0) (match_dup 1))
8769 (clobber (reg:CC FLAGS_REG))])]
8770 {
8771 rtx tmp;
8772 if (TARGET_64BIT)
8773 {
8774 tmp = gen_lowpart (DImode, operands[0]);
8775 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8776 operands[0] = tmp;
8777
8778 if (GET_CODE (operands[1]) == ABS)
8779 tmp = const0_rtx;
8780 else
8781 tmp = gen_rtx_NOT (DImode, tmp);
8782 }
8783 else
8784 {
8785 operands[0] = gen_highpart (SImode, operands[0]);
8786 if (GET_CODE (operands[1]) == ABS)
8787 {
8788 tmp = gen_int_mode (0x7fffffff, SImode);
8789 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8790 }
8791 else
8792 {
8793 tmp = gen_int_mode (0x80000000, SImode);
8794 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8795 }
8796 }
8797 operands[1] = tmp;
8798 })
8799
8800 (define_split
8801 [(set (match_operand:XF 0 "register_operand")
8802 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8803 (use (match_operand 2))
8804 (clobber (reg:CC FLAGS_REG))]
8805 "reload_completed"
8806 [(parallel [(set (match_dup 0) (match_dup 1))
8807 (clobber (reg:CC FLAGS_REG))])]
8808 {
8809 rtx tmp;
8810 operands[0] = gen_rtx_REG (SImode,
8811 true_regnum (operands[0])
8812 + (TARGET_64BIT ? 1 : 2));
8813 if (GET_CODE (operands[1]) == ABS)
8814 {
8815 tmp = GEN_INT (0x7fff);
8816 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8817 }
8818 else
8819 {
8820 tmp = GEN_INT (0x8000);
8821 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8822 }
8823 operands[1] = tmp;
8824 })
8825
8826 ;; Conditionalize these after reload. If they match before reload, we
8827 ;; lose the clobber and ability to use integer instructions.
8828
8829 (define_insn "*<code><mode>2_1"
8830 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8831 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8832 "TARGET_80387
8833 && (reload_completed
8834 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8835 "f<absneg_mnemonic>"
8836 [(set_attr "type" "fsgn")
8837 (set_attr "mode" "<MODE>")])
8838
8839 (define_insn "*<code>extendsfdf2"
8840 [(set (match_operand:DF 0 "register_operand" "=f")
8841 (absneg:DF (float_extend:DF
8842 (match_operand:SF 1 "register_operand" "0"))))]
8843 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8844 "f<absneg_mnemonic>"
8845 [(set_attr "type" "fsgn")
8846 (set_attr "mode" "DF")])
8847
8848 (define_insn "*<code>extendsfxf2"
8849 [(set (match_operand:XF 0 "register_operand" "=f")
8850 (absneg:XF (float_extend:XF
8851 (match_operand:SF 1 "register_operand" "0"))))]
8852 "TARGET_80387"
8853 "f<absneg_mnemonic>"
8854 [(set_attr "type" "fsgn")
8855 (set_attr "mode" "XF")])
8856
8857 (define_insn "*<code>extenddfxf2"
8858 [(set (match_operand:XF 0 "register_operand" "=f")
8859 (absneg:XF (float_extend:XF
8860 (match_operand:DF 1 "register_operand" "0"))))]
8861 "TARGET_80387"
8862 "f<absneg_mnemonic>"
8863 [(set_attr "type" "fsgn")
8864 (set_attr "mode" "XF")])
8865
8866 ;; Copysign instructions
8867
8868 (define_mode_iterator CSGNMODE [SF DF TF])
8869 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8870
8871 (define_expand "copysign<mode>3"
8872 [(match_operand:CSGNMODE 0 "register_operand")
8873 (match_operand:CSGNMODE 1 "nonmemory_operand")
8874 (match_operand:CSGNMODE 2 "register_operand")]
8875 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8876 || (TARGET_SSE && (<MODE>mode == TFmode))"
8877 "ix86_expand_copysign (operands); DONE;")
8878
8879 (define_insn_and_split "copysign<mode>3_const"
8880 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8881 (unspec:CSGNMODE
8882 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8883 (match_operand:CSGNMODE 2 "register_operand" "0")
8884 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8885 UNSPEC_COPYSIGN))]
8886 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8887 || (TARGET_SSE && (<MODE>mode == TFmode))"
8888 "#"
8889 "&& reload_completed"
8890 [(const_int 0)]
8891 "ix86_split_copysign_const (operands); DONE;")
8892
8893 (define_insn "copysign<mode>3_var"
8894 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8895 (unspec:CSGNMODE
8896 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8897 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8898 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8899 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8900 UNSPEC_COPYSIGN))
8901 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8902 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8903 || (TARGET_SSE && (<MODE>mode == TFmode))"
8904 "#")
8905
8906 (define_split
8907 [(set (match_operand:CSGNMODE 0 "register_operand")
8908 (unspec:CSGNMODE
8909 [(match_operand:CSGNMODE 2 "register_operand")
8910 (match_operand:CSGNMODE 3 "register_operand")
8911 (match_operand:<CSGNVMODE> 4)
8912 (match_operand:<CSGNVMODE> 5)]
8913 UNSPEC_COPYSIGN))
8914 (clobber (match_scratch:<CSGNVMODE> 1))]
8915 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8916 || (TARGET_SSE && (<MODE>mode == TFmode)))
8917 && reload_completed"
8918 [(const_int 0)]
8919 "ix86_split_copysign_var (operands); DONE;")
8920 \f
8921 ;; One complement instructions
8922
8923 (define_expand "one_cmpl<mode>2"
8924 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8925 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8926 ""
8927 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8928
8929 (define_insn "*one_cmpl<mode>2_1"
8930 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8931 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0")))]
8932 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8933 "not{<imodesuffix>}\t%0"
8934 [(set_attr "type" "negnot")
8935 (set_attr "mode" "<MODE>")])
8936
8937 (define_insn "*one_cmplhi2_1"
8938 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!Yk")
8939 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,Yk")))]
8940 "ix86_unary_operator_ok (NOT, HImode, operands)"
8941 "@
8942 not{w}\t%0
8943 knotw\t{%1, %0|%0, %1}"
8944 [(set_attr "isa" "*,avx512f")
8945 (set_attr "type" "negnot,msklog")
8946 (set_attr "prefix" "*,vex")
8947 (set_attr "mode" "HI")])
8948
8949 ;; %%% Potential partial reg stall on alternative 1. What to do?
8950 (define_insn "*one_cmplqi2_1"
8951 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!Yk")
8952 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,Yk")))]
8953 "ix86_unary_operator_ok (NOT, QImode, operands)"
8954 "@
8955 not{b}\t%0
8956 not{l}\t%k0
8957 knotw\t{%1, %0|%0, %1}"
8958 [(set_attr "isa" "*,*,avx512f")
8959 (set_attr "type" "negnot,negnot,msklog")
8960 (set_attr "prefix" "*,*,vex")
8961 (set_attr "mode" "QI,SI,QI")])
8962
8963 ;; ??? Currently never generated - xor is used instead.
8964 (define_insn "*one_cmplsi2_1_zext"
8965 [(set (match_operand:DI 0 "register_operand" "=r")
8966 (zero_extend:DI
8967 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8968 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8969 "not{l}\t%k0"
8970 [(set_attr "type" "negnot")
8971 (set_attr "mode" "SI")])
8972
8973 (define_insn "*one_cmpl<mode>2_2"
8974 [(set (reg FLAGS_REG)
8975 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8976 (const_int 0)))
8977 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8978 (not:SWI (match_dup 1)))]
8979 "ix86_match_ccmode (insn, CCNOmode)
8980 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8981 "#"
8982 [(set_attr "type" "alu1")
8983 (set_attr "mode" "<MODE>")])
8984
8985 (define_split
8986 [(set (match_operand 0 "flags_reg_operand")
8987 (match_operator 2 "compare_operator"
8988 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8989 (const_int 0)]))
8990 (set (match_operand:SWI 1 "nonimmediate_operand")
8991 (not:SWI (match_dup 3)))]
8992 "ix86_match_ccmode (insn, CCNOmode)"
8993 [(parallel [(set (match_dup 0)
8994 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8995 (const_int 0)]))
8996 (set (match_dup 1)
8997 (xor:SWI (match_dup 3) (const_int -1)))])])
8998
8999 ;; ??? Currently never generated - xor is used instead.
9000 (define_insn "*one_cmplsi2_2_zext"
9001 [(set (reg FLAGS_REG)
9002 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9003 (const_int 0)))
9004 (set (match_operand:DI 0 "register_operand" "=r")
9005 (zero_extend:DI (not:SI (match_dup 1))))]
9006 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9007 && ix86_unary_operator_ok (NOT, SImode, operands)"
9008 "#"
9009 [(set_attr "type" "alu1")
9010 (set_attr "mode" "SI")])
9011
9012 (define_split
9013 [(set (match_operand 0 "flags_reg_operand")
9014 (match_operator 2 "compare_operator"
9015 [(not:SI (match_operand:SI 3 "register_operand"))
9016 (const_int 0)]))
9017 (set (match_operand:DI 1 "register_operand")
9018 (zero_extend:DI (not:SI (match_dup 3))))]
9019 "ix86_match_ccmode (insn, CCNOmode)"
9020 [(parallel [(set (match_dup 0)
9021 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9022 (const_int 0)]))
9023 (set (match_dup 1)
9024 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9025 \f
9026 ;; Shift instructions
9027
9028 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9029 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9030 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9031 ;; from the assembler input.
9032 ;;
9033 ;; This instruction shifts the target reg/mem as usual, but instead of
9034 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9035 ;; is a left shift double, bits are taken from the high order bits of
9036 ;; reg, else if the insn is a shift right double, bits are taken from the
9037 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9038 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9039 ;;
9040 ;; Since sh[lr]d does not change the `reg' operand, that is done
9041 ;; separately, making all shifts emit pairs of shift double and normal
9042 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9043 ;; support a 63 bit shift, each shift where the count is in a reg expands
9044 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9045 ;;
9046 ;; If the shift count is a constant, we need never emit more than one
9047 ;; shift pair, instead using moves and sign extension for counts greater
9048 ;; than 31.
9049
9050 (define_expand "ashl<mode>3"
9051 [(set (match_operand:SDWIM 0 "<shift_operand>")
9052 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9053 (match_operand:QI 2 "nonmemory_operand")))]
9054 ""
9055 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9056
9057 (define_insn "*ashl<mode>3_doubleword"
9058 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9059 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9060 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9061 (clobber (reg:CC FLAGS_REG))]
9062 ""
9063 "#"
9064 [(set_attr "type" "multi")])
9065
9066 (define_split
9067 [(set (match_operand:DWI 0 "register_operand")
9068 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9069 (match_operand:QI 2 "nonmemory_operand")))
9070 (clobber (reg:CC FLAGS_REG))]
9071 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9072 [(const_int 0)]
9073 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9074
9075 ;; By default we don't ask for a scratch register, because when DWImode
9076 ;; values are manipulated, registers are already at a premium. But if
9077 ;; we have one handy, we won't turn it away.
9078
9079 (define_peephole2
9080 [(match_scratch:DWIH 3 "r")
9081 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9082 (ashift:<DWI>
9083 (match_operand:<DWI> 1 "nonmemory_operand")
9084 (match_operand:QI 2 "nonmemory_operand")))
9085 (clobber (reg:CC FLAGS_REG))])
9086 (match_dup 3)]
9087 "TARGET_CMOVE"
9088 [(const_int 0)]
9089 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9090
9091 (define_insn "x86_64_shld"
9092 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9093 (ior:DI (ashift:DI (match_dup 0)
9094 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9095 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9096 (minus:QI (const_int 64) (match_dup 2)))))
9097 (clobber (reg:CC FLAGS_REG))]
9098 "TARGET_64BIT"
9099 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9100 [(set_attr "type" "ishift")
9101 (set_attr "prefix_0f" "1")
9102 (set_attr "mode" "DI")
9103 (set_attr "athlon_decode" "vector")
9104 (set_attr "amdfam10_decode" "vector")
9105 (set_attr "bdver1_decode" "vector")])
9106
9107 (define_insn "x86_shld"
9108 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9109 (ior:SI (ashift:SI (match_dup 0)
9110 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9111 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9112 (minus:QI (const_int 32) (match_dup 2)))))
9113 (clobber (reg:CC FLAGS_REG))]
9114 ""
9115 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9116 [(set_attr "type" "ishift")
9117 (set_attr "prefix_0f" "1")
9118 (set_attr "mode" "SI")
9119 (set_attr "pent_pair" "np")
9120 (set_attr "athlon_decode" "vector")
9121 (set_attr "amdfam10_decode" "vector")
9122 (set_attr "bdver1_decode" "vector")])
9123
9124 (define_expand "x86_shift<mode>_adj_1"
9125 [(set (reg:CCZ FLAGS_REG)
9126 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9127 (match_dup 4))
9128 (const_int 0)))
9129 (set (match_operand:SWI48 0 "register_operand")
9130 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9131 (match_operand:SWI48 1 "register_operand")
9132 (match_dup 0)))
9133 (set (match_dup 1)
9134 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9135 (match_operand:SWI48 3 "register_operand")
9136 (match_dup 1)))]
9137 "TARGET_CMOVE"
9138 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9139
9140 (define_expand "x86_shift<mode>_adj_2"
9141 [(use (match_operand:SWI48 0 "register_operand"))
9142 (use (match_operand:SWI48 1 "register_operand"))
9143 (use (match_operand:QI 2 "register_operand"))]
9144 ""
9145 {
9146 rtx label = gen_label_rtx ();
9147 rtx tmp;
9148
9149 emit_insn (gen_testqi_ccz_1 (operands[2],
9150 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9151
9152 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9153 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9154 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9155 gen_rtx_LABEL_REF (VOIDmode, label),
9156 pc_rtx);
9157 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9158 JUMP_LABEL (tmp) = label;
9159
9160 emit_move_insn (operands[0], operands[1]);
9161 ix86_expand_clear (operands[1]);
9162
9163 emit_label (label);
9164 LABEL_NUSES (label) = 1;
9165
9166 DONE;
9167 })
9168
9169 ;; Avoid useless masking of count operand.
9170 (define_insn "*ashl<mode>3_mask"
9171 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9172 (ashift:SWI48
9173 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9174 (subreg:QI
9175 (and:SI
9176 (match_operand:SI 2 "register_operand" "c")
9177 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9178 (clobber (reg:CC FLAGS_REG))]
9179 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9180 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9181 == GET_MODE_BITSIZE (<MODE>mode)-1"
9182 {
9183 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9184 }
9185 [(set_attr "type" "ishift")
9186 (set_attr "mode" "<MODE>")])
9187
9188 (define_insn "*bmi2_ashl<mode>3_1"
9189 [(set (match_operand:SWI48 0 "register_operand" "=r")
9190 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9191 (match_operand:SWI48 2 "register_operand" "r")))]
9192 "TARGET_BMI2"
9193 "shlx\t{%2, %1, %0|%0, %1, %2}"
9194 [(set_attr "type" "ishiftx")
9195 (set_attr "mode" "<MODE>")])
9196
9197 (define_insn "*ashl<mode>3_1"
9198 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9199 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9200 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9201 (clobber (reg:CC FLAGS_REG))]
9202 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9203 {
9204 switch (get_attr_type (insn))
9205 {
9206 case TYPE_LEA:
9207 case TYPE_ISHIFTX:
9208 return "#";
9209
9210 case TYPE_ALU:
9211 gcc_assert (operands[2] == const1_rtx);
9212 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9213 return "add{<imodesuffix>}\t%0, %0";
9214
9215 default:
9216 if (operands[2] == const1_rtx
9217 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9218 return "sal{<imodesuffix>}\t%0";
9219 else
9220 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9221 }
9222 }
9223 [(set_attr "isa" "*,*,bmi2")
9224 (set (attr "type")
9225 (cond [(eq_attr "alternative" "1")
9226 (const_string "lea")
9227 (eq_attr "alternative" "2")
9228 (const_string "ishiftx")
9229 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9230 (match_operand 0 "register_operand"))
9231 (match_operand 2 "const1_operand"))
9232 (const_string "alu")
9233 ]
9234 (const_string "ishift")))
9235 (set (attr "length_immediate")
9236 (if_then_else
9237 (ior (eq_attr "type" "alu")
9238 (and (eq_attr "type" "ishift")
9239 (and (match_operand 2 "const1_operand")
9240 (ior (match_test "TARGET_SHIFT1")
9241 (match_test "optimize_function_for_size_p (cfun)")))))
9242 (const_string "0")
9243 (const_string "*")))
9244 (set_attr "mode" "<MODE>")])
9245
9246 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9247 (define_split
9248 [(set (match_operand:SWI48 0 "register_operand")
9249 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9250 (match_operand:QI 2 "register_operand")))
9251 (clobber (reg:CC FLAGS_REG))]
9252 "TARGET_BMI2 && reload_completed"
9253 [(set (match_dup 0)
9254 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9255 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9256
9257 (define_insn "*bmi2_ashlsi3_1_zext"
9258 [(set (match_operand:DI 0 "register_operand" "=r")
9259 (zero_extend:DI
9260 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9261 (match_operand:SI 2 "register_operand" "r"))))]
9262 "TARGET_64BIT && TARGET_BMI2"
9263 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9264 [(set_attr "type" "ishiftx")
9265 (set_attr "mode" "SI")])
9266
9267 (define_insn "*ashlsi3_1_zext"
9268 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9269 (zero_extend:DI
9270 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9271 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9272 (clobber (reg:CC FLAGS_REG))]
9273 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9274 {
9275 switch (get_attr_type (insn))
9276 {
9277 case TYPE_LEA:
9278 case TYPE_ISHIFTX:
9279 return "#";
9280
9281 case TYPE_ALU:
9282 gcc_assert (operands[2] == const1_rtx);
9283 return "add{l}\t%k0, %k0";
9284
9285 default:
9286 if (operands[2] == const1_rtx
9287 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9288 return "sal{l}\t%k0";
9289 else
9290 return "sal{l}\t{%2, %k0|%k0, %2}";
9291 }
9292 }
9293 [(set_attr "isa" "*,*,bmi2")
9294 (set (attr "type")
9295 (cond [(eq_attr "alternative" "1")
9296 (const_string "lea")
9297 (eq_attr "alternative" "2")
9298 (const_string "ishiftx")
9299 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9300 (match_operand 2 "const1_operand"))
9301 (const_string "alu")
9302 ]
9303 (const_string "ishift")))
9304 (set (attr "length_immediate")
9305 (if_then_else
9306 (ior (eq_attr "type" "alu")
9307 (and (eq_attr "type" "ishift")
9308 (and (match_operand 2 "const1_operand")
9309 (ior (match_test "TARGET_SHIFT1")
9310 (match_test "optimize_function_for_size_p (cfun)")))))
9311 (const_string "0")
9312 (const_string "*")))
9313 (set_attr "mode" "SI")])
9314
9315 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9316 (define_split
9317 [(set (match_operand:DI 0 "register_operand")
9318 (zero_extend:DI
9319 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9320 (match_operand:QI 2 "register_operand"))))
9321 (clobber (reg:CC FLAGS_REG))]
9322 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9323 [(set (match_dup 0)
9324 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9325 "operands[2] = gen_lowpart (SImode, operands[2]);")
9326
9327 (define_insn "*ashlhi3_1"
9328 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9329 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9330 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9331 (clobber (reg:CC FLAGS_REG))]
9332 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9333 {
9334 switch (get_attr_type (insn))
9335 {
9336 case TYPE_LEA:
9337 return "#";
9338
9339 case TYPE_ALU:
9340 gcc_assert (operands[2] == const1_rtx);
9341 return "add{w}\t%0, %0";
9342
9343 default:
9344 if (operands[2] == const1_rtx
9345 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9346 return "sal{w}\t%0";
9347 else
9348 return "sal{w}\t{%2, %0|%0, %2}";
9349 }
9350 }
9351 [(set (attr "type")
9352 (cond [(eq_attr "alternative" "1")
9353 (const_string "lea")
9354 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9355 (match_operand 0 "register_operand"))
9356 (match_operand 2 "const1_operand"))
9357 (const_string "alu")
9358 ]
9359 (const_string "ishift")))
9360 (set (attr "length_immediate")
9361 (if_then_else
9362 (ior (eq_attr "type" "alu")
9363 (and (eq_attr "type" "ishift")
9364 (and (match_operand 2 "const1_operand")
9365 (ior (match_test "TARGET_SHIFT1")
9366 (match_test "optimize_function_for_size_p (cfun)")))))
9367 (const_string "0")
9368 (const_string "*")))
9369 (set_attr "mode" "HI,SI")])
9370
9371 ;; %%% Potential partial reg stall on alternative 1. What to do?
9372 (define_insn "*ashlqi3_1"
9373 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9374 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9375 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9376 (clobber (reg:CC FLAGS_REG))]
9377 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9378 {
9379 switch (get_attr_type (insn))
9380 {
9381 case TYPE_LEA:
9382 return "#";
9383
9384 case TYPE_ALU:
9385 gcc_assert (operands[2] == const1_rtx);
9386 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9387 return "add{l}\t%k0, %k0";
9388 else
9389 return "add{b}\t%0, %0";
9390
9391 default:
9392 if (operands[2] == const1_rtx
9393 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9394 {
9395 if (get_attr_mode (insn) == MODE_SI)
9396 return "sal{l}\t%k0";
9397 else
9398 return "sal{b}\t%0";
9399 }
9400 else
9401 {
9402 if (get_attr_mode (insn) == MODE_SI)
9403 return "sal{l}\t{%2, %k0|%k0, %2}";
9404 else
9405 return "sal{b}\t{%2, %0|%0, %2}";
9406 }
9407 }
9408 }
9409 [(set (attr "type")
9410 (cond [(eq_attr "alternative" "2")
9411 (const_string "lea")
9412 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9413 (match_operand 0 "register_operand"))
9414 (match_operand 2 "const1_operand"))
9415 (const_string "alu")
9416 ]
9417 (const_string "ishift")))
9418 (set (attr "length_immediate")
9419 (if_then_else
9420 (ior (eq_attr "type" "alu")
9421 (and (eq_attr "type" "ishift")
9422 (and (match_operand 2 "const1_operand")
9423 (ior (match_test "TARGET_SHIFT1")
9424 (match_test "optimize_function_for_size_p (cfun)")))))
9425 (const_string "0")
9426 (const_string "*")))
9427 (set_attr "mode" "QI,SI,SI")])
9428
9429 (define_insn "*ashlqi3_1_slp"
9430 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9431 (ashift:QI (match_dup 0)
9432 (match_operand:QI 1 "nonmemory_operand" "cI")))
9433 (clobber (reg:CC FLAGS_REG))]
9434 "(optimize_function_for_size_p (cfun)
9435 || !TARGET_PARTIAL_FLAG_REG_STALL
9436 || (operands[1] == const1_rtx
9437 && (TARGET_SHIFT1
9438 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9439 {
9440 switch (get_attr_type (insn))
9441 {
9442 case TYPE_ALU:
9443 gcc_assert (operands[1] == const1_rtx);
9444 return "add{b}\t%0, %0";
9445
9446 default:
9447 if (operands[1] == const1_rtx
9448 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9449 return "sal{b}\t%0";
9450 else
9451 return "sal{b}\t{%1, %0|%0, %1}";
9452 }
9453 }
9454 [(set (attr "type")
9455 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9456 (match_operand 0 "register_operand"))
9457 (match_operand 1 "const1_operand"))
9458 (const_string "alu")
9459 ]
9460 (const_string "ishift1")))
9461 (set (attr "length_immediate")
9462 (if_then_else
9463 (ior (eq_attr "type" "alu")
9464 (and (eq_attr "type" "ishift1")
9465 (and (match_operand 1 "const1_operand")
9466 (ior (match_test "TARGET_SHIFT1")
9467 (match_test "optimize_function_for_size_p (cfun)")))))
9468 (const_string "0")
9469 (const_string "*")))
9470 (set_attr "mode" "QI")])
9471
9472 ;; Convert ashift to the lea pattern to avoid flags dependency.
9473 (define_split
9474 [(set (match_operand 0 "register_operand")
9475 (ashift (match_operand 1 "index_register_operand")
9476 (match_operand:QI 2 "const_int_operand")))
9477 (clobber (reg:CC FLAGS_REG))]
9478 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9479 && reload_completed
9480 && true_regnum (operands[0]) != true_regnum (operands[1])"
9481 [(const_int 0)]
9482 {
9483 enum machine_mode mode = GET_MODE (operands[0]);
9484 rtx pat;
9485
9486 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9487 {
9488 mode = SImode;
9489 operands[0] = gen_lowpart (mode, operands[0]);
9490 operands[1] = gen_lowpart (mode, operands[1]);
9491 }
9492
9493 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9494
9495 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9496
9497 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9498 DONE;
9499 })
9500
9501 ;; Convert ashift to the lea pattern to avoid flags dependency.
9502 (define_split
9503 [(set (match_operand:DI 0 "register_operand")
9504 (zero_extend:DI
9505 (ashift:SI (match_operand:SI 1 "index_register_operand")
9506 (match_operand:QI 2 "const_int_operand"))))
9507 (clobber (reg:CC FLAGS_REG))]
9508 "TARGET_64BIT && reload_completed
9509 && true_regnum (operands[0]) != true_regnum (operands[1])"
9510 [(set (match_dup 0)
9511 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9512 {
9513 operands[1] = gen_lowpart (SImode, operands[1]);
9514 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9515 })
9516
9517 ;; This pattern can't accept a variable shift count, since shifts by
9518 ;; zero don't affect the flags. We assume that shifts by constant
9519 ;; zero are optimized away.
9520 (define_insn "*ashl<mode>3_cmp"
9521 [(set (reg FLAGS_REG)
9522 (compare
9523 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9524 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9525 (const_int 0)))
9526 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9527 (ashift:SWI (match_dup 1) (match_dup 2)))]
9528 "(optimize_function_for_size_p (cfun)
9529 || !TARGET_PARTIAL_FLAG_REG_STALL
9530 || (operands[2] == const1_rtx
9531 && (TARGET_SHIFT1
9532 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9533 && ix86_match_ccmode (insn, CCGOCmode)
9534 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9535 {
9536 switch (get_attr_type (insn))
9537 {
9538 case TYPE_ALU:
9539 gcc_assert (operands[2] == const1_rtx);
9540 return "add{<imodesuffix>}\t%0, %0";
9541
9542 default:
9543 if (operands[2] == const1_rtx
9544 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9545 return "sal{<imodesuffix>}\t%0";
9546 else
9547 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9548 }
9549 }
9550 [(set (attr "type")
9551 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9552 (match_operand 0 "register_operand"))
9553 (match_operand 2 "const1_operand"))
9554 (const_string "alu")
9555 ]
9556 (const_string "ishift")))
9557 (set (attr "length_immediate")
9558 (if_then_else
9559 (ior (eq_attr "type" "alu")
9560 (and (eq_attr "type" "ishift")
9561 (and (match_operand 2 "const1_operand")
9562 (ior (match_test "TARGET_SHIFT1")
9563 (match_test "optimize_function_for_size_p (cfun)")))))
9564 (const_string "0")
9565 (const_string "*")))
9566 (set_attr "mode" "<MODE>")])
9567
9568 (define_insn "*ashlsi3_cmp_zext"
9569 [(set (reg FLAGS_REG)
9570 (compare
9571 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9572 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9573 (const_int 0)))
9574 (set (match_operand:DI 0 "register_operand" "=r")
9575 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9576 "TARGET_64BIT
9577 && (optimize_function_for_size_p (cfun)
9578 || !TARGET_PARTIAL_FLAG_REG_STALL
9579 || (operands[2] == const1_rtx
9580 && (TARGET_SHIFT1
9581 || TARGET_DOUBLE_WITH_ADD)))
9582 && ix86_match_ccmode (insn, CCGOCmode)
9583 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9584 {
9585 switch (get_attr_type (insn))
9586 {
9587 case TYPE_ALU:
9588 gcc_assert (operands[2] == const1_rtx);
9589 return "add{l}\t%k0, %k0";
9590
9591 default:
9592 if (operands[2] == const1_rtx
9593 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9594 return "sal{l}\t%k0";
9595 else
9596 return "sal{l}\t{%2, %k0|%k0, %2}";
9597 }
9598 }
9599 [(set (attr "type")
9600 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9601 (match_operand 2 "const1_operand"))
9602 (const_string "alu")
9603 ]
9604 (const_string "ishift")))
9605 (set (attr "length_immediate")
9606 (if_then_else
9607 (ior (eq_attr "type" "alu")
9608 (and (eq_attr "type" "ishift")
9609 (and (match_operand 2 "const1_operand")
9610 (ior (match_test "TARGET_SHIFT1")
9611 (match_test "optimize_function_for_size_p (cfun)")))))
9612 (const_string "0")
9613 (const_string "*")))
9614 (set_attr "mode" "SI")])
9615
9616 (define_insn "*ashl<mode>3_cconly"
9617 [(set (reg FLAGS_REG)
9618 (compare
9619 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9620 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9621 (const_int 0)))
9622 (clobber (match_scratch:SWI 0 "=<r>"))]
9623 "(optimize_function_for_size_p (cfun)
9624 || !TARGET_PARTIAL_FLAG_REG_STALL
9625 || (operands[2] == const1_rtx
9626 && (TARGET_SHIFT1
9627 || TARGET_DOUBLE_WITH_ADD)))
9628 && ix86_match_ccmode (insn, CCGOCmode)"
9629 {
9630 switch (get_attr_type (insn))
9631 {
9632 case TYPE_ALU:
9633 gcc_assert (operands[2] == const1_rtx);
9634 return "add{<imodesuffix>}\t%0, %0";
9635
9636 default:
9637 if (operands[2] == const1_rtx
9638 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9639 return "sal{<imodesuffix>}\t%0";
9640 else
9641 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9642 }
9643 }
9644 [(set (attr "type")
9645 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9646 (match_operand 0 "register_operand"))
9647 (match_operand 2 "const1_operand"))
9648 (const_string "alu")
9649 ]
9650 (const_string "ishift")))
9651 (set (attr "length_immediate")
9652 (if_then_else
9653 (ior (eq_attr "type" "alu")
9654 (and (eq_attr "type" "ishift")
9655 (and (match_operand 2 "const1_operand")
9656 (ior (match_test "TARGET_SHIFT1")
9657 (match_test "optimize_function_for_size_p (cfun)")))))
9658 (const_string "0")
9659 (const_string "*")))
9660 (set_attr "mode" "<MODE>")])
9661
9662 ;; See comment above `ashl<mode>3' about how this works.
9663
9664 (define_expand "<shift_insn><mode>3"
9665 [(set (match_operand:SDWIM 0 "<shift_operand>")
9666 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9667 (match_operand:QI 2 "nonmemory_operand")))]
9668 ""
9669 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9670
9671 ;; Avoid useless masking of count operand.
9672 (define_insn "*<shift_insn><mode>3_mask"
9673 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9674 (any_shiftrt:SWI48
9675 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9676 (subreg:QI
9677 (and:SI
9678 (match_operand:SI 2 "register_operand" "c")
9679 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9680 (clobber (reg:CC FLAGS_REG))]
9681 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9682 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9683 == GET_MODE_BITSIZE (<MODE>mode)-1"
9684 {
9685 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9686 }
9687 [(set_attr "type" "ishift")
9688 (set_attr "mode" "<MODE>")])
9689
9690 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9691 [(set (match_operand:DWI 0 "register_operand" "=r")
9692 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9693 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9694 (clobber (reg:CC FLAGS_REG))]
9695 ""
9696 "#"
9697 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9698 [(const_int 0)]
9699 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9700 [(set_attr "type" "multi")])
9701
9702 ;; By default we don't ask for a scratch register, because when DWImode
9703 ;; values are manipulated, registers are already at a premium. But if
9704 ;; we have one handy, we won't turn it away.
9705
9706 (define_peephole2
9707 [(match_scratch:DWIH 3 "r")
9708 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9709 (any_shiftrt:<DWI>
9710 (match_operand:<DWI> 1 "register_operand")
9711 (match_operand:QI 2 "nonmemory_operand")))
9712 (clobber (reg:CC FLAGS_REG))])
9713 (match_dup 3)]
9714 "TARGET_CMOVE"
9715 [(const_int 0)]
9716 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9717
9718 (define_insn "x86_64_shrd"
9719 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9720 (ior:DI (ashiftrt:DI (match_dup 0)
9721 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9722 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9723 (minus:QI (const_int 64) (match_dup 2)))))
9724 (clobber (reg:CC FLAGS_REG))]
9725 "TARGET_64BIT"
9726 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9727 [(set_attr "type" "ishift")
9728 (set_attr "prefix_0f" "1")
9729 (set_attr "mode" "DI")
9730 (set_attr "athlon_decode" "vector")
9731 (set_attr "amdfam10_decode" "vector")
9732 (set_attr "bdver1_decode" "vector")])
9733
9734 (define_insn "x86_shrd"
9735 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9736 (ior:SI (ashiftrt:SI (match_dup 0)
9737 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9738 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9739 (minus:QI (const_int 32) (match_dup 2)))))
9740 (clobber (reg:CC FLAGS_REG))]
9741 ""
9742 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9743 [(set_attr "type" "ishift")
9744 (set_attr "prefix_0f" "1")
9745 (set_attr "mode" "SI")
9746 (set_attr "pent_pair" "np")
9747 (set_attr "athlon_decode" "vector")
9748 (set_attr "amdfam10_decode" "vector")
9749 (set_attr "bdver1_decode" "vector")])
9750
9751 (define_insn "ashrdi3_cvt"
9752 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9753 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9754 (match_operand:QI 2 "const_int_operand")))
9755 (clobber (reg:CC FLAGS_REG))]
9756 "TARGET_64BIT && INTVAL (operands[2]) == 63
9757 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9758 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9759 "@
9760 {cqto|cqo}
9761 sar{q}\t{%2, %0|%0, %2}"
9762 [(set_attr "type" "imovx,ishift")
9763 (set_attr "prefix_0f" "0,*")
9764 (set_attr "length_immediate" "0,*")
9765 (set_attr "modrm" "0,1")
9766 (set_attr "mode" "DI")])
9767
9768 (define_insn "ashrsi3_cvt"
9769 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9770 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9771 (match_operand:QI 2 "const_int_operand")))
9772 (clobber (reg:CC FLAGS_REG))]
9773 "INTVAL (operands[2]) == 31
9774 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9775 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9776 "@
9777 {cltd|cdq}
9778 sar{l}\t{%2, %0|%0, %2}"
9779 [(set_attr "type" "imovx,ishift")
9780 (set_attr "prefix_0f" "0,*")
9781 (set_attr "length_immediate" "0,*")
9782 (set_attr "modrm" "0,1")
9783 (set_attr "mode" "SI")])
9784
9785 (define_insn "*ashrsi3_cvt_zext"
9786 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9787 (zero_extend:DI
9788 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9789 (match_operand:QI 2 "const_int_operand"))))
9790 (clobber (reg:CC FLAGS_REG))]
9791 "TARGET_64BIT && INTVAL (operands[2]) == 31
9792 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9793 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9794 "@
9795 {cltd|cdq}
9796 sar{l}\t{%2, %k0|%k0, %2}"
9797 [(set_attr "type" "imovx,ishift")
9798 (set_attr "prefix_0f" "0,*")
9799 (set_attr "length_immediate" "0,*")
9800 (set_attr "modrm" "0,1")
9801 (set_attr "mode" "SI")])
9802
9803 (define_expand "x86_shift<mode>_adj_3"
9804 [(use (match_operand:SWI48 0 "register_operand"))
9805 (use (match_operand:SWI48 1 "register_operand"))
9806 (use (match_operand:QI 2 "register_operand"))]
9807 ""
9808 {
9809 rtx label = gen_label_rtx ();
9810 rtx tmp;
9811
9812 emit_insn (gen_testqi_ccz_1 (operands[2],
9813 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9814
9815 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9816 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9817 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9818 gen_rtx_LABEL_REF (VOIDmode, label),
9819 pc_rtx);
9820 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9821 JUMP_LABEL (tmp) = label;
9822
9823 emit_move_insn (operands[0], operands[1]);
9824 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9825 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9826 emit_label (label);
9827 LABEL_NUSES (label) = 1;
9828
9829 DONE;
9830 })
9831
9832 (define_insn "*bmi2_<shift_insn><mode>3_1"
9833 [(set (match_operand:SWI48 0 "register_operand" "=r")
9834 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9835 (match_operand:SWI48 2 "register_operand" "r")))]
9836 "TARGET_BMI2"
9837 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9838 [(set_attr "type" "ishiftx")
9839 (set_attr "mode" "<MODE>")])
9840
9841 (define_insn "*<shift_insn><mode>3_1"
9842 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9843 (any_shiftrt:SWI48
9844 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9845 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9846 (clobber (reg:CC FLAGS_REG))]
9847 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9848 {
9849 switch (get_attr_type (insn))
9850 {
9851 case TYPE_ISHIFTX:
9852 return "#";
9853
9854 default:
9855 if (operands[2] == const1_rtx
9856 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9857 return "<shift>{<imodesuffix>}\t%0";
9858 else
9859 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9860 }
9861 }
9862 [(set_attr "isa" "*,bmi2")
9863 (set_attr "type" "ishift,ishiftx")
9864 (set (attr "length_immediate")
9865 (if_then_else
9866 (and (match_operand 2 "const1_operand")
9867 (ior (match_test "TARGET_SHIFT1")
9868 (match_test "optimize_function_for_size_p (cfun)")))
9869 (const_string "0")
9870 (const_string "*")))
9871 (set_attr "mode" "<MODE>")])
9872
9873 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9874 (define_split
9875 [(set (match_operand:SWI48 0 "register_operand")
9876 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9877 (match_operand:QI 2 "register_operand")))
9878 (clobber (reg:CC FLAGS_REG))]
9879 "TARGET_BMI2 && reload_completed"
9880 [(set (match_dup 0)
9881 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9882 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9883
9884 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9885 [(set (match_operand:DI 0 "register_operand" "=r")
9886 (zero_extend:DI
9887 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9888 (match_operand:SI 2 "register_operand" "r"))))]
9889 "TARGET_64BIT && TARGET_BMI2"
9890 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9891 [(set_attr "type" "ishiftx")
9892 (set_attr "mode" "SI")])
9893
9894 (define_insn "*<shift_insn>si3_1_zext"
9895 [(set (match_operand:DI 0 "register_operand" "=r,r")
9896 (zero_extend:DI
9897 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9898 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9899 (clobber (reg:CC FLAGS_REG))]
9900 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9901 {
9902 switch (get_attr_type (insn))
9903 {
9904 case TYPE_ISHIFTX:
9905 return "#";
9906
9907 default:
9908 if (operands[2] == const1_rtx
9909 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9910 return "<shift>{l}\t%k0";
9911 else
9912 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9913 }
9914 }
9915 [(set_attr "isa" "*,bmi2")
9916 (set_attr "type" "ishift,ishiftx")
9917 (set (attr "length_immediate")
9918 (if_then_else
9919 (and (match_operand 2 "const1_operand")
9920 (ior (match_test "TARGET_SHIFT1")
9921 (match_test "optimize_function_for_size_p (cfun)")))
9922 (const_string "0")
9923 (const_string "*")))
9924 (set_attr "mode" "SI")])
9925
9926 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9927 (define_split
9928 [(set (match_operand:DI 0 "register_operand")
9929 (zero_extend:DI
9930 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9931 (match_operand:QI 2 "register_operand"))))
9932 (clobber (reg:CC FLAGS_REG))]
9933 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9934 [(set (match_dup 0)
9935 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9936 "operands[2] = gen_lowpart (SImode, operands[2]);")
9937
9938 (define_insn "*<shift_insn><mode>3_1"
9939 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9940 (any_shiftrt:SWI12
9941 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9942 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9943 (clobber (reg:CC FLAGS_REG))]
9944 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9945 {
9946 if (operands[2] == const1_rtx
9947 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9948 return "<shift>{<imodesuffix>}\t%0";
9949 else
9950 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9951 }
9952 [(set_attr "type" "ishift")
9953 (set (attr "length_immediate")
9954 (if_then_else
9955 (and (match_operand 2 "const1_operand")
9956 (ior (match_test "TARGET_SHIFT1")
9957 (match_test "optimize_function_for_size_p (cfun)")))
9958 (const_string "0")
9959 (const_string "*")))
9960 (set_attr "mode" "<MODE>")])
9961
9962 (define_insn "*<shift_insn>qi3_1_slp"
9963 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9964 (any_shiftrt:QI (match_dup 0)
9965 (match_operand:QI 1 "nonmemory_operand" "cI")))
9966 (clobber (reg:CC FLAGS_REG))]
9967 "(optimize_function_for_size_p (cfun)
9968 || !TARGET_PARTIAL_REG_STALL
9969 || (operands[1] == const1_rtx
9970 && TARGET_SHIFT1))"
9971 {
9972 if (operands[1] == const1_rtx
9973 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9974 return "<shift>{b}\t%0";
9975 else
9976 return "<shift>{b}\t{%1, %0|%0, %1}";
9977 }
9978 [(set_attr "type" "ishift1")
9979 (set (attr "length_immediate")
9980 (if_then_else
9981 (and (match_operand 1 "const1_operand")
9982 (ior (match_test "TARGET_SHIFT1")
9983 (match_test "optimize_function_for_size_p (cfun)")))
9984 (const_string "0")
9985 (const_string "*")))
9986 (set_attr "mode" "QI")])
9987
9988 ;; This pattern can't accept a variable shift count, since shifts by
9989 ;; zero don't affect the flags. We assume that shifts by constant
9990 ;; zero are optimized away.
9991 (define_insn "*<shift_insn><mode>3_cmp"
9992 [(set (reg FLAGS_REG)
9993 (compare
9994 (any_shiftrt:SWI
9995 (match_operand:SWI 1 "nonimmediate_operand" "0")
9996 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9997 (const_int 0)))
9998 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9999 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10000 "(optimize_function_for_size_p (cfun)
10001 || !TARGET_PARTIAL_FLAG_REG_STALL
10002 || (operands[2] == const1_rtx
10003 && TARGET_SHIFT1))
10004 && ix86_match_ccmode (insn, CCGOCmode)
10005 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10006 {
10007 if (operands[2] == const1_rtx
10008 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10009 return "<shift>{<imodesuffix>}\t%0";
10010 else
10011 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10012 }
10013 [(set_attr "type" "ishift")
10014 (set (attr "length_immediate")
10015 (if_then_else
10016 (and (match_operand 2 "const1_operand")
10017 (ior (match_test "TARGET_SHIFT1")
10018 (match_test "optimize_function_for_size_p (cfun)")))
10019 (const_string "0")
10020 (const_string "*")))
10021 (set_attr "mode" "<MODE>")])
10022
10023 (define_insn "*<shift_insn>si3_cmp_zext"
10024 [(set (reg FLAGS_REG)
10025 (compare
10026 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10027 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10028 (const_int 0)))
10029 (set (match_operand:DI 0 "register_operand" "=r")
10030 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10031 "TARGET_64BIT
10032 && (optimize_function_for_size_p (cfun)
10033 || !TARGET_PARTIAL_FLAG_REG_STALL
10034 || (operands[2] == const1_rtx
10035 && TARGET_SHIFT1))
10036 && ix86_match_ccmode (insn, CCGOCmode)
10037 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10038 {
10039 if (operands[2] == const1_rtx
10040 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10041 return "<shift>{l}\t%k0";
10042 else
10043 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10044 }
10045 [(set_attr "type" "ishift")
10046 (set (attr "length_immediate")
10047 (if_then_else
10048 (and (match_operand 2 "const1_operand")
10049 (ior (match_test "TARGET_SHIFT1")
10050 (match_test "optimize_function_for_size_p (cfun)")))
10051 (const_string "0")
10052 (const_string "*")))
10053 (set_attr "mode" "SI")])
10054
10055 (define_insn "*<shift_insn><mode>3_cconly"
10056 [(set (reg FLAGS_REG)
10057 (compare
10058 (any_shiftrt:SWI
10059 (match_operand:SWI 1 "register_operand" "0")
10060 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10061 (const_int 0)))
10062 (clobber (match_scratch:SWI 0 "=<r>"))]
10063 "(optimize_function_for_size_p (cfun)
10064 || !TARGET_PARTIAL_FLAG_REG_STALL
10065 || (operands[2] == const1_rtx
10066 && TARGET_SHIFT1))
10067 && ix86_match_ccmode (insn, CCGOCmode)"
10068 {
10069 if (operands[2] == const1_rtx
10070 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10071 return "<shift>{<imodesuffix>}\t%0";
10072 else
10073 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10074 }
10075 [(set_attr "type" "ishift")
10076 (set (attr "length_immediate")
10077 (if_then_else
10078 (and (match_operand 2 "const1_operand")
10079 (ior (match_test "TARGET_SHIFT1")
10080 (match_test "optimize_function_for_size_p (cfun)")))
10081 (const_string "0")
10082 (const_string "*")))
10083 (set_attr "mode" "<MODE>")])
10084 \f
10085 ;; Rotate instructions
10086
10087 (define_expand "<rotate_insn>ti3"
10088 [(set (match_operand:TI 0 "register_operand")
10089 (any_rotate:TI (match_operand:TI 1 "register_operand")
10090 (match_operand:QI 2 "nonmemory_operand")))]
10091 "TARGET_64BIT"
10092 {
10093 if (const_1_to_63_operand (operands[2], VOIDmode))
10094 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10095 (operands[0], operands[1], operands[2]));
10096 else
10097 FAIL;
10098
10099 DONE;
10100 })
10101
10102 (define_expand "<rotate_insn>di3"
10103 [(set (match_operand:DI 0 "shiftdi_operand")
10104 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10105 (match_operand:QI 2 "nonmemory_operand")))]
10106 ""
10107 {
10108 if (TARGET_64BIT)
10109 ix86_expand_binary_operator (<CODE>, DImode, operands);
10110 else if (const_1_to_31_operand (operands[2], VOIDmode))
10111 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10112 (operands[0], operands[1], operands[2]));
10113 else
10114 FAIL;
10115
10116 DONE;
10117 })
10118
10119 (define_expand "<rotate_insn><mode>3"
10120 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10121 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10122 (match_operand:QI 2 "nonmemory_operand")))]
10123 ""
10124 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10125
10126 ;; Avoid useless masking of count operand.
10127 (define_insn "*<rotate_insn><mode>3_mask"
10128 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10129 (any_rotate:SWI48
10130 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10131 (subreg:QI
10132 (and:SI
10133 (match_operand:SI 2 "register_operand" "c")
10134 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10135 (clobber (reg:CC FLAGS_REG))]
10136 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10137 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10138 == GET_MODE_BITSIZE (<MODE>mode)-1"
10139 {
10140 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10141 }
10142 [(set_attr "type" "rotate")
10143 (set_attr "mode" "<MODE>")])
10144
10145 ;; Implement rotation using two double-precision
10146 ;; shift instructions and a scratch register.
10147
10148 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10149 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10150 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10151 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10152 (clobber (reg:CC FLAGS_REG))
10153 (clobber (match_scratch:DWIH 3 "=&r"))]
10154 ""
10155 "#"
10156 "reload_completed"
10157 [(set (match_dup 3) (match_dup 4))
10158 (parallel
10159 [(set (match_dup 4)
10160 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10161 (lshiftrt:DWIH (match_dup 5)
10162 (minus:QI (match_dup 6) (match_dup 2)))))
10163 (clobber (reg:CC FLAGS_REG))])
10164 (parallel
10165 [(set (match_dup 5)
10166 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10167 (lshiftrt:DWIH (match_dup 3)
10168 (minus:QI (match_dup 6) (match_dup 2)))))
10169 (clobber (reg:CC FLAGS_REG))])]
10170 {
10171 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10172
10173 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10174 })
10175
10176 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10177 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10178 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10179 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10180 (clobber (reg:CC FLAGS_REG))
10181 (clobber (match_scratch:DWIH 3 "=&r"))]
10182 ""
10183 "#"
10184 "reload_completed"
10185 [(set (match_dup 3) (match_dup 4))
10186 (parallel
10187 [(set (match_dup 4)
10188 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10189 (ashift:DWIH (match_dup 5)
10190 (minus:QI (match_dup 6) (match_dup 2)))))
10191 (clobber (reg:CC FLAGS_REG))])
10192 (parallel
10193 [(set (match_dup 5)
10194 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10195 (ashift:DWIH (match_dup 3)
10196 (minus:QI (match_dup 6) (match_dup 2)))))
10197 (clobber (reg:CC FLAGS_REG))])]
10198 {
10199 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10200
10201 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10202 })
10203
10204 (define_insn "*bmi2_rorx<mode>3_1"
10205 [(set (match_operand:SWI48 0 "register_operand" "=r")
10206 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10207 (match_operand:QI 2 "immediate_operand" "<S>")))]
10208 "TARGET_BMI2"
10209 "rorx\t{%2, %1, %0|%0, %1, %2}"
10210 [(set_attr "type" "rotatex")
10211 (set_attr "mode" "<MODE>")])
10212
10213 (define_insn "*<rotate_insn><mode>3_1"
10214 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10215 (any_rotate:SWI48
10216 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10217 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10218 (clobber (reg:CC FLAGS_REG))]
10219 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10220 {
10221 switch (get_attr_type (insn))
10222 {
10223 case TYPE_ROTATEX:
10224 return "#";
10225
10226 default:
10227 if (operands[2] == const1_rtx
10228 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10229 return "<rotate>{<imodesuffix>}\t%0";
10230 else
10231 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10232 }
10233 }
10234 [(set_attr "isa" "*,bmi2")
10235 (set_attr "type" "rotate,rotatex")
10236 (set (attr "length_immediate")
10237 (if_then_else
10238 (and (eq_attr "type" "rotate")
10239 (and (match_operand 2 "const1_operand")
10240 (ior (match_test "TARGET_SHIFT1")
10241 (match_test "optimize_function_for_size_p (cfun)"))))
10242 (const_string "0")
10243 (const_string "*")))
10244 (set_attr "mode" "<MODE>")])
10245
10246 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10247 (define_split
10248 [(set (match_operand:SWI48 0 "register_operand")
10249 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10250 (match_operand:QI 2 "immediate_operand")))
10251 (clobber (reg:CC FLAGS_REG))]
10252 "TARGET_BMI2 && reload_completed"
10253 [(set (match_dup 0)
10254 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10255 {
10256 operands[2]
10257 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10258 })
10259
10260 (define_split
10261 [(set (match_operand:SWI48 0 "register_operand")
10262 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10263 (match_operand:QI 2 "immediate_operand")))
10264 (clobber (reg:CC FLAGS_REG))]
10265 "TARGET_BMI2 && reload_completed"
10266 [(set (match_dup 0)
10267 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10268
10269 (define_insn "*bmi2_rorxsi3_1_zext"
10270 [(set (match_operand:DI 0 "register_operand" "=r")
10271 (zero_extend:DI
10272 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10273 (match_operand:QI 2 "immediate_operand" "I"))))]
10274 "TARGET_64BIT && TARGET_BMI2"
10275 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10276 [(set_attr "type" "rotatex")
10277 (set_attr "mode" "SI")])
10278
10279 (define_insn "*<rotate_insn>si3_1_zext"
10280 [(set (match_operand:DI 0 "register_operand" "=r,r")
10281 (zero_extend:DI
10282 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10283 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10284 (clobber (reg:CC FLAGS_REG))]
10285 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10286 {
10287 switch (get_attr_type (insn))
10288 {
10289 case TYPE_ROTATEX:
10290 return "#";
10291
10292 default:
10293 if (operands[2] == const1_rtx
10294 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10295 return "<rotate>{l}\t%k0";
10296 else
10297 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10298 }
10299 }
10300 [(set_attr "isa" "*,bmi2")
10301 (set_attr "type" "rotate,rotatex")
10302 (set (attr "length_immediate")
10303 (if_then_else
10304 (and (eq_attr "type" "rotate")
10305 (and (match_operand 2 "const1_operand")
10306 (ior (match_test "TARGET_SHIFT1")
10307 (match_test "optimize_function_for_size_p (cfun)"))))
10308 (const_string "0")
10309 (const_string "*")))
10310 (set_attr "mode" "SI")])
10311
10312 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10313 (define_split
10314 [(set (match_operand:DI 0 "register_operand")
10315 (zero_extend:DI
10316 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10317 (match_operand:QI 2 "immediate_operand"))))
10318 (clobber (reg:CC FLAGS_REG))]
10319 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10320 [(set (match_dup 0)
10321 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10322 {
10323 operands[2]
10324 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10325 })
10326
10327 (define_split
10328 [(set (match_operand:DI 0 "register_operand")
10329 (zero_extend:DI
10330 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10331 (match_operand:QI 2 "immediate_operand"))))
10332 (clobber (reg:CC FLAGS_REG))]
10333 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10334 [(set (match_dup 0)
10335 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10336
10337 (define_insn "*<rotate_insn><mode>3_1"
10338 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10339 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10340 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10341 (clobber (reg:CC FLAGS_REG))]
10342 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10343 {
10344 if (operands[2] == const1_rtx
10345 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10346 return "<rotate>{<imodesuffix>}\t%0";
10347 else
10348 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10349 }
10350 [(set_attr "type" "rotate")
10351 (set (attr "length_immediate")
10352 (if_then_else
10353 (and (match_operand 2 "const1_operand")
10354 (ior (match_test "TARGET_SHIFT1")
10355 (match_test "optimize_function_for_size_p (cfun)")))
10356 (const_string "0")
10357 (const_string "*")))
10358 (set_attr "mode" "<MODE>")])
10359
10360 (define_insn "*<rotate_insn>qi3_1_slp"
10361 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10362 (any_rotate:QI (match_dup 0)
10363 (match_operand:QI 1 "nonmemory_operand" "cI")))
10364 (clobber (reg:CC FLAGS_REG))]
10365 "(optimize_function_for_size_p (cfun)
10366 || !TARGET_PARTIAL_REG_STALL
10367 || (operands[1] == const1_rtx
10368 && TARGET_SHIFT1))"
10369 {
10370 if (operands[1] == const1_rtx
10371 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10372 return "<rotate>{b}\t%0";
10373 else
10374 return "<rotate>{b}\t{%1, %0|%0, %1}";
10375 }
10376 [(set_attr "type" "rotate1")
10377 (set (attr "length_immediate")
10378 (if_then_else
10379 (and (match_operand 1 "const1_operand")
10380 (ior (match_test "TARGET_SHIFT1")
10381 (match_test "optimize_function_for_size_p (cfun)")))
10382 (const_string "0")
10383 (const_string "*")))
10384 (set_attr "mode" "QI")])
10385
10386 (define_split
10387 [(set (match_operand:HI 0 "register_operand")
10388 (any_rotate:HI (match_dup 0) (const_int 8)))
10389 (clobber (reg:CC FLAGS_REG))]
10390 "reload_completed
10391 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10392 [(parallel [(set (strict_low_part (match_dup 0))
10393 (bswap:HI (match_dup 0)))
10394 (clobber (reg:CC FLAGS_REG))])])
10395 \f
10396 ;; Bit set / bit test instructions
10397
10398 (define_expand "extv"
10399 [(set (match_operand:SI 0 "register_operand")
10400 (sign_extract:SI (match_operand:SI 1 "register_operand")
10401 (match_operand:SI 2 "const8_operand")
10402 (match_operand:SI 3 "const8_operand")))]
10403 ""
10404 {
10405 /* Handle extractions from %ah et al. */
10406 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10407 FAIL;
10408
10409 /* From mips.md: extract_bit_field doesn't verify that our source
10410 matches the predicate, so check it again here. */
10411 if (! ext_register_operand (operands[1], VOIDmode))
10412 FAIL;
10413 })
10414
10415 (define_expand "extzv"
10416 [(set (match_operand:SI 0 "register_operand")
10417 (zero_extract:SI (match_operand 1 "ext_register_operand")
10418 (match_operand:SI 2 "const8_operand")
10419 (match_operand:SI 3 "const8_operand")))]
10420 ""
10421 {
10422 /* Handle extractions from %ah et al. */
10423 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10424 FAIL;
10425
10426 /* From mips.md: extract_bit_field doesn't verify that our source
10427 matches the predicate, so check it again here. */
10428 if (! ext_register_operand (operands[1], VOIDmode))
10429 FAIL;
10430 })
10431
10432 (define_expand "insv"
10433 [(set (zero_extract (match_operand 0 "register_operand")
10434 (match_operand 1 "const_int_operand")
10435 (match_operand 2 "const_int_operand"))
10436 (match_operand 3 "register_operand"))]
10437 ""
10438 {
10439 rtx (*gen_mov_insv_1) (rtx, rtx);
10440
10441 if (ix86_expand_pinsr (operands))
10442 DONE;
10443
10444 /* Handle insertions to %ah et al. */
10445 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10446 FAIL;
10447
10448 /* From mips.md: insert_bit_field doesn't verify that our source
10449 matches the predicate, so check it again here. */
10450 if (! ext_register_operand (operands[0], VOIDmode))
10451 FAIL;
10452
10453 gen_mov_insv_1 = (TARGET_64BIT
10454 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10455
10456 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10457 DONE;
10458 })
10459
10460 ;; %%% bts, btr, btc, bt.
10461 ;; In general these instructions are *slow* when applied to memory,
10462 ;; since they enforce atomic operation. When applied to registers,
10463 ;; it depends on the cpu implementation. They're never faster than
10464 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10465 ;; no point. But in 64-bit, we can't hold the relevant immediates
10466 ;; within the instruction itself, so operating on bits in the high
10467 ;; 32-bits of a register becomes easier.
10468 ;;
10469 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10470 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10471 ;; negdf respectively, so they can never be disabled entirely.
10472
10473 (define_insn "*btsq"
10474 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10475 (const_int 1)
10476 (match_operand:DI 1 "const_0_to_63_operand"))
10477 (const_int 1))
10478 (clobber (reg:CC FLAGS_REG))]
10479 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10480 "bts{q}\t{%1, %0|%0, %1}"
10481 [(set_attr "type" "alu1")
10482 (set_attr "prefix_0f" "1")
10483 (set_attr "mode" "DI")])
10484
10485 (define_insn "*btrq"
10486 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10487 (const_int 1)
10488 (match_operand:DI 1 "const_0_to_63_operand"))
10489 (const_int 0))
10490 (clobber (reg:CC FLAGS_REG))]
10491 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10492 "btr{q}\t{%1, %0|%0, %1}"
10493 [(set_attr "type" "alu1")
10494 (set_attr "prefix_0f" "1")
10495 (set_attr "mode" "DI")])
10496
10497 (define_insn "*btcq"
10498 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10499 (const_int 1)
10500 (match_operand:DI 1 "const_0_to_63_operand"))
10501 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10502 (clobber (reg:CC FLAGS_REG))]
10503 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10504 "btc{q}\t{%1, %0|%0, %1}"
10505 [(set_attr "type" "alu1")
10506 (set_attr "prefix_0f" "1")
10507 (set_attr "mode" "DI")])
10508
10509 ;; Allow Nocona to avoid these instructions if a register is available.
10510
10511 (define_peephole2
10512 [(match_scratch:DI 2 "r")
10513 (parallel [(set (zero_extract:DI
10514 (match_operand:DI 0 "register_operand")
10515 (const_int 1)
10516 (match_operand:DI 1 "const_0_to_63_operand"))
10517 (const_int 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_iordi3 (operands[0], operands[0], op1));
10540 DONE;
10541 })
10542
10543 (define_peephole2
10544 [(match_scratch:DI 2 "r")
10545 (parallel [(set (zero_extract:DI
10546 (match_operand:DI 0 "register_operand")
10547 (const_int 1)
10548 (match_operand:DI 1 "const_0_to_63_operand"))
10549 (const_int 0))
10550 (clobber (reg:CC FLAGS_REG))])]
10551 "TARGET_64BIT && !TARGET_USE_BT"
10552 [(const_int 0)]
10553 {
10554 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10555 rtx op1;
10556
10557 if (HOST_BITS_PER_WIDE_INT >= 64)
10558 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10559 else if (i < HOST_BITS_PER_WIDE_INT)
10560 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10561 else
10562 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10563
10564 op1 = immed_double_const (~lo, ~hi, DImode);
10565 if (i >= 32)
10566 {
10567 emit_move_insn (operands[2], op1);
10568 op1 = operands[2];
10569 }
10570
10571 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10572 DONE;
10573 })
10574
10575 (define_peephole2
10576 [(match_scratch:DI 2 "r")
10577 (parallel [(set (zero_extract:DI
10578 (match_operand:DI 0 "register_operand")
10579 (const_int 1)
10580 (match_operand:DI 1 "const_0_to_63_operand"))
10581 (not:DI (zero_extract:DI
10582 (match_dup 0) (const_int 1) (match_dup 1))))
10583 (clobber (reg:CC FLAGS_REG))])]
10584 "TARGET_64BIT && !TARGET_USE_BT"
10585 [(const_int 0)]
10586 {
10587 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10588 rtx op1;
10589
10590 if (HOST_BITS_PER_WIDE_INT >= 64)
10591 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10592 else if (i < HOST_BITS_PER_WIDE_INT)
10593 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10594 else
10595 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10596
10597 op1 = immed_double_const (lo, hi, DImode);
10598 if (i >= 31)
10599 {
10600 emit_move_insn (operands[2], op1);
10601 op1 = operands[2];
10602 }
10603
10604 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10605 DONE;
10606 })
10607
10608 (define_insn "*bt<mode>"
10609 [(set (reg:CCC FLAGS_REG)
10610 (compare:CCC
10611 (zero_extract:SWI48
10612 (match_operand:SWI48 0 "register_operand" "r")
10613 (const_int 1)
10614 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10615 (const_int 0)))]
10616 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10617 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10618 [(set_attr "type" "alu1")
10619 (set_attr "prefix_0f" "1")
10620 (set_attr "mode" "<MODE>")])
10621 \f
10622 ;; Store-flag instructions.
10623
10624 ;; For all sCOND expanders, also expand the compare or test insn that
10625 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10626
10627 (define_insn_and_split "*setcc_di_1"
10628 [(set (match_operand:DI 0 "register_operand" "=q")
10629 (match_operator:DI 1 "ix86_comparison_operator"
10630 [(reg FLAGS_REG) (const_int 0)]))]
10631 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10632 "#"
10633 "&& reload_completed"
10634 [(set (match_dup 2) (match_dup 1))
10635 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10636 {
10637 PUT_MODE (operands[1], QImode);
10638 operands[2] = gen_lowpart (QImode, operands[0]);
10639 })
10640
10641 (define_insn_and_split "*setcc_si_1_and"
10642 [(set (match_operand:SI 0 "register_operand" "=q")
10643 (match_operator:SI 1 "ix86_comparison_operator"
10644 [(reg FLAGS_REG) (const_int 0)]))
10645 (clobber (reg:CC FLAGS_REG))]
10646 "!TARGET_PARTIAL_REG_STALL
10647 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10648 "#"
10649 "&& reload_completed"
10650 [(set (match_dup 2) (match_dup 1))
10651 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10652 (clobber (reg:CC FLAGS_REG))])]
10653 {
10654 PUT_MODE (operands[1], QImode);
10655 operands[2] = gen_lowpart (QImode, operands[0]);
10656 })
10657
10658 (define_insn_and_split "*setcc_si_1_movzbl"
10659 [(set (match_operand:SI 0 "register_operand" "=q")
10660 (match_operator:SI 1 "ix86_comparison_operator"
10661 [(reg FLAGS_REG) (const_int 0)]))]
10662 "!TARGET_PARTIAL_REG_STALL
10663 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10664 "#"
10665 "&& reload_completed"
10666 [(set (match_dup 2) (match_dup 1))
10667 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10668 {
10669 PUT_MODE (operands[1], QImode);
10670 operands[2] = gen_lowpart (QImode, operands[0]);
10671 })
10672
10673 (define_insn "*setcc_qi"
10674 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10675 (match_operator:QI 1 "ix86_comparison_operator"
10676 [(reg FLAGS_REG) (const_int 0)]))]
10677 ""
10678 "set%C1\t%0"
10679 [(set_attr "type" "setcc")
10680 (set_attr "mode" "QI")])
10681
10682 (define_insn "*setcc_qi_slp"
10683 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10684 (match_operator:QI 1 "ix86_comparison_operator"
10685 [(reg FLAGS_REG) (const_int 0)]))]
10686 ""
10687 "set%C1\t%0"
10688 [(set_attr "type" "setcc")
10689 (set_attr "mode" "QI")])
10690
10691 ;; In general it is not safe to assume too much about CCmode registers,
10692 ;; so simplify-rtx stops when it sees a second one. Under certain
10693 ;; conditions this is safe on x86, so help combine not create
10694 ;;
10695 ;; seta %al
10696 ;; testb %al, %al
10697 ;; sete %al
10698
10699 (define_split
10700 [(set (match_operand:QI 0 "nonimmediate_operand")
10701 (ne:QI (match_operator 1 "ix86_comparison_operator"
10702 [(reg FLAGS_REG) (const_int 0)])
10703 (const_int 0)))]
10704 ""
10705 [(set (match_dup 0) (match_dup 1))]
10706 "PUT_MODE (operands[1], QImode);")
10707
10708 (define_split
10709 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10710 (ne:QI (match_operator 1 "ix86_comparison_operator"
10711 [(reg FLAGS_REG) (const_int 0)])
10712 (const_int 0)))]
10713 ""
10714 [(set (match_dup 0) (match_dup 1))]
10715 "PUT_MODE (operands[1], QImode);")
10716
10717 (define_split
10718 [(set (match_operand:QI 0 "nonimmediate_operand")
10719 (eq:QI (match_operator 1 "ix86_comparison_operator"
10720 [(reg FLAGS_REG) (const_int 0)])
10721 (const_int 0)))]
10722 ""
10723 [(set (match_dup 0) (match_dup 1))]
10724 {
10725 rtx new_op1 = copy_rtx (operands[1]);
10726 operands[1] = new_op1;
10727 PUT_MODE (new_op1, QImode);
10728 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10729 GET_MODE (XEXP (new_op1, 0))));
10730
10731 /* Make sure that (a) the CCmode we have for the flags is strong
10732 enough for the reversed compare or (b) we have a valid FP compare. */
10733 if (! ix86_comparison_operator (new_op1, VOIDmode))
10734 FAIL;
10735 })
10736
10737 (define_split
10738 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10739 (eq:QI (match_operator 1 "ix86_comparison_operator"
10740 [(reg FLAGS_REG) (const_int 0)])
10741 (const_int 0)))]
10742 ""
10743 [(set (match_dup 0) (match_dup 1))]
10744 {
10745 rtx new_op1 = copy_rtx (operands[1]);
10746 operands[1] = new_op1;
10747 PUT_MODE (new_op1, QImode);
10748 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10749 GET_MODE (XEXP (new_op1, 0))));
10750
10751 /* Make sure that (a) the CCmode we have for the flags is strong
10752 enough for the reversed compare or (b) we have a valid FP compare. */
10753 if (! ix86_comparison_operator (new_op1, VOIDmode))
10754 FAIL;
10755 })
10756
10757 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10758 ;; subsequent logical operations are used to imitate conditional moves.
10759 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10760 ;; it directly.
10761
10762 (define_insn "setcc_<mode>_sse"
10763 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10764 (match_operator:MODEF 3 "sse_comparison_operator"
10765 [(match_operand:MODEF 1 "register_operand" "0,x")
10766 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10767 "SSE_FLOAT_MODE_P (<MODE>mode)"
10768 "@
10769 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10770 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10771 [(set_attr "isa" "noavx,avx")
10772 (set_attr "type" "ssecmp")
10773 (set_attr "length_immediate" "1")
10774 (set_attr "prefix" "orig,vex")
10775 (set_attr "mode" "<MODE>")])
10776 \f
10777 ;; Basic conditional jump instructions.
10778 ;; We ignore the overflow flag for signed branch instructions.
10779
10780 (define_insn "*jcc_1"
10781 [(set (pc)
10782 (if_then_else (match_operator 1 "ix86_comparison_operator"
10783 [(reg FLAGS_REG) (const_int 0)])
10784 (label_ref (match_operand 0))
10785 (pc)))]
10786 ""
10787 "%!%+j%C1\t%l0"
10788 [(set_attr "type" "ibr")
10789 (set_attr "modrm" "0")
10790 (set (attr "length_nobnd")
10791 (if_then_else (and (ge (minus (match_dup 0) (pc))
10792 (const_int -126))
10793 (lt (minus (match_dup 0) (pc))
10794 (const_int 128)))
10795 (const_int 2)
10796 (const_int 6)))])
10797
10798 (define_insn "*jcc_2"
10799 [(set (pc)
10800 (if_then_else (match_operator 1 "ix86_comparison_operator"
10801 [(reg FLAGS_REG) (const_int 0)])
10802 (pc)
10803 (label_ref (match_operand 0))))]
10804 ""
10805 "%!%+j%c1\t%l0"
10806 [(set_attr "type" "ibr")
10807 (set_attr "modrm" "0")
10808 (set (attr "length_nobnd")
10809 (if_then_else (and (ge (minus (match_dup 0) (pc))
10810 (const_int -126))
10811 (lt (minus (match_dup 0) (pc))
10812 (const_int 128)))
10813 (const_int 2)
10814 (const_int 6)))])
10815
10816 ;; In general it is not safe to assume too much about CCmode registers,
10817 ;; so simplify-rtx stops when it sees a second one. Under certain
10818 ;; conditions this is safe on x86, so help combine not create
10819 ;;
10820 ;; seta %al
10821 ;; testb %al, %al
10822 ;; je Lfoo
10823
10824 (define_split
10825 [(set (pc)
10826 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10827 [(reg FLAGS_REG) (const_int 0)])
10828 (const_int 0))
10829 (label_ref (match_operand 1))
10830 (pc)))]
10831 ""
10832 [(set (pc)
10833 (if_then_else (match_dup 0)
10834 (label_ref (match_dup 1))
10835 (pc)))]
10836 "PUT_MODE (operands[0], VOIDmode);")
10837
10838 (define_split
10839 [(set (pc)
10840 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10841 [(reg FLAGS_REG) (const_int 0)])
10842 (const_int 0))
10843 (label_ref (match_operand 1))
10844 (pc)))]
10845 ""
10846 [(set (pc)
10847 (if_then_else (match_dup 0)
10848 (label_ref (match_dup 1))
10849 (pc)))]
10850 {
10851 rtx new_op0 = copy_rtx (operands[0]);
10852 operands[0] = new_op0;
10853 PUT_MODE (new_op0, VOIDmode);
10854 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10855 GET_MODE (XEXP (new_op0, 0))));
10856
10857 /* Make sure that (a) the CCmode we have for the flags is strong
10858 enough for the reversed compare or (b) we have a valid FP compare. */
10859 if (! ix86_comparison_operator (new_op0, VOIDmode))
10860 FAIL;
10861 })
10862
10863 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10864 ;; pass generates from shift insn with QImode operand. Actually, the mode
10865 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10866 ;; appropriate modulo of the bit offset value.
10867
10868 (define_insn_and_split "*jcc_bt<mode>"
10869 [(set (pc)
10870 (if_then_else (match_operator 0 "bt_comparison_operator"
10871 [(zero_extract:SWI48
10872 (match_operand:SWI48 1 "register_operand" "r")
10873 (const_int 1)
10874 (zero_extend:SI
10875 (match_operand:QI 2 "register_operand" "r")))
10876 (const_int 0)])
10877 (label_ref (match_operand 3))
10878 (pc)))
10879 (clobber (reg:CC FLAGS_REG))]
10880 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10881 "#"
10882 "&& 1"
10883 [(set (reg:CCC FLAGS_REG)
10884 (compare:CCC
10885 (zero_extract:SWI48
10886 (match_dup 1)
10887 (const_int 1)
10888 (match_dup 2))
10889 (const_int 0)))
10890 (set (pc)
10891 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10892 (label_ref (match_dup 3))
10893 (pc)))]
10894 {
10895 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10896
10897 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10898 })
10899
10900 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10901 ;; zero extended to SImode.
10902 (define_insn_and_split "*jcc_bt<mode>_1"
10903 [(set (pc)
10904 (if_then_else (match_operator 0 "bt_comparison_operator"
10905 [(zero_extract:SWI48
10906 (match_operand:SWI48 1 "register_operand" "r")
10907 (const_int 1)
10908 (match_operand:SI 2 "register_operand" "r"))
10909 (const_int 0)])
10910 (label_ref (match_operand 3))
10911 (pc)))
10912 (clobber (reg:CC FLAGS_REG))]
10913 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10914 "#"
10915 "&& 1"
10916 [(set (reg:CCC FLAGS_REG)
10917 (compare:CCC
10918 (zero_extract:SWI48
10919 (match_dup 1)
10920 (const_int 1)
10921 (match_dup 2))
10922 (const_int 0)))
10923 (set (pc)
10924 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10925 (label_ref (match_dup 3))
10926 (pc)))]
10927 {
10928 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10929
10930 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10931 })
10932
10933 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10934 ;; also for DImode, this is what combine produces.
10935 (define_insn_and_split "*jcc_bt<mode>_mask"
10936 [(set (pc)
10937 (if_then_else (match_operator 0 "bt_comparison_operator"
10938 [(zero_extract:SWI48
10939 (match_operand:SWI48 1 "register_operand" "r")
10940 (const_int 1)
10941 (and:SI
10942 (match_operand:SI 2 "register_operand" "r")
10943 (match_operand:SI 3 "const_int_operand" "n")))])
10944 (label_ref (match_operand 4))
10945 (pc)))
10946 (clobber (reg:CC FLAGS_REG))]
10947 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10948 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10949 == GET_MODE_BITSIZE (<MODE>mode)-1"
10950 "#"
10951 "&& 1"
10952 [(set (reg:CCC FLAGS_REG)
10953 (compare:CCC
10954 (zero_extract:SWI48
10955 (match_dup 1)
10956 (const_int 1)
10957 (match_dup 2))
10958 (const_int 0)))
10959 (set (pc)
10960 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10961 (label_ref (match_dup 4))
10962 (pc)))]
10963 {
10964 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10965
10966 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10967 })
10968
10969 (define_insn_and_split "*jcc_btsi_1"
10970 [(set (pc)
10971 (if_then_else (match_operator 0 "bt_comparison_operator"
10972 [(and:SI
10973 (lshiftrt:SI
10974 (match_operand:SI 1 "register_operand" "r")
10975 (match_operand:QI 2 "register_operand" "r"))
10976 (const_int 1))
10977 (const_int 0)])
10978 (label_ref (match_operand 3))
10979 (pc)))
10980 (clobber (reg:CC FLAGS_REG))]
10981 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10982 "#"
10983 "&& 1"
10984 [(set (reg:CCC FLAGS_REG)
10985 (compare:CCC
10986 (zero_extract:SI
10987 (match_dup 1)
10988 (const_int 1)
10989 (match_dup 2))
10990 (const_int 0)))
10991 (set (pc)
10992 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10993 (label_ref (match_dup 3))
10994 (pc)))]
10995 {
10996 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10997
10998 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10999 })
11000
11001 ;; avoid useless masking of bit offset operand
11002 (define_insn_and_split "*jcc_btsi_mask_1"
11003 [(set (pc)
11004 (if_then_else
11005 (match_operator 0 "bt_comparison_operator"
11006 [(and:SI
11007 (lshiftrt:SI
11008 (match_operand:SI 1 "register_operand" "r")
11009 (subreg:QI
11010 (and:SI
11011 (match_operand:SI 2 "register_operand" "r")
11012 (match_operand:SI 3 "const_int_operand" "n")) 0))
11013 (const_int 1))
11014 (const_int 0)])
11015 (label_ref (match_operand 4))
11016 (pc)))
11017 (clobber (reg:CC FLAGS_REG))]
11018 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11019 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11020 "#"
11021 "&& 1"
11022 [(set (reg:CCC FLAGS_REG)
11023 (compare:CCC
11024 (zero_extract:SI
11025 (match_dup 1)
11026 (const_int 1)
11027 (match_dup 2))
11028 (const_int 0)))
11029 (set (pc)
11030 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11031 (label_ref (match_dup 4))
11032 (pc)))]
11033 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11034
11035 ;; Define combination compare-and-branch fp compare instructions to help
11036 ;; combine.
11037
11038 (define_insn "*jcc<mode>_0_i387"
11039 [(set (pc)
11040 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11041 [(match_operand:X87MODEF 1 "register_operand" "f")
11042 (match_operand:X87MODEF 2 "const0_operand")])
11043 (label_ref (match_operand 3))
11044 (pc)))
11045 (clobber (reg:CCFP FPSR_REG))
11046 (clobber (reg:CCFP FLAGS_REG))
11047 (clobber (match_scratch:HI 4 "=a"))]
11048 "TARGET_80387 && !TARGET_CMOVE"
11049 "#")
11050
11051 (define_insn "*jcc<mode>_0_r_i387"
11052 [(set (pc)
11053 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11054 [(match_operand:X87MODEF 1 "register_operand" "f")
11055 (match_operand:X87MODEF 2 "const0_operand")])
11056 (pc)
11057 (label_ref (match_operand 3))))
11058 (clobber (reg:CCFP FPSR_REG))
11059 (clobber (reg:CCFP FLAGS_REG))
11060 (clobber (match_scratch:HI 4 "=a"))]
11061 "TARGET_80387 && !TARGET_CMOVE"
11062 "#")
11063
11064 (define_insn "*jccxf_i387"
11065 [(set (pc)
11066 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11067 [(match_operand:XF 1 "register_operand" "f")
11068 (match_operand:XF 2 "register_operand" "f")])
11069 (label_ref (match_operand 3))
11070 (pc)))
11071 (clobber (reg:CCFP FPSR_REG))
11072 (clobber (reg:CCFP FLAGS_REG))
11073 (clobber (match_scratch:HI 4 "=a"))]
11074 "TARGET_80387 && !TARGET_CMOVE"
11075 "#")
11076
11077 (define_insn "*jccxf_r_i387"
11078 [(set (pc)
11079 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11080 [(match_operand:XF 1 "register_operand" "f")
11081 (match_operand:XF 2 "register_operand" "f")])
11082 (pc)
11083 (label_ref (match_operand 3))))
11084 (clobber (reg:CCFP FPSR_REG))
11085 (clobber (reg:CCFP FLAGS_REG))
11086 (clobber (match_scratch:HI 4 "=a"))]
11087 "TARGET_80387 && !TARGET_CMOVE"
11088 "#")
11089
11090 (define_insn "*jcc<mode>_i387"
11091 [(set (pc)
11092 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11093 [(match_operand:MODEF 1 "register_operand" "f")
11094 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11095 (label_ref (match_operand 3))
11096 (pc)))
11097 (clobber (reg:CCFP FPSR_REG))
11098 (clobber (reg:CCFP FLAGS_REG))
11099 (clobber (match_scratch:HI 4 "=a"))]
11100 "TARGET_80387 && !TARGET_CMOVE"
11101 "#")
11102
11103 (define_insn "*jcc<mode>_r_i387"
11104 [(set (pc)
11105 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11106 [(match_operand:MODEF 1 "register_operand" "f")
11107 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11108 (pc)
11109 (label_ref (match_operand 3))))
11110 (clobber (reg:CCFP FPSR_REG))
11111 (clobber (reg:CCFP FLAGS_REG))
11112 (clobber (match_scratch:HI 4 "=a"))]
11113 "TARGET_80387 && !TARGET_CMOVE"
11114 "#")
11115
11116 (define_insn "*jccu<mode>_i387"
11117 [(set (pc)
11118 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11119 [(match_operand:X87MODEF 1 "register_operand" "f")
11120 (match_operand:X87MODEF 2 "register_operand" "f")])
11121 (label_ref (match_operand 3))
11122 (pc)))
11123 (clobber (reg:CCFP FPSR_REG))
11124 (clobber (reg:CCFP FLAGS_REG))
11125 (clobber (match_scratch:HI 4 "=a"))]
11126 "TARGET_80387 && !TARGET_CMOVE"
11127 "#")
11128
11129 (define_insn "*jccu<mode>_r_i387"
11130 [(set (pc)
11131 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11132 [(match_operand:X87MODEF 1 "register_operand" "f")
11133 (match_operand:X87MODEF 2 "register_operand" "f")])
11134 (pc)
11135 (label_ref (match_operand 3))))
11136 (clobber (reg:CCFP FPSR_REG))
11137 (clobber (reg:CCFP FLAGS_REG))
11138 (clobber (match_scratch:HI 4 "=a"))]
11139 "TARGET_80387 && !TARGET_CMOVE"
11140 "#")
11141
11142 (define_split
11143 [(set (pc)
11144 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11145 [(match_operand:X87MODEF 1 "register_operand")
11146 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11147 (match_operand 3)
11148 (match_operand 4)))
11149 (clobber (reg:CCFP FPSR_REG))
11150 (clobber (reg:CCFP FLAGS_REG))]
11151 "TARGET_80387 && !TARGET_CMOVE
11152 && reload_completed"
11153 [(const_int 0)]
11154 {
11155 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11156 operands[3], operands[4], NULL_RTX, NULL_RTX);
11157 DONE;
11158 })
11159
11160 (define_split
11161 [(set (pc)
11162 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11163 [(match_operand:X87MODEF 1 "register_operand")
11164 (match_operand:X87MODEF 2 "general_operand")])
11165 (match_operand 3)
11166 (match_operand 4)))
11167 (clobber (reg:CCFP FPSR_REG))
11168 (clobber (reg:CCFP FLAGS_REG))
11169 (clobber (match_scratch:HI 5))]
11170 "TARGET_80387 && !TARGET_CMOVE
11171 && reload_completed"
11172 [(const_int 0)]
11173 {
11174 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11175 operands[3], operands[4], operands[5], NULL_RTX);
11176 DONE;
11177 })
11178
11179 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11180 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11181 ;; with a precedence over other operators and is always put in the first
11182 ;; place. Swap condition and operands to match ficom instruction.
11183
11184 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11185 [(set (pc)
11186 (if_then_else
11187 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11188 [(match_operator:X87MODEF 1 "float_operator"
11189 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11190 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11191 (label_ref (match_operand 4))
11192 (pc)))
11193 (clobber (reg:CCFP FPSR_REG))
11194 (clobber (reg:CCFP FLAGS_REG))
11195 (clobber (match_scratch:HI 5 "=a,a"))]
11196 "TARGET_80387 && !TARGET_CMOVE
11197 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11198 || optimize_function_for_size_p (cfun))"
11199 "#")
11200
11201 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11202 [(set (pc)
11203 (if_then_else
11204 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11205 [(match_operator:X87MODEF 1 "float_operator"
11206 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11207 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11208 (pc)
11209 (label_ref (match_operand 4))))
11210 (clobber (reg:CCFP FPSR_REG))
11211 (clobber (reg:CCFP FLAGS_REG))
11212 (clobber (match_scratch:HI 5 "=a,a"))]
11213 "TARGET_80387 && !TARGET_CMOVE
11214 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11215 || optimize_function_for_size_p (cfun))"
11216 "#")
11217
11218 (define_split
11219 [(set (pc)
11220 (if_then_else
11221 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11222 [(match_operator:X87MODEF 1 "float_operator"
11223 [(match_operand:SWI24 2 "memory_operand")])
11224 (match_operand:X87MODEF 3 "register_operand")])
11225 (match_operand 4)
11226 (match_operand 5)))
11227 (clobber (reg:CCFP FPSR_REG))
11228 (clobber (reg:CCFP FLAGS_REG))
11229 (clobber (match_scratch:HI 6))]
11230 "TARGET_80387 && !TARGET_CMOVE
11231 && reload_completed"
11232 [(const_int 0)]
11233 {
11234 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11235 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11236 operands[4], operands[5], operands[6], NULL_RTX);
11237 DONE;
11238 })
11239
11240 ;; %%% Kill this when reload knows how to do it.
11241 (define_split
11242 [(set (pc)
11243 (if_then_else
11244 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11245 [(match_operator:X87MODEF 1 "float_operator"
11246 [(match_operand:SWI24 2 "register_operand")])
11247 (match_operand:X87MODEF 3 "register_operand")])
11248 (match_operand 4)
11249 (match_operand 5)))
11250 (clobber (reg:CCFP FPSR_REG))
11251 (clobber (reg:CCFP FLAGS_REG))
11252 (clobber (match_scratch:HI 6))]
11253 "TARGET_80387 && !TARGET_CMOVE
11254 && reload_completed"
11255 [(const_int 0)]
11256 {
11257 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11258
11259 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11260 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
11261 operands[4], operands[5], operands[6], operands[2]);
11262 DONE;
11263 })
11264 \f
11265 ;; Unconditional and other jump instructions
11266
11267 (define_insn "jump"
11268 [(set (pc)
11269 (label_ref (match_operand 0)))]
11270 ""
11271 "%!jmp\t%l0"
11272 [(set_attr "type" "ibr")
11273 (set (attr "length_nobnd")
11274 (if_then_else (and (ge (minus (match_dup 0) (pc))
11275 (const_int -126))
11276 (lt (minus (match_dup 0) (pc))
11277 (const_int 128)))
11278 (const_int 2)
11279 (const_int 5)))
11280 (set_attr "modrm" "0")])
11281
11282 (define_expand "indirect_jump"
11283 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11284 ""
11285 {
11286 if (TARGET_X32)
11287 operands[0] = convert_memory_address (word_mode, operands[0]);
11288 })
11289
11290 (define_insn "*indirect_jump"
11291 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11292 ""
11293 "%!jmp\t%A0"
11294 [(set_attr "type" "ibr")
11295 (set_attr "length_immediate" "0")])
11296
11297 (define_expand "tablejump"
11298 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11299 (use (label_ref (match_operand 1)))])]
11300 ""
11301 {
11302 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11303 relative. Convert the relative address to an absolute address. */
11304 if (flag_pic)
11305 {
11306 rtx op0, op1;
11307 enum rtx_code code;
11308
11309 /* We can't use @GOTOFF for text labels on VxWorks;
11310 see gotoff_operand. */
11311 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11312 {
11313 code = PLUS;
11314 op0 = operands[0];
11315 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11316 }
11317 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11318 {
11319 code = PLUS;
11320 op0 = operands[0];
11321 op1 = pic_offset_table_rtx;
11322 }
11323 else
11324 {
11325 code = MINUS;
11326 op0 = pic_offset_table_rtx;
11327 op1 = operands[0];
11328 }
11329
11330 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11331 OPTAB_DIRECT);
11332 }
11333
11334 if (TARGET_X32)
11335 operands[0] = convert_memory_address (word_mode, operands[0]);
11336 })
11337
11338 (define_insn "*tablejump_1"
11339 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11340 (use (label_ref (match_operand 1)))]
11341 ""
11342 "%!jmp\t%A0"
11343 [(set_attr "type" "ibr")
11344 (set_attr "length_immediate" "0")])
11345 \f
11346 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11347
11348 (define_peephole2
11349 [(set (reg FLAGS_REG) (match_operand 0))
11350 (set (match_operand:QI 1 "register_operand")
11351 (match_operator:QI 2 "ix86_comparison_operator"
11352 [(reg FLAGS_REG) (const_int 0)]))
11353 (set (match_operand 3 "q_regs_operand")
11354 (zero_extend (match_dup 1)))]
11355 "(peep2_reg_dead_p (3, operands[1])
11356 || operands_match_p (operands[1], operands[3]))
11357 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11358 [(set (match_dup 4) (match_dup 0))
11359 (set (strict_low_part (match_dup 5))
11360 (match_dup 2))]
11361 {
11362 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11363 operands[5] = gen_lowpart (QImode, operands[3]);
11364 ix86_expand_clear (operands[3]);
11365 })
11366
11367 (define_peephole2
11368 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11369 (match_operand 4)])
11370 (set (match_operand:QI 1 "register_operand")
11371 (match_operator:QI 2 "ix86_comparison_operator"
11372 [(reg FLAGS_REG) (const_int 0)]))
11373 (set (match_operand 3 "q_regs_operand")
11374 (zero_extend (match_dup 1)))]
11375 "(peep2_reg_dead_p (3, operands[1])
11376 || operands_match_p (operands[1], operands[3]))
11377 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11378 [(parallel [(set (match_dup 5) (match_dup 0))
11379 (match_dup 4)])
11380 (set (strict_low_part (match_dup 6))
11381 (match_dup 2))]
11382 {
11383 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11384 operands[6] = gen_lowpart (QImode, operands[3]);
11385 ix86_expand_clear (operands[3]);
11386 })
11387
11388 ;; Similar, but match zero extend with andsi3.
11389
11390 (define_peephole2
11391 [(set (reg FLAGS_REG) (match_operand 0))
11392 (set (match_operand:QI 1 "register_operand")
11393 (match_operator:QI 2 "ix86_comparison_operator"
11394 [(reg FLAGS_REG) (const_int 0)]))
11395 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11396 (and:SI (match_dup 3) (const_int 255)))
11397 (clobber (reg:CC FLAGS_REG))])]
11398 "REGNO (operands[1]) == REGNO (operands[3])
11399 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11400 [(set (match_dup 4) (match_dup 0))
11401 (set (strict_low_part (match_dup 5))
11402 (match_dup 2))]
11403 {
11404 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11405 operands[5] = gen_lowpart (QImode, operands[3]);
11406 ix86_expand_clear (operands[3]);
11407 })
11408
11409 (define_peephole2
11410 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11411 (match_operand 4)])
11412 (set (match_operand:QI 1 "register_operand")
11413 (match_operator:QI 2 "ix86_comparison_operator"
11414 [(reg FLAGS_REG) (const_int 0)]))
11415 (parallel [(set (match_operand 3 "q_regs_operand")
11416 (zero_extend (match_dup 1)))
11417 (clobber (reg:CC FLAGS_REG))])]
11418 "(peep2_reg_dead_p (3, operands[1])
11419 || operands_match_p (operands[1], operands[3]))
11420 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11421 [(parallel [(set (match_dup 5) (match_dup 0))
11422 (match_dup 4)])
11423 (set (strict_low_part (match_dup 6))
11424 (match_dup 2))]
11425 {
11426 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11427 operands[6] = gen_lowpart (QImode, operands[3]);
11428 ix86_expand_clear (operands[3]);
11429 })
11430 \f
11431 ;; Call instructions.
11432
11433 ;; The predicates normally associated with named expanders are not properly
11434 ;; checked for calls. This is a bug in the generic code, but it isn't that
11435 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11436
11437 ;; P6 processors will jump to the address after the decrement when %esp
11438 ;; is used as a call operand, so they will execute return address as a code.
11439 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11440
11441 ;; Register constraint for call instruction.
11442 (define_mode_attr c [(SI "l") (DI "r")])
11443
11444 ;; Call subroutine returning no value.
11445
11446 (define_expand "call"
11447 [(call (match_operand:QI 0)
11448 (match_operand 1))
11449 (use (match_operand 2))]
11450 ""
11451 {
11452 ix86_expand_call (NULL, operands[0], operands[1],
11453 operands[2], NULL, false);
11454 DONE;
11455 })
11456
11457 (define_expand "sibcall"
11458 [(call (match_operand:QI 0)
11459 (match_operand 1))
11460 (use (match_operand 2))]
11461 ""
11462 {
11463 ix86_expand_call (NULL, operands[0], operands[1],
11464 operands[2], NULL, true);
11465 DONE;
11466 })
11467
11468 (define_insn "*call"
11469 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11470 (match_operand 1))]
11471 "!SIBLING_CALL_P (insn)"
11472 "* return ix86_output_call_insn (insn, operands[0]);"
11473 [(set_attr "type" "call")])
11474
11475 (define_insn "*call_rex64_ms_sysv"
11476 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11477 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11478 (match_operand 1))
11479 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11480 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11481 "* return ix86_output_call_insn (insn, operands[0]);"
11482 [(set_attr "type" "call")])
11483
11484 (define_insn "*sibcall"
11485 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11486 (match_operand 1))]
11487 "SIBLING_CALL_P (insn)"
11488 "* return ix86_output_call_insn (insn, operands[0]);"
11489 [(set_attr "type" "call")])
11490
11491 (define_expand "call_pop"
11492 [(parallel [(call (match_operand:QI 0)
11493 (match_operand:SI 1))
11494 (set (reg:SI SP_REG)
11495 (plus:SI (reg:SI SP_REG)
11496 (match_operand:SI 3)))])]
11497 "!TARGET_64BIT"
11498 {
11499 ix86_expand_call (NULL, operands[0], operands[1],
11500 operands[2], operands[3], false);
11501 DONE;
11502 })
11503
11504 (define_insn "*call_pop"
11505 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11506 (match_operand 1))
11507 (set (reg:SI SP_REG)
11508 (plus:SI (reg:SI SP_REG)
11509 (match_operand:SI 2 "immediate_operand" "i")))]
11510 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11511 "* return ix86_output_call_insn (insn, operands[0]);"
11512 [(set_attr "type" "call")])
11513
11514 (define_insn "*sibcall_pop"
11515 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11516 (match_operand 1))
11517 (set (reg:SI SP_REG)
11518 (plus:SI (reg:SI SP_REG)
11519 (match_operand:SI 2 "immediate_operand" "i")))]
11520 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11521 "* return ix86_output_call_insn (insn, operands[0]);"
11522 [(set_attr "type" "call")])
11523
11524 ;; Call subroutine, returning value in operand 0
11525
11526 (define_expand "call_value"
11527 [(set (match_operand 0)
11528 (call (match_operand:QI 1)
11529 (match_operand 2)))
11530 (use (match_operand 3))]
11531 ""
11532 {
11533 ix86_expand_call (operands[0], operands[1], operands[2],
11534 operands[3], NULL, false);
11535 DONE;
11536 })
11537
11538 (define_expand "sibcall_value"
11539 [(set (match_operand 0)
11540 (call (match_operand:QI 1)
11541 (match_operand 2)))
11542 (use (match_operand 3))]
11543 ""
11544 {
11545 ix86_expand_call (operands[0], operands[1], operands[2],
11546 operands[3], NULL, true);
11547 DONE;
11548 })
11549
11550 (define_insn "*call_value"
11551 [(set (match_operand 0)
11552 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11553 (match_operand 2)))]
11554 "!SIBLING_CALL_P (insn)"
11555 "* return ix86_output_call_insn (insn, operands[1]);"
11556 [(set_attr "type" "callv")])
11557
11558 (define_insn "*sibcall_value"
11559 [(set (match_operand 0)
11560 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11561 (match_operand 2)))]
11562 "SIBLING_CALL_P (insn)"
11563 "* return ix86_output_call_insn (insn, operands[1]);"
11564 [(set_attr "type" "callv")])
11565
11566 (define_insn "*call_value_rex64_ms_sysv"
11567 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11568 [(set (match_operand 0)
11569 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11570 (match_operand 2)))
11571 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11572 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11573 "* return ix86_output_call_insn (insn, operands[1]);"
11574 [(set_attr "type" "callv")])
11575
11576 (define_expand "call_value_pop"
11577 [(parallel [(set (match_operand 0)
11578 (call (match_operand:QI 1)
11579 (match_operand:SI 2)))
11580 (set (reg:SI SP_REG)
11581 (plus:SI (reg:SI SP_REG)
11582 (match_operand:SI 4)))])]
11583 "!TARGET_64BIT"
11584 {
11585 ix86_expand_call (operands[0], operands[1], operands[2],
11586 operands[3], operands[4], false);
11587 DONE;
11588 })
11589
11590 (define_insn "*call_value_pop"
11591 [(set (match_operand 0)
11592 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11593 (match_operand 2)))
11594 (set (reg:SI SP_REG)
11595 (plus:SI (reg:SI SP_REG)
11596 (match_operand:SI 3 "immediate_operand" "i")))]
11597 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11598 "* return ix86_output_call_insn (insn, operands[1]);"
11599 [(set_attr "type" "callv")])
11600
11601 (define_insn "*sibcall_value_pop"
11602 [(set (match_operand 0)
11603 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11604 (match_operand 2)))
11605 (set (reg:SI SP_REG)
11606 (plus:SI (reg:SI SP_REG)
11607 (match_operand:SI 3 "immediate_operand" "i")))]
11608 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11609 "* return ix86_output_call_insn (insn, operands[1]);"
11610 [(set_attr "type" "callv")])
11611
11612 ;; Call subroutine returning any type.
11613
11614 (define_expand "untyped_call"
11615 [(parallel [(call (match_operand 0)
11616 (const_int 0))
11617 (match_operand 1)
11618 (match_operand 2)])]
11619 ""
11620 {
11621 int i;
11622
11623 /* In order to give reg-stack an easier job in validating two
11624 coprocessor registers as containing a possible return value,
11625 simply pretend the untyped call returns a complex long double
11626 value.
11627
11628 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11629 and should have the default ABI. */
11630
11631 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11632 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11633 operands[0], const0_rtx,
11634 GEN_INT ((TARGET_64BIT
11635 ? (ix86_abi == SYSV_ABI
11636 ? X86_64_SSE_REGPARM_MAX
11637 : X86_64_MS_SSE_REGPARM_MAX)
11638 : X86_32_SSE_REGPARM_MAX)
11639 - 1),
11640 NULL, false);
11641
11642 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11643 {
11644 rtx set = XVECEXP (operands[2], 0, i);
11645 emit_move_insn (SET_DEST (set), SET_SRC (set));
11646 }
11647
11648 /* The optimizer does not know that the call sets the function value
11649 registers we stored in the result block. We avoid problems by
11650 claiming that all hard registers are used and clobbered at this
11651 point. */
11652 emit_insn (gen_blockage ());
11653
11654 DONE;
11655 })
11656 \f
11657 ;; Prologue and epilogue instructions
11658
11659 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11660 ;; all of memory. This blocks insns from being moved across this point.
11661
11662 (define_insn "blockage"
11663 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11664 ""
11665 ""
11666 [(set_attr "length" "0")])
11667
11668 ;; Do not schedule instructions accessing memory across this point.
11669
11670 (define_expand "memory_blockage"
11671 [(set (match_dup 0)
11672 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11673 ""
11674 {
11675 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11676 MEM_VOLATILE_P (operands[0]) = 1;
11677 })
11678
11679 (define_insn "*memory_blockage"
11680 [(set (match_operand:BLK 0)
11681 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11682 ""
11683 ""
11684 [(set_attr "length" "0")])
11685
11686 ;; As USE insns aren't meaningful after reload, this is used instead
11687 ;; to prevent deleting instructions setting registers for PIC code
11688 (define_insn "prologue_use"
11689 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11690 ""
11691 ""
11692 [(set_attr "length" "0")])
11693
11694 ;; Insn emitted into the body of a function to return from a function.
11695 ;; This is only done if the function's epilogue is known to be simple.
11696 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11697
11698 (define_expand "return"
11699 [(simple_return)]
11700 "ix86_can_use_return_insn_p ()"
11701 {
11702 if (crtl->args.pops_args)
11703 {
11704 rtx popc = GEN_INT (crtl->args.pops_args);
11705 emit_jump_insn (gen_simple_return_pop_internal (popc));
11706 DONE;
11707 }
11708 })
11709
11710 ;; We need to disable this for TARGET_SEH, as otherwise
11711 ;; shrink-wrapped prologue gets enabled too. This might exceed
11712 ;; the maximum size of prologue in unwind information.
11713
11714 (define_expand "simple_return"
11715 [(simple_return)]
11716 "!TARGET_SEH"
11717 {
11718 if (crtl->args.pops_args)
11719 {
11720 rtx popc = GEN_INT (crtl->args.pops_args);
11721 emit_jump_insn (gen_simple_return_pop_internal (popc));
11722 DONE;
11723 }
11724 })
11725
11726 (define_insn "simple_return_internal"
11727 [(simple_return)]
11728 "reload_completed"
11729 "%!ret"
11730 [(set_attr "length_nobnd" "1")
11731 (set_attr "atom_unit" "jeu")
11732 (set_attr "length_immediate" "0")
11733 (set_attr "modrm" "0")])
11734
11735 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11736 ;; instruction Athlon and K8 have.
11737
11738 (define_insn "simple_return_internal_long"
11739 [(simple_return)
11740 (unspec [(const_int 0)] UNSPEC_REP)]
11741 "reload_completed"
11742 {
11743 if (ix86_bnd_prefixed_insn_p (insn))
11744 return "%!ret";
11745
11746 return "rep%; ret";
11747 }
11748 [(set_attr "length" "2")
11749 (set_attr "atom_unit" "jeu")
11750 (set_attr "length_immediate" "0")
11751 (set_attr "prefix_rep" "1")
11752 (set_attr "modrm" "0")])
11753
11754 (define_insn "simple_return_pop_internal"
11755 [(simple_return)
11756 (use (match_operand:SI 0 "const_int_operand"))]
11757 "reload_completed"
11758 "%!ret\t%0"
11759 [(set_attr "length_nobnd" "3")
11760 (set_attr "atom_unit" "jeu")
11761 (set_attr "length_immediate" "2")
11762 (set_attr "modrm" "0")])
11763
11764 (define_insn "simple_return_indirect_internal"
11765 [(simple_return)
11766 (use (match_operand:SI 0 "register_operand" "r"))]
11767 "reload_completed"
11768 "%!jmp\t%A0"
11769 [(set_attr "type" "ibr")
11770 (set_attr "length_immediate" "0")])
11771
11772 (define_insn "nop"
11773 [(const_int 0)]
11774 ""
11775 "nop"
11776 [(set_attr "length" "1")
11777 (set_attr "length_immediate" "0")
11778 (set_attr "modrm" "0")])
11779
11780 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11781 (define_insn "nops"
11782 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11783 UNSPECV_NOPS)]
11784 "reload_completed"
11785 {
11786 int num = INTVAL (operands[0]);
11787
11788 gcc_assert (IN_RANGE (num, 1, 8));
11789
11790 while (num--)
11791 fputs ("\tnop\n", asm_out_file);
11792
11793 return "";
11794 }
11795 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11796 (set_attr "length_immediate" "0")
11797 (set_attr "modrm" "0")])
11798
11799 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11800 ;; branch prediction penalty for the third jump in a 16-byte
11801 ;; block on K8.
11802
11803 (define_insn "pad"
11804 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11805 ""
11806 {
11807 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11808 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11809 #else
11810 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11811 The align insn is used to avoid 3 jump instructions in the row to improve
11812 branch prediction and the benefits hardly outweigh the cost of extra 8
11813 nops on the average inserted by full alignment pseudo operation. */
11814 #endif
11815 return "";
11816 }
11817 [(set_attr "length" "16")])
11818
11819 (define_expand "prologue"
11820 [(const_int 0)]
11821 ""
11822 "ix86_expand_prologue (); DONE;")
11823
11824 (define_insn "set_got"
11825 [(set (match_operand:SI 0 "register_operand" "=r")
11826 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11827 (clobber (reg:CC FLAGS_REG))]
11828 "!TARGET_64BIT"
11829 "* return output_set_got (operands[0], NULL_RTX);"
11830 [(set_attr "type" "multi")
11831 (set_attr "length" "12")])
11832
11833 (define_insn "set_got_labelled"
11834 [(set (match_operand:SI 0 "register_operand" "=r")
11835 (unspec:SI [(label_ref (match_operand 1))]
11836 UNSPEC_SET_GOT))
11837 (clobber (reg:CC FLAGS_REG))]
11838 "!TARGET_64BIT"
11839 "* return output_set_got (operands[0], operands[1]);"
11840 [(set_attr "type" "multi")
11841 (set_attr "length" "12")])
11842
11843 (define_insn "set_got_rex64"
11844 [(set (match_operand:DI 0 "register_operand" "=r")
11845 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11846 "TARGET_64BIT"
11847 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11848 [(set_attr "type" "lea")
11849 (set_attr "length_address" "4")
11850 (set_attr "mode" "DI")])
11851
11852 (define_insn "set_rip_rex64"
11853 [(set (match_operand:DI 0 "register_operand" "=r")
11854 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11855 "TARGET_64BIT"
11856 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11857 [(set_attr "type" "lea")
11858 (set_attr "length_address" "4")
11859 (set_attr "mode" "DI")])
11860
11861 (define_insn "set_got_offset_rex64"
11862 [(set (match_operand:DI 0 "register_operand" "=r")
11863 (unspec:DI
11864 [(label_ref (match_operand 1))]
11865 UNSPEC_SET_GOT_OFFSET))]
11866 "TARGET_LP64"
11867 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11868 [(set_attr "type" "imov")
11869 (set_attr "length_immediate" "0")
11870 (set_attr "length_address" "8")
11871 (set_attr "mode" "DI")])
11872
11873 (define_expand "epilogue"
11874 [(const_int 0)]
11875 ""
11876 "ix86_expand_epilogue (1); DONE;")
11877
11878 (define_expand "sibcall_epilogue"
11879 [(const_int 0)]
11880 ""
11881 "ix86_expand_epilogue (0); DONE;")
11882
11883 (define_expand "eh_return"
11884 [(use (match_operand 0 "register_operand"))]
11885 ""
11886 {
11887 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11888
11889 /* Tricky bit: we write the address of the handler to which we will
11890 be returning into someone else's stack frame, one word below the
11891 stack address we wish to restore. */
11892 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11893 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11894 tmp = gen_rtx_MEM (Pmode, tmp);
11895 emit_move_insn (tmp, ra);
11896
11897 emit_jump_insn (gen_eh_return_internal ());
11898 emit_barrier ();
11899 DONE;
11900 })
11901
11902 (define_insn_and_split "eh_return_internal"
11903 [(eh_return)]
11904 ""
11905 "#"
11906 "epilogue_completed"
11907 [(const_int 0)]
11908 "ix86_expand_epilogue (2); DONE;")
11909
11910 (define_insn "leave"
11911 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11912 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11913 (clobber (mem:BLK (scratch)))]
11914 "!TARGET_64BIT"
11915 "leave"
11916 [(set_attr "type" "leave")])
11917
11918 (define_insn "leave_rex64"
11919 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11920 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11921 (clobber (mem:BLK (scratch)))]
11922 "TARGET_64BIT"
11923 "leave"
11924 [(set_attr "type" "leave")])
11925 \f
11926 ;; Handle -fsplit-stack.
11927
11928 (define_expand "split_stack_prologue"
11929 [(const_int 0)]
11930 ""
11931 {
11932 ix86_expand_split_stack_prologue ();
11933 DONE;
11934 })
11935
11936 ;; In order to support the call/return predictor, we use a return
11937 ;; instruction which the middle-end doesn't see.
11938 (define_insn "split_stack_return"
11939 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11940 UNSPECV_SPLIT_STACK_RETURN)]
11941 ""
11942 {
11943 if (operands[0] == const0_rtx)
11944 return "ret";
11945 else
11946 return "ret\t%0";
11947 }
11948 [(set_attr "atom_unit" "jeu")
11949 (set_attr "modrm" "0")
11950 (set (attr "length")
11951 (if_then_else (match_operand:SI 0 "const0_operand")
11952 (const_int 1)
11953 (const_int 3)))
11954 (set (attr "length_immediate")
11955 (if_then_else (match_operand:SI 0 "const0_operand")
11956 (const_int 0)
11957 (const_int 2)))])
11958
11959 ;; If there are operand 0 bytes available on the stack, jump to
11960 ;; operand 1.
11961
11962 (define_expand "split_stack_space_check"
11963 [(set (pc) (if_then_else
11964 (ltu (minus (reg SP_REG)
11965 (match_operand 0 "register_operand"))
11966 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11967 (label_ref (match_operand 1))
11968 (pc)))]
11969 ""
11970 {
11971 rtx reg, size, limit;
11972
11973 reg = gen_reg_rtx (Pmode);
11974 size = force_reg (Pmode, operands[0]);
11975 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11976 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11977 UNSPEC_STACK_CHECK);
11978 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11979 ix86_expand_branch (GEU, reg, limit, operands[1]);
11980
11981 DONE;
11982 })
11983 \f
11984 ;; Bit manipulation instructions.
11985
11986 (define_expand "ffs<mode>2"
11987 [(set (match_dup 2) (const_int -1))
11988 (parallel [(set (match_dup 3) (match_dup 4))
11989 (set (match_operand:SWI48 0 "register_operand")
11990 (ctz:SWI48
11991 (match_operand:SWI48 1 "nonimmediate_operand")))])
11992 (set (match_dup 0) (if_then_else:SWI48
11993 (eq (match_dup 3) (const_int 0))
11994 (match_dup 2)
11995 (match_dup 0)))
11996 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11997 (clobber (reg:CC FLAGS_REG))])]
11998 ""
11999 {
12000 enum machine_mode flags_mode;
12001
12002 if (<MODE>mode == SImode && !TARGET_CMOVE)
12003 {
12004 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12005 DONE;
12006 }
12007
12008 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12009
12010 operands[2] = gen_reg_rtx (<MODE>mode);
12011 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12012 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12013 })
12014
12015 (define_insn_and_split "ffssi2_no_cmove"
12016 [(set (match_operand:SI 0 "register_operand" "=r")
12017 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12018 (clobber (match_scratch:SI 2 "=&q"))
12019 (clobber (reg:CC FLAGS_REG))]
12020 "!TARGET_CMOVE"
12021 "#"
12022 "&& reload_completed"
12023 [(parallel [(set (match_dup 4) (match_dup 5))
12024 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12025 (set (strict_low_part (match_dup 3))
12026 (eq:QI (match_dup 4) (const_int 0)))
12027 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12028 (clobber (reg:CC FLAGS_REG))])
12029 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12030 (clobber (reg:CC FLAGS_REG))])
12031 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12032 (clobber (reg:CC FLAGS_REG))])]
12033 {
12034 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12035
12036 operands[3] = gen_lowpart (QImode, operands[2]);
12037 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12038 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12039
12040 ix86_expand_clear (operands[2]);
12041 })
12042
12043 (define_insn "*tzcnt<mode>_1"
12044 [(set (reg:CCC FLAGS_REG)
12045 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12046 (const_int 0)))
12047 (set (match_operand:SWI48 0 "register_operand" "=r")
12048 (ctz:SWI48 (match_dup 1)))]
12049 "TARGET_BMI"
12050 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12051 [(set_attr "type" "alu1")
12052 (set_attr "prefix_0f" "1")
12053 (set_attr "prefix_rep" "1")
12054 (set_attr "btver2_decode" "double")
12055 (set_attr "mode" "<MODE>")])
12056
12057 (define_insn "*bsf<mode>_1"
12058 [(set (reg:CCZ FLAGS_REG)
12059 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12060 (const_int 0)))
12061 (set (match_operand:SWI48 0 "register_operand" "=r")
12062 (ctz:SWI48 (match_dup 1)))]
12063 ""
12064 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12065 [(set_attr "type" "alu1")
12066 (set_attr "prefix_0f" "1")
12067 (set_attr "btver2_decode" "double")
12068 (set_attr "mode" "<MODE>")])
12069
12070 (define_insn "ctz<mode>2"
12071 [(set (match_operand:SWI248 0 "register_operand" "=r")
12072 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12073 (clobber (reg:CC FLAGS_REG))]
12074 ""
12075 {
12076 if (TARGET_BMI)
12077 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12078 else if (optimize_function_for_size_p (cfun))
12079 ;
12080 else if (TARGET_GENERIC)
12081 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12082 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12083
12084 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12085 }
12086 [(set_attr "type" "alu1")
12087 (set_attr "prefix_0f" "1")
12088 (set (attr "prefix_rep")
12089 (if_then_else
12090 (ior (match_test "TARGET_BMI")
12091 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12092 (match_test "TARGET_GENERIC")))
12093 (const_string "1")
12094 (const_string "0")))
12095 (set_attr "mode" "<MODE>")])
12096
12097 (define_expand "clz<mode>2"
12098 [(parallel
12099 [(set (match_operand:SWI248 0 "register_operand")
12100 (minus:SWI248
12101 (match_dup 2)
12102 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12103 (clobber (reg:CC FLAGS_REG))])
12104 (parallel
12105 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12106 (clobber (reg:CC FLAGS_REG))])]
12107 ""
12108 {
12109 if (TARGET_LZCNT)
12110 {
12111 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12112 DONE;
12113 }
12114 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12115 })
12116
12117 (define_insn "clz<mode>2_lzcnt"
12118 [(set (match_operand:SWI248 0 "register_operand" "=r")
12119 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12120 (clobber (reg:CC FLAGS_REG))]
12121 "TARGET_LZCNT"
12122 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12123 [(set_attr "prefix_rep" "1")
12124 (set_attr "type" "bitmanip")
12125 (set_attr "mode" "<MODE>")])
12126
12127 ;; BMI instructions.
12128 (define_insn "*bmi_andn_<mode>"
12129 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12130 (and:SWI48
12131 (not:SWI48
12132 (match_operand:SWI48 1 "register_operand" "r,r"))
12133 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12134 (clobber (reg:CC FLAGS_REG))]
12135 "TARGET_BMI"
12136 "andn\t{%2, %1, %0|%0, %1, %2}"
12137 [(set_attr "type" "bitmanip")
12138 (set_attr "btver2_decode" "direct, double")
12139 (set_attr "mode" "<MODE>")])
12140
12141 (define_insn "bmi_bextr_<mode>"
12142 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12143 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12144 (match_operand:SWI48 2 "register_operand" "r,r")]
12145 UNSPEC_BEXTR))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "TARGET_BMI"
12148 "bextr\t{%2, %1, %0|%0, %1, %2}"
12149 [(set_attr "type" "bitmanip")
12150 (set_attr "btver2_decode" "direct, double")
12151 (set_attr "mode" "<MODE>")])
12152
12153 (define_insn "*bmi_blsi_<mode>"
12154 [(set (match_operand:SWI48 0 "register_operand" "=r")
12155 (and:SWI48
12156 (neg:SWI48
12157 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12158 (match_dup 1)))
12159 (clobber (reg:CC FLAGS_REG))]
12160 "TARGET_BMI"
12161 "blsi\t{%1, %0|%0, %1}"
12162 [(set_attr "type" "bitmanip")
12163 (set_attr "btver2_decode" "double")
12164 (set_attr "mode" "<MODE>")])
12165
12166 (define_insn "*bmi_blsmsk_<mode>"
12167 [(set (match_operand:SWI48 0 "register_operand" "=r")
12168 (xor:SWI48
12169 (plus:SWI48
12170 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12171 (const_int -1))
12172 (match_dup 1)))
12173 (clobber (reg:CC FLAGS_REG))]
12174 "TARGET_BMI"
12175 "blsmsk\t{%1, %0|%0, %1}"
12176 [(set_attr "type" "bitmanip")
12177 (set_attr "btver2_decode" "double")
12178 (set_attr "mode" "<MODE>")])
12179
12180 (define_insn "*bmi_blsr_<mode>"
12181 [(set (match_operand:SWI48 0 "register_operand" "=r")
12182 (and:SWI48
12183 (plus:SWI48
12184 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12185 (const_int -1))
12186 (match_dup 1)))
12187 (clobber (reg:CC FLAGS_REG))]
12188 "TARGET_BMI"
12189 "blsr\t{%1, %0|%0, %1}"
12190 [(set_attr "type" "bitmanip")
12191 (set_attr "btver2_decode" "double")
12192 (set_attr "mode" "<MODE>")])
12193
12194 ;; BMI2 instructions.
12195 (define_insn "bmi2_bzhi_<mode>3"
12196 [(set (match_operand:SWI48 0 "register_operand" "=r")
12197 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12198 (match_operand:SWI48 2 "register_operand" "r"))
12199 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12200 (clobber (reg:CC FLAGS_REG))]
12201 "TARGET_BMI2"
12202 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12203 [(set_attr "type" "bitmanip")
12204 (set_attr "prefix" "vex")
12205 (set_attr "mode" "<MODE>")])
12206
12207 (define_insn "bmi2_pdep_<mode>3"
12208 [(set (match_operand:SWI48 0 "register_operand" "=r")
12209 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12210 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12211 UNSPEC_PDEP))]
12212 "TARGET_BMI2"
12213 "pdep\t{%2, %1, %0|%0, %1, %2}"
12214 [(set_attr "type" "bitmanip")
12215 (set_attr "prefix" "vex")
12216 (set_attr "mode" "<MODE>")])
12217
12218 (define_insn "bmi2_pext_<mode>3"
12219 [(set (match_operand:SWI48 0 "register_operand" "=r")
12220 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12221 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12222 UNSPEC_PEXT))]
12223 "TARGET_BMI2"
12224 "pext\t{%2, %1, %0|%0, %1, %2}"
12225 [(set_attr "type" "bitmanip")
12226 (set_attr "prefix" "vex")
12227 (set_attr "mode" "<MODE>")])
12228
12229 ;; TBM instructions.
12230 (define_insn "tbm_bextri_<mode>"
12231 [(set (match_operand:SWI48 0 "register_operand" "=r")
12232 (zero_extract:SWI48
12233 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12234 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12235 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12236 (clobber (reg:CC FLAGS_REG))]
12237 "TARGET_TBM"
12238 {
12239 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12240 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12241 }
12242 [(set_attr "type" "bitmanip")
12243 (set_attr "mode" "<MODE>")])
12244
12245 (define_insn "*tbm_blcfill_<mode>"
12246 [(set (match_operand:SWI48 0 "register_operand" "=r")
12247 (and:SWI48
12248 (plus:SWI48
12249 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12250 (const_int 1))
12251 (match_dup 1)))
12252 (clobber (reg:CC FLAGS_REG))]
12253 "TARGET_TBM"
12254 "blcfill\t{%1, %0|%0, %1}"
12255 [(set_attr "type" "bitmanip")
12256 (set_attr "mode" "<MODE>")])
12257
12258 (define_insn "*tbm_blci_<mode>"
12259 [(set (match_operand:SWI48 0 "register_operand" "=r")
12260 (ior:SWI48
12261 (not:SWI48
12262 (plus:SWI48
12263 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12264 (const_int 1)))
12265 (match_dup 1)))
12266 (clobber (reg:CC FLAGS_REG))]
12267 "TARGET_TBM"
12268 "blci\t{%1, %0|%0, %1}"
12269 [(set_attr "type" "bitmanip")
12270 (set_attr "mode" "<MODE>")])
12271
12272 (define_insn "*tbm_blcic_<mode>"
12273 [(set (match_operand:SWI48 0 "register_operand" "=r")
12274 (and:SWI48
12275 (plus:SWI48
12276 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12277 (const_int 1))
12278 (not:SWI48
12279 (match_dup 1))))
12280 (clobber (reg:CC FLAGS_REG))]
12281 "TARGET_TBM"
12282 "blcic\t{%1, %0|%0, %1}"
12283 [(set_attr "type" "bitmanip")
12284 (set_attr "mode" "<MODE>")])
12285
12286 (define_insn "*tbm_blcmsk_<mode>"
12287 [(set (match_operand:SWI48 0 "register_operand" "=r")
12288 (xor:SWI48
12289 (plus:SWI48
12290 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12291 (const_int 1))
12292 (match_dup 1)))
12293 (clobber (reg:CC FLAGS_REG))]
12294 "TARGET_TBM"
12295 "blcmsk\t{%1, %0|%0, %1}"
12296 [(set_attr "type" "bitmanip")
12297 (set_attr "mode" "<MODE>")])
12298
12299 (define_insn "*tbm_blcs_<mode>"
12300 [(set (match_operand:SWI48 0 "register_operand" "=r")
12301 (ior:SWI48
12302 (plus:SWI48
12303 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12304 (const_int 1))
12305 (match_dup 1)))
12306 (clobber (reg:CC FLAGS_REG))]
12307 "TARGET_TBM"
12308 "blcs\t{%1, %0|%0, %1}"
12309 [(set_attr "type" "bitmanip")
12310 (set_attr "mode" "<MODE>")])
12311
12312 (define_insn "*tbm_blsfill_<mode>"
12313 [(set (match_operand:SWI48 0 "register_operand" "=r")
12314 (ior:SWI48
12315 (plus:SWI48
12316 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12317 (const_int -1))
12318 (match_dup 1)))
12319 (clobber (reg:CC FLAGS_REG))]
12320 "TARGET_TBM"
12321 "blsfill\t{%1, %0|%0, %1}"
12322 [(set_attr "type" "bitmanip")
12323 (set_attr "mode" "<MODE>")])
12324
12325 (define_insn "*tbm_blsic_<mode>"
12326 [(set (match_operand:SWI48 0 "register_operand" "=r")
12327 (ior:SWI48
12328 (plus:SWI48
12329 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12330 (const_int -1))
12331 (not:SWI48
12332 (match_dup 1))))
12333 (clobber (reg:CC FLAGS_REG))]
12334 "TARGET_TBM"
12335 "blsic\t{%1, %0|%0, %1}"
12336 [(set_attr "type" "bitmanip")
12337 (set_attr "mode" "<MODE>")])
12338
12339 (define_insn "*tbm_t1mskc_<mode>"
12340 [(set (match_operand:SWI48 0 "register_operand" "=r")
12341 (ior:SWI48
12342 (plus:SWI48
12343 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12344 (const_int 1))
12345 (not:SWI48
12346 (match_dup 1))))
12347 (clobber (reg:CC FLAGS_REG))]
12348 "TARGET_TBM"
12349 "t1mskc\t{%1, %0|%0, %1}"
12350 [(set_attr "type" "bitmanip")
12351 (set_attr "mode" "<MODE>")])
12352
12353 (define_insn "*tbm_tzmsk_<mode>"
12354 [(set (match_operand:SWI48 0 "register_operand" "=r")
12355 (and:SWI48
12356 (plus:SWI48
12357 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12358 (const_int -1))
12359 (not:SWI48
12360 (match_dup 1))))
12361 (clobber (reg:CC FLAGS_REG))]
12362 "TARGET_TBM"
12363 "tzmsk\t{%1, %0|%0, %1}"
12364 [(set_attr "type" "bitmanip")
12365 (set_attr "mode" "<MODE>")])
12366
12367 (define_insn "bsr_rex64"
12368 [(set (match_operand:DI 0 "register_operand" "=r")
12369 (minus:DI (const_int 63)
12370 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12371 (clobber (reg:CC FLAGS_REG))]
12372 "TARGET_64BIT"
12373 "bsr{q}\t{%1, %0|%0, %1}"
12374 [(set_attr "type" "alu1")
12375 (set_attr "prefix_0f" "1")
12376 (set_attr "mode" "DI")])
12377
12378 (define_insn "bsr"
12379 [(set (match_operand:SI 0 "register_operand" "=r")
12380 (minus:SI (const_int 31)
12381 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12382 (clobber (reg:CC FLAGS_REG))]
12383 ""
12384 "bsr{l}\t{%1, %0|%0, %1}"
12385 [(set_attr "type" "alu1")
12386 (set_attr "prefix_0f" "1")
12387 (set_attr "mode" "SI")])
12388
12389 (define_insn "*bsrhi"
12390 [(set (match_operand:HI 0 "register_operand" "=r")
12391 (minus:HI (const_int 15)
12392 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12393 (clobber (reg:CC FLAGS_REG))]
12394 ""
12395 "bsr{w}\t{%1, %0|%0, %1}"
12396 [(set_attr "type" "alu1")
12397 (set_attr "prefix_0f" "1")
12398 (set_attr "mode" "HI")])
12399
12400 (define_insn "popcount<mode>2"
12401 [(set (match_operand:SWI248 0 "register_operand" "=r")
12402 (popcount:SWI248
12403 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12404 (clobber (reg:CC FLAGS_REG))]
12405 "TARGET_POPCNT"
12406 {
12407 #if TARGET_MACHO
12408 return "popcnt\t{%1, %0|%0, %1}";
12409 #else
12410 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12411 #endif
12412 }
12413 [(set_attr "prefix_rep" "1")
12414 (set_attr "type" "bitmanip")
12415 (set_attr "mode" "<MODE>")])
12416
12417 (define_insn "*popcount<mode>2_cmp"
12418 [(set (reg FLAGS_REG)
12419 (compare
12420 (popcount:SWI248
12421 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12422 (const_int 0)))
12423 (set (match_operand:SWI248 0 "register_operand" "=r")
12424 (popcount:SWI248 (match_dup 1)))]
12425 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12426 {
12427 #if TARGET_MACHO
12428 return "popcnt\t{%1, %0|%0, %1}";
12429 #else
12430 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12431 #endif
12432 }
12433 [(set_attr "prefix_rep" "1")
12434 (set_attr "type" "bitmanip")
12435 (set_attr "mode" "<MODE>")])
12436
12437 (define_insn "*popcountsi2_cmp_zext"
12438 [(set (reg FLAGS_REG)
12439 (compare
12440 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12441 (const_int 0)))
12442 (set (match_operand:DI 0 "register_operand" "=r")
12443 (zero_extend:DI(popcount:SI (match_dup 1))))]
12444 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12445 {
12446 #if TARGET_MACHO
12447 return "popcnt\t{%1, %0|%0, %1}";
12448 #else
12449 return "popcnt{l}\t{%1, %0|%0, %1}";
12450 #endif
12451 }
12452 [(set_attr "prefix_rep" "1")
12453 (set_attr "type" "bitmanip")
12454 (set_attr "mode" "SI")])
12455
12456 (define_expand "bswapdi2"
12457 [(set (match_operand:DI 0 "register_operand")
12458 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12459 "TARGET_64BIT"
12460 {
12461 if (!TARGET_MOVBE)
12462 operands[1] = force_reg (DImode, operands[1]);
12463 })
12464
12465 (define_expand "bswapsi2"
12466 [(set (match_operand:SI 0 "register_operand")
12467 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12468 ""
12469 {
12470 if (TARGET_MOVBE)
12471 ;
12472 else if (TARGET_BSWAP)
12473 operands[1] = force_reg (SImode, operands[1]);
12474 else
12475 {
12476 rtx x = operands[0];
12477
12478 emit_move_insn (x, operands[1]);
12479 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12480 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12481 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12482 DONE;
12483 }
12484 })
12485
12486 (define_insn "*bswap<mode>2_movbe"
12487 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12488 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12489 "TARGET_MOVBE
12490 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12491 "@
12492 bswap\t%0
12493 movbe\t{%1, %0|%0, %1}
12494 movbe\t{%1, %0|%0, %1}"
12495 [(set_attr "type" "bitmanip,imov,imov")
12496 (set_attr "modrm" "0,1,1")
12497 (set_attr "prefix_0f" "*,1,1")
12498 (set_attr "prefix_extra" "*,1,1")
12499 (set_attr "mode" "<MODE>")])
12500
12501 (define_insn "*bswap<mode>2"
12502 [(set (match_operand:SWI48 0 "register_operand" "=r")
12503 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12504 "TARGET_BSWAP"
12505 "bswap\t%0"
12506 [(set_attr "type" "bitmanip")
12507 (set_attr "modrm" "0")
12508 (set_attr "mode" "<MODE>")])
12509
12510 (define_insn "*bswaphi_lowpart_1"
12511 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12512 (bswap:HI (match_dup 0)))
12513 (clobber (reg:CC FLAGS_REG))]
12514 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12515 "@
12516 xchg{b}\t{%h0, %b0|%b0, %h0}
12517 rol{w}\t{$8, %0|%0, 8}"
12518 [(set_attr "length" "2,4")
12519 (set_attr "mode" "QI,HI")])
12520
12521 (define_insn "bswaphi_lowpart"
12522 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12523 (bswap:HI (match_dup 0)))
12524 (clobber (reg:CC FLAGS_REG))]
12525 ""
12526 "rol{w}\t{$8, %0|%0, 8}"
12527 [(set_attr "length" "4")
12528 (set_attr "mode" "HI")])
12529
12530 (define_expand "paritydi2"
12531 [(set (match_operand:DI 0 "register_operand")
12532 (parity:DI (match_operand:DI 1 "register_operand")))]
12533 "! TARGET_POPCNT"
12534 {
12535 rtx scratch = gen_reg_rtx (QImode);
12536 rtx cond;
12537
12538 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12539 NULL_RTX, operands[1]));
12540
12541 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12542 gen_rtx_REG (CCmode, FLAGS_REG),
12543 const0_rtx);
12544 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12545
12546 if (TARGET_64BIT)
12547 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12548 else
12549 {
12550 rtx tmp = gen_reg_rtx (SImode);
12551
12552 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12553 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12554 }
12555 DONE;
12556 })
12557
12558 (define_expand "paritysi2"
12559 [(set (match_operand:SI 0 "register_operand")
12560 (parity:SI (match_operand:SI 1 "register_operand")))]
12561 "! TARGET_POPCNT"
12562 {
12563 rtx scratch = gen_reg_rtx (QImode);
12564 rtx cond;
12565
12566 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12567
12568 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12569 gen_rtx_REG (CCmode, FLAGS_REG),
12570 const0_rtx);
12571 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12572
12573 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12574 DONE;
12575 })
12576
12577 (define_insn_and_split "paritydi2_cmp"
12578 [(set (reg:CC FLAGS_REG)
12579 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12580 UNSPEC_PARITY))
12581 (clobber (match_scratch:DI 0 "=r"))
12582 (clobber (match_scratch:SI 1 "=&r"))
12583 (clobber (match_scratch:HI 2 "=Q"))]
12584 "! TARGET_POPCNT"
12585 "#"
12586 "&& reload_completed"
12587 [(parallel
12588 [(set (match_dup 1)
12589 (xor:SI (match_dup 1) (match_dup 4)))
12590 (clobber (reg:CC FLAGS_REG))])
12591 (parallel
12592 [(set (reg:CC FLAGS_REG)
12593 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12594 (clobber (match_dup 1))
12595 (clobber (match_dup 2))])]
12596 {
12597 operands[4] = gen_lowpart (SImode, operands[3]);
12598
12599 if (TARGET_64BIT)
12600 {
12601 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12602 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12603 }
12604 else
12605 operands[1] = gen_highpart (SImode, operands[3]);
12606 })
12607
12608 (define_insn_and_split "paritysi2_cmp"
12609 [(set (reg:CC FLAGS_REG)
12610 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12611 UNSPEC_PARITY))
12612 (clobber (match_scratch:SI 0 "=r"))
12613 (clobber (match_scratch:HI 1 "=&Q"))]
12614 "! TARGET_POPCNT"
12615 "#"
12616 "&& reload_completed"
12617 [(parallel
12618 [(set (match_dup 1)
12619 (xor:HI (match_dup 1) (match_dup 3)))
12620 (clobber (reg:CC FLAGS_REG))])
12621 (parallel
12622 [(set (reg:CC FLAGS_REG)
12623 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12624 (clobber (match_dup 1))])]
12625 {
12626 operands[3] = gen_lowpart (HImode, operands[2]);
12627
12628 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12629 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12630 })
12631
12632 (define_insn "*parityhi2_cmp"
12633 [(set (reg:CC FLAGS_REG)
12634 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12635 UNSPEC_PARITY))
12636 (clobber (match_scratch:HI 0 "=Q"))]
12637 "! TARGET_POPCNT"
12638 "xor{b}\t{%h0, %b0|%b0, %h0}"
12639 [(set_attr "length" "2")
12640 (set_attr "mode" "HI")])
12641
12642 \f
12643 ;; Thread-local storage patterns for ELF.
12644 ;;
12645 ;; Note that these code sequences must appear exactly as shown
12646 ;; in order to allow linker relaxation.
12647
12648 (define_insn "*tls_global_dynamic_32_gnu"
12649 [(set (match_operand:SI 0 "register_operand" "=a")
12650 (unspec:SI
12651 [(match_operand:SI 1 "register_operand" "b")
12652 (match_operand 2 "tls_symbolic_operand")
12653 (match_operand 3 "constant_call_address_operand" "z")]
12654 UNSPEC_TLS_GD))
12655 (clobber (match_scratch:SI 4 "=d"))
12656 (clobber (match_scratch:SI 5 "=c"))
12657 (clobber (reg:CC FLAGS_REG))]
12658 "!TARGET_64BIT && TARGET_GNU_TLS"
12659 {
12660 output_asm_insn
12661 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12662 if (TARGET_SUN_TLS)
12663 #ifdef HAVE_AS_IX86_TLSGDPLT
12664 return "call\t%a2@tlsgdplt";
12665 #else
12666 return "call\t%p3@plt";
12667 #endif
12668 return "call\t%P3";
12669 }
12670 [(set_attr "type" "multi")
12671 (set_attr "length" "12")])
12672
12673 (define_expand "tls_global_dynamic_32"
12674 [(parallel
12675 [(set (match_operand:SI 0 "register_operand")
12676 (unspec:SI [(match_operand:SI 2 "register_operand")
12677 (match_operand 1 "tls_symbolic_operand")
12678 (match_operand 3 "constant_call_address_operand")]
12679 UNSPEC_TLS_GD))
12680 (clobber (match_scratch:SI 4))
12681 (clobber (match_scratch:SI 5))
12682 (clobber (reg:CC FLAGS_REG))])])
12683
12684 (define_insn "*tls_global_dynamic_64_<mode>"
12685 [(set (match_operand:P 0 "register_operand" "=a")
12686 (call:P
12687 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12688 (match_operand 3)))
12689 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12690 UNSPEC_TLS_GD)]
12691 "TARGET_64BIT"
12692 {
12693 if (!TARGET_X32)
12694 fputs (ASM_BYTE "0x66\n", asm_out_file);
12695 output_asm_insn
12696 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12697 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12698 fputs ("\trex64\n", asm_out_file);
12699 if (TARGET_SUN_TLS)
12700 return "call\t%p2@plt";
12701 return "call\t%P2";
12702 }
12703 [(set_attr "type" "multi")
12704 (set (attr "length")
12705 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12706
12707 (define_insn "*tls_global_dynamic_64_largepic"
12708 [(set (match_operand:DI 0 "register_operand" "=a")
12709 (call:DI
12710 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12711 (match_operand:DI 3 "immediate_operand" "i")))
12712 (match_operand 4)))
12713 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12714 UNSPEC_TLS_GD)]
12715 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12716 && GET_CODE (operands[3]) == CONST
12717 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12718 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12719 {
12720 output_asm_insn
12721 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12722 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12723 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12724 return "call\t{*%%rax|rax}";
12725 }
12726 [(set_attr "type" "multi")
12727 (set_attr "length" "22")])
12728
12729 (define_expand "tls_global_dynamic_64_<mode>"
12730 [(parallel
12731 [(set (match_operand:P 0 "register_operand")
12732 (call:P
12733 (mem:QI (match_operand 2))
12734 (const_int 0)))
12735 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12736 UNSPEC_TLS_GD)])]
12737 "TARGET_64BIT")
12738
12739 (define_insn "*tls_local_dynamic_base_32_gnu"
12740 [(set (match_operand:SI 0 "register_operand" "=a")
12741 (unspec:SI
12742 [(match_operand:SI 1 "register_operand" "b")
12743 (match_operand 2 "constant_call_address_operand" "z")]
12744 UNSPEC_TLS_LD_BASE))
12745 (clobber (match_scratch:SI 3 "=d"))
12746 (clobber (match_scratch:SI 4 "=c"))
12747 (clobber (reg:CC FLAGS_REG))]
12748 "!TARGET_64BIT && TARGET_GNU_TLS"
12749 {
12750 output_asm_insn
12751 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12752 if (TARGET_SUN_TLS)
12753 #ifdef HAVE_AS_IX86_TLSLDMPLT
12754 return "call\t%&@tlsldmplt";
12755 #else
12756 return "call\t%p2@plt";
12757 #endif
12758 return "call\t%P2";
12759 }
12760 [(set_attr "type" "multi")
12761 (set_attr "length" "11")])
12762
12763 (define_expand "tls_local_dynamic_base_32"
12764 [(parallel
12765 [(set (match_operand:SI 0 "register_operand")
12766 (unspec:SI
12767 [(match_operand:SI 1 "register_operand")
12768 (match_operand 2 "constant_call_address_operand")]
12769 UNSPEC_TLS_LD_BASE))
12770 (clobber (match_scratch:SI 3))
12771 (clobber (match_scratch:SI 4))
12772 (clobber (reg:CC FLAGS_REG))])])
12773
12774 (define_insn "*tls_local_dynamic_base_64_<mode>"
12775 [(set (match_operand:P 0 "register_operand" "=a")
12776 (call:P
12777 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12778 (match_operand 2)))
12779 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12780 "TARGET_64BIT"
12781 {
12782 output_asm_insn
12783 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12784 if (TARGET_SUN_TLS)
12785 return "call\t%p1@plt";
12786 return "call\t%P1";
12787 }
12788 [(set_attr "type" "multi")
12789 (set_attr "length" "12")])
12790
12791 (define_insn "*tls_local_dynamic_base_64_largepic"
12792 [(set (match_operand:DI 0 "register_operand" "=a")
12793 (call:DI
12794 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
12795 (match_operand:DI 2 "immediate_operand" "i")))
12796 (match_operand 3)))
12797 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12798 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12799 && GET_CODE (operands[2]) == CONST
12800 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
12801 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
12802 {
12803 output_asm_insn
12804 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12805 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
12806 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
12807 return "call\t{*%%rax|rax}";
12808 }
12809 [(set_attr "type" "multi")
12810 (set_attr "length" "22")])
12811
12812 (define_expand "tls_local_dynamic_base_64_<mode>"
12813 [(parallel
12814 [(set (match_operand:P 0 "register_operand")
12815 (call:P
12816 (mem:QI (match_operand 1))
12817 (const_int 0)))
12818 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12819 "TARGET_64BIT")
12820
12821 ;; Local dynamic of a single variable is a lose. Show combine how
12822 ;; to convert that back to global dynamic.
12823
12824 (define_insn_and_split "*tls_local_dynamic_32_once"
12825 [(set (match_operand:SI 0 "register_operand" "=a")
12826 (plus:SI
12827 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12828 (match_operand 2 "constant_call_address_operand" "z")]
12829 UNSPEC_TLS_LD_BASE)
12830 (const:SI (unspec:SI
12831 [(match_operand 3 "tls_symbolic_operand")]
12832 UNSPEC_DTPOFF))))
12833 (clobber (match_scratch:SI 4 "=d"))
12834 (clobber (match_scratch:SI 5 "=c"))
12835 (clobber (reg:CC FLAGS_REG))]
12836 ""
12837 "#"
12838 ""
12839 [(parallel
12840 [(set (match_dup 0)
12841 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12842 UNSPEC_TLS_GD))
12843 (clobber (match_dup 4))
12844 (clobber (match_dup 5))
12845 (clobber (reg:CC FLAGS_REG))])])
12846
12847 ;; Segment register for the thread base ptr load
12848 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12849
12850 ;; Load and add the thread base pointer from %<tp_seg>:0.
12851 (define_insn "*load_tp_x32"
12852 [(set (match_operand:SI 0 "register_operand" "=r")
12853 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12854 "TARGET_X32"
12855 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12856 [(set_attr "type" "imov")
12857 (set_attr "modrm" "0")
12858 (set_attr "length" "7")
12859 (set_attr "memory" "load")
12860 (set_attr "imm_disp" "false")])
12861
12862 (define_insn "*load_tp_x32_zext"
12863 [(set (match_operand:DI 0 "register_operand" "=r")
12864 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12865 "TARGET_X32"
12866 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12867 [(set_attr "type" "imov")
12868 (set_attr "modrm" "0")
12869 (set_attr "length" "7")
12870 (set_attr "memory" "load")
12871 (set_attr "imm_disp" "false")])
12872
12873 (define_insn "*load_tp_<mode>"
12874 [(set (match_operand:P 0 "register_operand" "=r")
12875 (unspec:P [(const_int 0)] UNSPEC_TP))]
12876 "!TARGET_X32"
12877 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12878 [(set_attr "type" "imov")
12879 (set_attr "modrm" "0")
12880 (set_attr "length" "7")
12881 (set_attr "memory" "load")
12882 (set_attr "imm_disp" "false")])
12883
12884 (define_insn "*add_tp_x32"
12885 [(set (match_operand:SI 0 "register_operand" "=r")
12886 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12887 (match_operand:SI 1 "register_operand" "0")))
12888 (clobber (reg:CC FLAGS_REG))]
12889 "TARGET_X32"
12890 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12891 [(set_attr "type" "alu")
12892 (set_attr "modrm" "0")
12893 (set_attr "length" "7")
12894 (set_attr "memory" "load")
12895 (set_attr "imm_disp" "false")])
12896
12897 (define_insn "*add_tp_x32_zext"
12898 [(set (match_operand:DI 0 "register_operand" "=r")
12899 (zero_extend:DI
12900 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12901 (match_operand:SI 1 "register_operand" "0"))))
12902 (clobber (reg:CC FLAGS_REG))]
12903 "TARGET_X32"
12904 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12905 [(set_attr "type" "alu")
12906 (set_attr "modrm" "0")
12907 (set_attr "length" "7")
12908 (set_attr "memory" "load")
12909 (set_attr "imm_disp" "false")])
12910
12911 (define_insn "*add_tp_<mode>"
12912 [(set (match_operand:P 0 "register_operand" "=r")
12913 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12914 (match_operand:P 1 "register_operand" "0")))
12915 (clobber (reg:CC FLAGS_REG))]
12916 "!TARGET_X32"
12917 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12918 [(set_attr "type" "alu")
12919 (set_attr "modrm" "0")
12920 (set_attr "length" "7")
12921 (set_attr "memory" "load")
12922 (set_attr "imm_disp" "false")])
12923
12924 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12925 ;; %rax as destination of the initial executable code sequence.
12926 (define_insn "tls_initial_exec_64_sun"
12927 [(set (match_operand:DI 0 "register_operand" "=a")
12928 (unspec:DI
12929 [(match_operand 1 "tls_symbolic_operand")]
12930 UNSPEC_TLS_IE_SUN))
12931 (clobber (reg:CC FLAGS_REG))]
12932 "TARGET_64BIT && TARGET_SUN_TLS"
12933 {
12934 output_asm_insn
12935 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12936 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12937 }
12938 [(set_attr "type" "multi")])
12939
12940 ;; GNU2 TLS patterns can be split.
12941
12942 (define_expand "tls_dynamic_gnu2_32"
12943 [(set (match_dup 3)
12944 (plus:SI (match_operand:SI 2 "register_operand")
12945 (const:SI
12946 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12947 UNSPEC_TLSDESC))))
12948 (parallel
12949 [(set (match_operand:SI 0 "register_operand")
12950 (unspec:SI [(match_dup 1) (match_dup 3)
12951 (match_dup 2) (reg:SI SP_REG)]
12952 UNSPEC_TLSDESC))
12953 (clobber (reg:CC FLAGS_REG))])]
12954 "!TARGET_64BIT && TARGET_GNU2_TLS"
12955 {
12956 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12957 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12958 })
12959
12960 (define_insn "*tls_dynamic_gnu2_lea_32"
12961 [(set (match_operand:SI 0 "register_operand" "=r")
12962 (plus:SI (match_operand:SI 1 "register_operand" "b")
12963 (const:SI
12964 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12965 UNSPEC_TLSDESC))))]
12966 "!TARGET_64BIT && TARGET_GNU2_TLS"
12967 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12968 [(set_attr "type" "lea")
12969 (set_attr "mode" "SI")
12970 (set_attr "length" "6")
12971 (set_attr "length_address" "4")])
12972
12973 (define_insn "*tls_dynamic_gnu2_call_32"
12974 [(set (match_operand:SI 0 "register_operand" "=a")
12975 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12976 (match_operand:SI 2 "register_operand" "0")
12977 ;; we have to make sure %ebx still points to the GOT
12978 (match_operand:SI 3 "register_operand" "b")
12979 (reg:SI SP_REG)]
12980 UNSPEC_TLSDESC))
12981 (clobber (reg:CC FLAGS_REG))]
12982 "!TARGET_64BIT && TARGET_GNU2_TLS"
12983 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12984 [(set_attr "type" "call")
12985 (set_attr "length" "2")
12986 (set_attr "length_address" "0")])
12987
12988 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12989 [(set (match_operand:SI 0 "register_operand" "=&a")
12990 (plus:SI
12991 (unspec:SI [(match_operand 3 "tls_modbase_operand")
12992 (match_operand:SI 4)
12993 (match_operand:SI 2 "register_operand" "b")
12994 (reg:SI SP_REG)]
12995 UNSPEC_TLSDESC)
12996 (const:SI (unspec:SI
12997 [(match_operand 1 "tls_symbolic_operand")]
12998 UNSPEC_DTPOFF))))
12999 (clobber (reg:CC FLAGS_REG))]
13000 "!TARGET_64BIT && TARGET_GNU2_TLS"
13001 "#"
13002 ""
13003 [(set (match_dup 0) (match_dup 5))]
13004 {
13005 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13006 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13007 })
13008
13009 (define_expand "tls_dynamic_gnu2_64"
13010 [(set (match_dup 2)
13011 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13012 UNSPEC_TLSDESC))
13013 (parallel
13014 [(set (match_operand:DI 0 "register_operand")
13015 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13016 UNSPEC_TLSDESC))
13017 (clobber (reg:CC FLAGS_REG))])]
13018 "TARGET_64BIT && TARGET_GNU2_TLS"
13019 {
13020 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13021 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13022 })
13023
13024 (define_insn "*tls_dynamic_gnu2_lea_64"
13025 [(set (match_operand:DI 0 "register_operand" "=r")
13026 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13027 UNSPEC_TLSDESC))]
13028 "TARGET_64BIT && TARGET_GNU2_TLS"
13029 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13030 [(set_attr "type" "lea")
13031 (set_attr "mode" "DI")
13032 (set_attr "length" "7")
13033 (set_attr "length_address" "4")])
13034
13035 (define_insn "*tls_dynamic_gnu2_call_64"
13036 [(set (match_operand:DI 0 "register_operand" "=a")
13037 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13038 (match_operand:DI 2 "register_operand" "0")
13039 (reg:DI SP_REG)]
13040 UNSPEC_TLSDESC))
13041 (clobber (reg:CC FLAGS_REG))]
13042 "TARGET_64BIT && TARGET_GNU2_TLS"
13043 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13044 [(set_attr "type" "call")
13045 (set_attr "length" "2")
13046 (set_attr "length_address" "0")])
13047
13048 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13049 [(set (match_operand:DI 0 "register_operand" "=&a")
13050 (plus:DI
13051 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13052 (match_operand:DI 3)
13053 (reg:DI SP_REG)]
13054 UNSPEC_TLSDESC)
13055 (const:DI (unspec:DI
13056 [(match_operand 1 "tls_symbolic_operand")]
13057 UNSPEC_DTPOFF))))
13058 (clobber (reg:CC FLAGS_REG))]
13059 "TARGET_64BIT && TARGET_GNU2_TLS"
13060 "#"
13061 ""
13062 [(set (match_dup 0) (match_dup 4))]
13063 {
13064 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13065 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13066 })
13067 \f
13068 ;; These patterns match the binary 387 instructions for addM3, subM3,
13069 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13070 ;; SFmode. The first is the normal insn, the second the same insn but
13071 ;; with one operand a conversion, and the third the same insn but with
13072 ;; the other operand a conversion. The conversion may be SFmode or
13073 ;; SImode if the target mode DFmode, but only SImode if the target mode
13074 ;; is SFmode.
13075
13076 ;; Gcc is slightly more smart about handling normal two address instructions
13077 ;; so use special patterns for add and mull.
13078
13079 (define_insn "*fop_<mode>_comm_mixed"
13080 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13081 (match_operator:MODEF 3 "binary_fp_operator"
13082 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13083 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13084 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13085 && COMMUTATIVE_ARITH_P (operands[3])
13086 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13087 "* return output_387_binary_op (insn, operands);"
13088 [(set (attr "type")
13089 (if_then_else (eq_attr "alternative" "1,2")
13090 (if_then_else (match_operand:MODEF 3 "mult_operator")
13091 (const_string "ssemul")
13092 (const_string "sseadd"))
13093 (if_then_else (match_operand:MODEF 3 "mult_operator")
13094 (const_string "fmul")
13095 (const_string "fop"))))
13096 (set_attr "isa" "*,noavx,avx")
13097 (set_attr "prefix" "orig,orig,vex")
13098 (set_attr "mode" "<MODE>")])
13099
13100 (define_insn "*fop_<mode>_comm_sse"
13101 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13102 (match_operator:MODEF 3 "binary_fp_operator"
13103 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13104 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13105 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13106 && COMMUTATIVE_ARITH_P (operands[3])
13107 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13108 "* return output_387_binary_op (insn, operands);"
13109 [(set (attr "type")
13110 (if_then_else (match_operand:MODEF 3 "mult_operator")
13111 (const_string "ssemul")
13112 (const_string "sseadd")))
13113 (set_attr "isa" "noavx,avx")
13114 (set_attr "prefix" "orig,vex")
13115 (set_attr "mode" "<MODE>")])
13116
13117 (define_insn "*fop_<mode>_comm_i387"
13118 [(set (match_operand:MODEF 0 "register_operand" "=f")
13119 (match_operator:MODEF 3 "binary_fp_operator"
13120 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13121 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13122 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13123 && COMMUTATIVE_ARITH_P (operands[3])
13124 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13125 "* return output_387_binary_op (insn, operands);"
13126 [(set (attr "type")
13127 (if_then_else (match_operand:MODEF 3 "mult_operator")
13128 (const_string "fmul")
13129 (const_string "fop")))
13130 (set_attr "mode" "<MODE>")])
13131
13132 (define_insn "*fop_<mode>_1_mixed"
13133 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13134 (match_operator:MODEF 3 "binary_fp_operator"
13135 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13136 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13137 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13138 && !COMMUTATIVE_ARITH_P (operands[3])
13139 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13140 "* return output_387_binary_op (insn, operands);"
13141 [(set (attr "type")
13142 (cond [(and (eq_attr "alternative" "2,3")
13143 (match_operand:MODEF 3 "mult_operator"))
13144 (const_string "ssemul")
13145 (and (eq_attr "alternative" "2,3")
13146 (match_operand:MODEF 3 "div_operator"))
13147 (const_string "ssediv")
13148 (eq_attr "alternative" "2,3")
13149 (const_string "sseadd")
13150 (match_operand:MODEF 3 "mult_operator")
13151 (const_string "fmul")
13152 (match_operand:MODEF 3 "div_operator")
13153 (const_string "fdiv")
13154 ]
13155 (const_string "fop")))
13156 (set_attr "isa" "*,*,noavx,avx")
13157 (set_attr "prefix" "orig,orig,orig,vex")
13158 (set_attr "mode" "<MODE>")])
13159
13160 (define_insn "*rcpsf2_sse"
13161 [(set (match_operand:SF 0 "register_operand" "=x")
13162 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13163 UNSPEC_RCP))]
13164 "TARGET_SSE_MATH"
13165 "%vrcpss\t{%1, %d0|%d0, %1}"
13166 [(set_attr "type" "sse")
13167 (set_attr "atom_sse_attr" "rcp")
13168 (set_attr "btver2_sse_attr" "rcp")
13169 (set_attr "prefix" "maybe_vex")
13170 (set_attr "mode" "SF")])
13171
13172 (define_insn "*fop_<mode>_1_sse"
13173 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13174 (match_operator:MODEF 3 "binary_fp_operator"
13175 [(match_operand:MODEF 1 "register_operand" "0,x")
13176 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13177 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13178 && !COMMUTATIVE_ARITH_P (operands[3])"
13179 "* return output_387_binary_op (insn, operands);"
13180 [(set (attr "type")
13181 (cond [(match_operand:MODEF 3 "mult_operator")
13182 (const_string "ssemul")
13183 (match_operand:MODEF 3 "div_operator")
13184 (const_string "ssediv")
13185 ]
13186 (const_string "sseadd")))
13187 (set_attr "isa" "noavx,avx")
13188 (set_attr "prefix" "orig,vex")
13189 (set_attr "mode" "<MODE>")])
13190
13191 ;; This pattern is not fully shadowed by the pattern above.
13192 (define_insn "*fop_<mode>_1_i387"
13193 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13194 (match_operator:MODEF 3 "binary_fp_operator"
13195 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13196 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13197 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13198 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13199 && !COMMUTATIVE_ARITH_P (operands[3])
13200 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13201 "* return output_387_binary_op (insn, operands);"
13202 [(set (attr "type")
13203 (cond [(match_operand:MODEF 3 "mult_operator")
13204 (const_string "fmul")
13205 (match_operand:MODEF 3 "div_operator")
13206 (const_string "fdiv")
13207 ]
13208 (const_string "fop")))
13209 (set_attr "mode" "<MODE>")])
13210
13211 ;; ??? Add SSE splitters for these!
13212 (define_insn "*fop_<MODEF:mode>_2_i387"
13213 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13214 (match_operator:MODEF 3 "binary_fp_operator"
13215 [(float:MODEF
13216 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13217 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13218 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13219 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13220 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13221 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13222 [(set (attr "type")
13223 (cond [(match_operand:MODEF 3 "mult_operator")
13224 (const_string "fmul")
13225 (match_operand:MODEF 3 "div_operator")
13226 (const_string "fdiv")
13227 ]
13228 (const_string "fop")))
13229 (set_attr "fp_int_src" "true")
13230 (set_attr "mode" "<SWI24:MODE>")])
13231
13232 (define_insn "*fop_<MODEF:mode>_3_i387"
13233 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13234 (match_operator:MODEF 3 "binary_fp_operator"
13235 [(match_operand:MODEF 1 "register_operand" "0,0")
13236 (float:MODEF
13237 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13238 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13239 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13240 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13241 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13242 [(set (attr "type")
13243 (cond [(match_operand:MODEF 3 "mult_operator")
13244 (const_string "fmul")
13245 (match_operand:MODEF 3 "div_operator")
13246 (const_string "fdiv")
13247 ]
13248 (const_string "fop")))
13249 (set_attr "fp_int_src" "true")
13250 (set_attr "mode" "<MODE>")])
13251
13252 (define_insn "*fop_df_4_i387"
13253 [(set (match_operand:DF 0 "register_operand" "=f,f")
13254 (match_operator:DF 3 "binary_fp_operator"
13255 [(float_extend:DF
13256 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13257 (match_operand:DF 2 "register_operand" "0,f")]))]
13258 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13259 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13260 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13261 "* return output_387_binary_op (insn, operands);"
13262 [(set (attr "type")
13263 (cond [(match_operand:DF 3 "mult_operator")
13264 (const_string "fmul")
13265 (match_operand:DF 3 "div_operator")
13266 (const_string "fdiv")
13267 ]
13268 (const_string "fop")))
13269 (set_attr "mode" "SF")])
13270
13271 (define_insn "*fop_df_5_i387"
13272 [(set (match_operand:DF 0 "register_operand" "=f,f")
13273 (match_operator:DF 3 "binary_fp_operator"
13274 [(match_operand:DF 1 "register_operand" "0,f")
13275 (float_extend:DF
13276 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13277 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13278 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13279 "* return output_387_binary_op (insn, operands);"
13280 [(set (attr "type")
13281 (cond [(match_operand:DF 3 "mult_operator")
13282 (const_string "fmul")
13283 (match_operand:DF 3 "div_operator")
13284 (const_string "fdiv")
13285 ]
13286 (const_string "fop")))
13287 (set_attr "mode" "SF")])
13288
13289 (define_insn "*fop_df_6_i387"
13290 [(set (match_operand:DF 0 "register_operand" "=f,f")
13291 (match_operator:DF 3 "binary_fp_operator"
13292 [(float_extend:DF
13293 (match_operand:SF 1 "register_operand" "0,f"))
13294 (float_extend:DF
13295 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13296 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13297 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13298 "* return output_387_binary_op (insn, operands);"
13299 [(set (attr "type")
13300 (cond [(match_operand:DF 3 "mult_operator")
13301 (const_string "fmul")
13302 (match_operand:DF 3 "div_operator")
13303 (const_string "fdiv")
13304 ]
13305 (const_string "fop")))
13306 (set_attr "mode" "SF")])
13307
13308 (define_insn "*fop_xf_comm_i387"
13309 [(set (match_operand:XF 0 "register_operand" "=f")
13310 (match_operator:XF 3 "binary_fp_operator"
13311 [(match_operand:XF 1 "register_operand" "%0")
13312 (match_operand:XF 2 "register_operand" "f")]))]
13313 "TARGET_80387
13314 && COMMUTATIVE_ARITH_P (operands[3])"
13315 "* return output_387_binary_op (insn, operands);"
13316 [(set (attr "type")
13317 (if_then_else (match_operand:XF 3 "mult_operator")
13318 (const_string "fmul")
13319 (const_string "fop")))
13320 (set_attr "mode" "XF")])
13321
13322 (define_insn "*fop_xf_1_i387"
13323 [(set (match_operand:XF 0 "register_operand" "=f,f")
13324 (match_operator:XF 3 "binary_fp_operator"
13325 [(match_operand:XF 1 "register_operand" "0,f")
13326 (match_operand:XF 2 "register_operand" "f,0")]))]
13327 "TARGET_80387
13328 && !COMMUTATIVE_ARITH_P (operands[3])"
13329 "* return output_387_binary_op (insn, operands);"
13330 [(set (attr "type")
13331 (cond [(match_operand:XF 3 "mult_operator")
13332 (const_string "fmul")
13333 (match_operand:XF 3 "div_operator")
13334 (const_string "fdiv")
13335 ]
13336 (const_string "fop")))
13337 (set_attr "mode" "XF")])
13338
13339 (define_insn "*fop_xf_2_i387"
13340 [(set (match_operand:XF 0 "register_operand" "=f,f")
13341 (match_operator:XF 3 "binary_fp_operator"
13342 [(float:XF
13343 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13344 (match_operand:XF 2 "register_operand" "0,0")]))]
13345 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13346 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13347 [(set (attr "type")
13348 (cond [(match_operand:XF 3 "mult_operator")
13349 (const_string "fmul")
13350 (match_operand:XF 3 "div_operator")
13351 (const_string "fdiv")
13352 ]
13353 (const_string "fop")))
13354 (set_attr "fp_int_src" "true")
13355 (set_attr "mode" "<MODE>")])
13356
13357 (define_insn "*fop_xf_3_i387"
13358 [(set (match_operand:XF 0 "register_operand" "=f,f")
13359 (match_operator:XF 3 "binary_fp_operator"
13360 [(match_operand:XF 1 "register_operand" "0,0")
13361 (float:XF
13362 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13363 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13364 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13365 [(set (attr "type")
13366 (cond [(match_operand:XF 3 "mult_operator")
13367 (const_string "fmul")
13368 (match_operand:XF 3 "div_operator")
13369 (const_string "fdiv")
13370 ]
13371 (const_string "fop")))
13372 (set_attr "fp_int_src" "true")
13373 (set_attr "mode" "<MODE>")])
13374
13375 (define_insn "*fop_xf_4_i387"
13376 [(set (match_operand:XF 0 "register_operand" "=f,f")
13377 (match_operator:XF 3 "binary_fp_operator"
13378 [(float_extend:XF
13379 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13380 (match_operand:XF 2 "register_operand" "0,f")]))]
13381 "TARGET_80387"
13382 "* return output_387_binary_op (insn, operands);"
13383 [(set (attr "type")
13384 (cond [(match_operand:XF 3 "mult_operator")
13385 (const_string "fmul")
13386 (match_operand:XF 3 "div_operator")
13387 (const_string "fdiv")
13388 ]
13389 (const_string "fop")))
13390 (set_attr "mode" "<MODE>")])
13391
13392 (define_insn "*fop_xf_5_i387"
13393 [(set (match_operand:XF 0 "register_operand" "=f,f")
13394 (match_operator:XF 3 "binary_fp_operator"
13395 [(match_operand:XF 1 "register_operand" "0,f")
13396 (float_extend:XF
13397 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13398 "TARGET_80387"
13399 "* return output_387_binary_op (insn, operands);"
13400 [(set (attr "type")
13401 (cond [(match_operand:XF 3 "mult_operator")
13402 (const_string "fmul")
13403 (match_operand:XF 3 "div_operator")
13404 (const_string "fdiv")
13405 ]
13406 (const_string "fop")))
13407 (set_attr "mode" "<MODE>")])
13408
13409 (define_insn "*fop_xf_6_i387"
13410 [(set (match_operand:XF 0 "register_operand" "=f,f")
13411 (match_operator:XF 3 "binary_fp_operator"
13412 [(float_extend:XF
13413 (match_operand:MODEF 1 "register_operand" "0,f"))
13414 (float_extend:XF
13415 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13416 "TARGET_80387"
13417 "* return output_387_binary_op (insn, operands);"
13418 [(set (attr "type")
13419 (cond [(match_operand:XF 3 "mult_operator")
13420 (const_string "fmul")
13421 (match_operand:XF 3 "div_operator")
13422 (const_string "fdiv")
13423 ]
13424 (const_string "fop")))
13425 (set_attr "mode" "<MODE>")])
13426
13427 (define_split
13428 [(set (match_operand 0 "register_operand")
13429 (match_operator 3 "binary_fp_operator"
13430 [(float (match_operand:SWI24 1 "register_operand"))
13431 (match_operand 2 "register_operand")]))]
13432 "reload_completed
13433 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13434 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13435 [(const_int 0)]
13436 {
13437 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13438 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13439 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13440 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13441 GET_MODE (operands[3]),
13442 operands[4],
13443 operands[2])));
13444 ix86_free_from_memory (GET_MODE (operands[1]));
13445 DONE;
13446 })
13447
13448 (define_split
13449 [(set (match_operand 0 "register_operand")
13450 (match_operator 3 "binary_fp_operator"
13451 [(match_operand 1 "register_operand")
13452 (float (match_operand:SWI24 2 "register_operand"))]))]
13453 "reload_completed
13454 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13455 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13456 [(const_int 0)]
13457 {
13458 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13459 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13460 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13461 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13462 GET_MODE (operands[3]),
13463 operands[1],
13464 operands[4])));
13465 ix86_free_from_memory (GET_MODE (operands[2]));
13466 DONE;
13467 })
13468 \f
13469 ;; FPU special functions.
13470
13471 ;; This pattern implements a no-op XFmode truncation for
13472 ;; all fancy i386 XFmode math functions.
13473
13474 (define_insn "truncxf<mode>2_i387_noop_unspec"
13475 [(set (match_operand:MODEF 0 "register_operand" "=f")
13476 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13477 UNSPEC_TRUNC_NOOP))]
13478 "TARGET_USE_FANCY_MATH_387"
13479 "* return output_387_reg_move (insn, operands);"
13480 [(set_attr "type" "fmov")
13481 (set_attr "mode" "<MODE>")])
13482
13483 (define_insn "sqrtxf2"
13484 [(set (match_operand:XF 0 "register_operand" "=f")
13485 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13486 "TARGET_USE_FANCY_MATH_387"
13487 "fsqrt"
13488 [(set_attr "type" "fpspc")
13489 (set_attr "mode" "XF")
13490 (set_attr "athlon_decode" "direct")
13491 (set_attr "amdfam10_decode" "direct")
13492 (set_attr "bdver1_decode" "direct")])
13493
13494 (define_insn "sqrt_extend<mode>xf2_i387"
13495 [(set (match_operand:XF 0 "register_operand" "=f")
13496 (sqrt:XF
13497 (float_extend:XF
13498 (match_operand:MODEF 1 "register_operand" "0"))))]
13499 "TARGET_USE_FANCY_MATH_387"
13500 "fsqrt"
13501 [(set_attr "type" "fpspc")
13502 (set_attr "mode" "XF")
13503 (set_attr "athlon_decode" "direct")
13504 (set_attr "amdfam10_decode" "direct")
13505 (set_attr "bdver1_decode" "direct")])
13506
13507 (define_insn "*rsqrtsf2_sse"
13508 [(set (match_operand:SF 0 "register_operand" "=x")
13509 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13510 UNSPEC_RSQRT))]
13511 "TARGET_SSE_MATH"
13512 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13513 [(set_attr "type" "sse")
13514 (set_attr "atom_sse_attr" "rcp")
13515 (set_attr "btver2_sse_attr" "rcp")
13516 (set_attr "prefix" "maybe_vex")
13517 (set_attr "mode" "SF")])
13518
13519 (define_expand "rsqrtsf2"
13520 [(set (match_operand:SF 0 "register_operand")
13521 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13522 UNSPEC_RSQRT))]
13523 "TARGET_SSE_MATH"
13524 {
13525 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13526 DONE;
13527 })
13528
13529 (define_insn "*sqrt<mode>2_sse"
13530 [(set (match_operand:MODEF 0 "register_operand" "=x")
13531 (sqrt:MODEF
13532 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13533 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13534 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13535 [(set_attr "type" "sse")
13536 (set_attr "atom_sse_attr" "sqrt")
13537 (set_attr "btver2_sse_attr" "sqrt")
13538 (set_attr "prefix" "maybe_vex")
13539 (set_attr "mode" "<MODE>")
13540 (set_attr "athlon_decode" "*")
13541 (set_attr "amdfam10_decode" "*")
13542 (set_attr "bdver1_decode" "*")])
13543
13544 (define_expand "sqrt<mode>2"
13545 [(set (match_operand:MODEF 0 "register_operand")
13546 (sqrt:MODEF
13547 (match_operand:MODEF 1 "nonimmediate_operand")))]
13548 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13549 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13550 {
13551 if (<MODE>mode == SFmode
13552 && TARGET_SSE_MATH
13553 && TARGET_RECIP_SQRT
13554 && !optimize_function_for_size_p (cfun)
13555 && flag_finite_math_only && !flag_trapping_math
13556 && flag_unsafe_math_optimizations)
13557 {
13558 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13559 DONE;
13560 }
13561
13562 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13563 {
13564 rtx op0 = gen_reg_rtx (XFmode);
13565 rtx op1 = force_reg (<MODE>mode, operands[1]);
13566
13567 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13568 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13569 DONE;
13570 }
13571 })
13572
13573 (define_insn "fpremxf4_i387"
13574 [(set (match_operand:XF 0 "register_operand" "=f")
13575 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13576 (match_operand:XF 3 "register_operand" "1")]
13577 UNSPEC_FPREM_F))
13578 (set (match_operand:XF 1 "register_operand" "=u")
13579 (unspec:XF [(match_dup 2) (match_dup 3)]
13580 UNSPEC_FPREM_U))
13581 (set (reg:CCFP FPSR_REG)
13582 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13583 UNSPEC_C2_FLAG))]
13584 "TARGET_USE_FANCY_MATH_387"
13585 "fprem"
13586 [(set_attr "type" "fpspc")
13587 (set_attr "mode" "XF")])
13588
13589 (define_expand "fmodxf3"
13590 [(use (match_operand:XF 0 "register_operand"))
13591 (use (match_operand:XF 1 "general_operand"))
13592 (use (match_operand:XF 2 "general_operand"))]
13593 "TARGET_USE_FANCY_MATH_387"
13594 {
13595 rtx label = gen_label_rtx ();
13596
13597 rtx op1 = gen_reg_rtx (XFmode);
13598 rtx op2 = gen_reg_rtx (XFmode);
13599
13600 emit_move_insn (op2, operands[2]);
13601 emit_move_insn (op1, operands[1]);
13602
13603 emit_label (label);
13604 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13605 ix86_emit_fp_unordered_jump (label);
13606 LABEL_NUSES (label) = 1;
13607
13608 emit_move_insn (operands[0], op1);
13609 DONE;
13610 })
13611
13612 (define_expand "fmod<mode>3"
13613 [(use (match_operand:MODEF 0 "register_operand"))
13614 (use (match_operand:MODEF 1 "general_operand"))
13615 (use (match_operand:MODEF 2 "general_operand"))]
13616 "TARGET_USE_FANCY_MATH_387"
13617 {
13618 rtx (*gen_truncxf) (rtx, rtx);
13619
13620 rtx label = gen_label_rtx ();
13621
13622 rtx op1 = gen_reg_rtx (XFmode);
13623 rtx op2 = gen_reg_rtx (XFmode);
13624
13625 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13626 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13627
13628 emit_label (label);
13629 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13630 ix86_emit_fp_unordered_jump (label);
13631 LABEL_NUSES (label) = 1;
13632
13633 /* Truncate the result properly for strict SSE math. */
13634 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13635 && !TARGET_MIX_SSE_I387)
13636 gen_truncxf = gen_truncxf<mode>2;
13637 else
13638 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13639
13640 emit_insn (gen_truncxf (operands[0], op1));
13641 DONE;
13642 })
13643
13644 (define_insn "fprem1xf4_i387"
13645 [(set (match_operand:XF 0 "register_operand" "=f")
13646 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13647 (match_operand:XF 3 "register_operand" "1")]
13648 UNSPEC_FPREM1_F))
13649 (set (match_operand:XF 1 "register_operand" "=u")
13650 (unspec:XF [(match_dup 2) (match_dup 3)]
13651 UNSPEC_FPREM1_U))
13652 (set (reg:CCFP FPSR_REG)
13653 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13654 UNSPEC_C2_FLAG))]
13655 "TARGET_USE_FANCY_MATH_387"
13656 "fprem1"
13657 [(set_attr "type" "fpspc")
13658 (set_attr "mode" "XF")])
13659
13660 (define_expand "remainderxf3"
13661 [(use (match_operand:XF 0 "register_operand"))
13662 (use (match_operand:XF 1 "general_operand"))
13663 (use (match_operand:XF 2 "general_operand"))]
13664 "TARGET_USE_FANCY_MATH_387"
13665 {
13666 rtx label = gen_label_rtx ();
13667
13668 rtx op1 = gen_reg_rtx (XFmode);
13669 rtx op2 = gen_reg_rtx (XFmode);
13670
13671 emit_move_insn (op2, operands[2]);
13672 emit_move_insn (op1, operands[1]);
13673
13674 emit_label (label);
13675 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13676 ix86_emit_fp_unordered_jump (label);
13677 LABEL_NUSES (label) = 1;
13678
13679 emit_move_insn (operands[0], op1);
13680 DONE;
13681 })
13682
13683 (define_expand "remainder<mode>3"
13684 [(use (match_operand:MODEF 0 "register_operand"))
13685 (use (match_operand:MODEF 1 "general_operand"))
13686 (use (match_operand:MODEF 2 "general_operand"))]
13687 "TARGET_USE_FANCY_MATH_387"
13688 {
13689 rtx (*gen_truncxf) (rtx, rtx);
13690
13691 rtx label = gen_label_rtx ();
13692
13693 rtx op1 = gen_reg_rtx (XFmode);
13694 rtx op2 = gen_reg_rtx (XFmode);
13695
13696 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13697 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13698
13699 emit_label (label);
13700
13701 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13702 ix86_emit_fp_unordered_jump (label);
13703 LABEL_NUSES (label) = 1;
13704
13705 /* Truncate the result properly for strict SSE math. */
13706 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13707 && !TARGET_MIX_SSE_I387)
13708 gen_truncxf = gen_truncxf<mode>2;
13709 else
13710 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13711
13712 emit_insn (gen_truncxf (operands[0], op1));
13713 DONE;
13714 })
13715
13716 (define_int_iterator SINCOS
13717 [UNSPEC_SIN
13718 UNSPEC_COS])
13719
13720 (define_int_attr sincos
13721 [(UNSPEC_SIN "sin")
13722 (UNSPEC_COS "cos")])
13723
13724 (define_insn "*<sincos>xf2_i387"
13725 [(set (match_operand:XF 0 "register_operand" "=f")
13726 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13727 SINCOS))]
13728 "TARGET_USE_FANCY_MATH_387
13729 && flag_unsafe_math_optimizations"
13730 "f<sincos>"
13731 [(set_attr "type" "fpspc")
13732 (set_attr "mode" "XF")])
13733
13734 (define_insn "*<sincos>_extend<mode>xf2_i387"
13735 [(set (match_operand:XF 0 "register_operand" "=f")
13736 (unspec:XF [(float_extend:XF
13737 (match_operand:MODEF 1 "register_operand" "0"))]
13738 SINCOS))]
13739 "TARGET_USE_FANCY_MATH_387
13740 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13741 || TARGET_MIX_SSE_I387)
13742 && flag_unsafe_math_optimizations"
13743 "f<sincos>"
13744 [(set_attr "type" "fpspc")
13745 (set_attr "mode" "XF")])
13746
13747 ;; When sincos pattern is defined, sin and cos builtin functions will be
13748 ;; expanded to sincos pattern with one of its outputs left unused.
13749 ;; CSE pass will figure out if two sincos patterns can be combined,
13750 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13751 ;; depending on the unused output.
13752
13753 (define_insn "sincosxf3"
13754 [(set (match_operand:XF 0 "register_operand" "=f")
13755 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13756 UNSPEC_SINCOS_COS))
13757 (set (match_operand:XF 1 "register_operand" "=u")
13758 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13759 "TARGET_USE_FANCY_MATH_387
13760 && flag_unsafe_math_optimizations"
13761 "fsincos"
13762 [(set_attr "type" "fpspc")
13763 (set_attr "mode" "XF")])
13764
13765 (define_split
13766 [(set (match_operand:XF 0 "register_operand")
13767 (unspec:XF [(match_operand:XF 2 "register_operand")]
13768 UNSPEC_SINCOS_COS))
13769 (set (match_operand:XF 1 "register_operand")
13770 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13771 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13772 && can_create_pseudo_p ()"
13773 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13774
13775 (define_split
13776 [(set (match_operand:XF 0 "register_operand")
13777 (unspec:XF [(match_operand:XF 2 "register_operand")]
13778 UNSPEC_SINCOS_COS))
13779 (set (match_operand:XF 1 "register_operand")
13780 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13781 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13782 && can_create_pseudo_p ()"
13783 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13784
13785 (define_insn "sincos_extend<mode>xf3_i387"
13786 [(set (match_operand:XF 0 "register_operand" "=f")
13787 (unspec:XF [(float_extend:XF
13788 (match_operand:MODEF 2 "register_operand" "0"))]
13789 UNSPEC_SINCOS_COS))
13790 (set (match_operand:XF 1 "register_operand" "=u")
13791 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13792 "TARGET_USE_FANCY_MATH_387
13793 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13794 || TARGET_MIX_SSE_I387)
13795 && flag_unsafe_math_optimizations"
13796 "fsincos"
13797 [(set_attr "type" "fpspc")
13798 (set_attr "mode" "XF")])
13799
13800 (define_split
13801 [(set (match_operand:XF 0 "register_operand")
13802 (unspec:XF [(float_extend:XF
13803 (match_operand:MODEF 2 "register_operand"))]
13804 UNSPEC_SINCOS_COS))
13805 (set (match_operand:XF 1 "register_operand")
13806 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13807 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13808 && can_create_pseudo_p ()"
13809 [(set (match_dup 1)
13810 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13811
13812 (define_split
13813 [(set (match_operand:XF 0 "register_operand")
13814 (unspec:XF [(float_extend:XF
13815 (match_operand:MODEF 2 "register_operand"))]
13816 UNSPEC_SINCOS_COS))
13817 (set (match_operand:XF 1 "register_operand")
13818 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13819 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13820 && can_create_pseudo_p ()"
13821 [(set (match_dup 0)
13822 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13823
13824 (define_expand "sincos<mode>3"
13825 [(use (match_operand:MODEF 0 "register_operand"))
13826 (use (match_operand:MODEF 1 "register_operand"))
13827 (use (match_operand:MODEF 2 "register_operand"))]
13828 "TARGET_USE_FANCY_MATH_387
13829 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13830 || TARGET_MIX_SSE_I387)
13831 && flag_unsafe_math_optimizations"
13832 {
13833 rtx op0 = gen_reg_rtx (XFmode);
13834 rtx op1 = gen_reg_rtx (XFmode);
13835
13836 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13837 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13839 DONE;
13840 })
13841
13842 (define_insn "fptanxf4_i387"
13843 [(set (match_operand:XF 0 "register_operand" "=f")
13844 (match_operand:XF 3 "const_double_operand" "F"))
13845 (set (match_operand:XF 1 "register_operand" "=u")
13846 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13847 UNSPEC_TAN))]
13848 "TARGET_USE_FANCY_MATH_387
13849 && flag_unsafe_math_optimizations
13850 && standard_80387_constant_p (operands[3]) == 2"
13851 "fptan"
13852 [(set_attr "type" "fpspc")
13853 (set_attr "mode" "XF")])
13854
13855 (define_insn "fptan_extend<mode>xf4_i387"
13856 [(set (match_operand:MODEF 0 "register_operand" "=f")
13857 (match_operand:MODEF 3 "const_double_operand" "F"))
13858 (set (match_operand:XF 1 "register_operand" "=u")
13859 (unspec:XF [(float_extend:XF
13860 (match_operand:MODEF 2 "register_operand" "0"))]
13861 UNSPEC_TAN))]
13862 "TARGET_USE_FANCY_MATH_387
13863 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13864 || TARGET_MIX_SSE_I387)
13865 && flag_unsafe_math_optimizations
13866 && standard_80387_constant_p (operands[3]) == 2"
13867 "fptan"
13868 [(set_attr "type" "fpspc")
13869 (set_attr "mode" "XF")])
13870
13871 (define_expand "tanxf2"
13872 [(use (match_operand:XF 0 "register_operand"))
13873 (use (match_operand:XF 1 "register_operand"))]
13874 "TARGET_USE_FANCY_MATH_387
13875 && flag_unsafe_math_optimizations"
13876 {
13877 rtx one = gen_reg_rtx (XFmode);
13878 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13879
13880 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13881 DONE;
13882 })
13883
13884 (define_expand "tan<mode>2"
13885 [(use (match_operand:MODEF 0 "register_operand"))
13886 (use (match_operand:MODEF 1 "register_operand"))]
13887 "TARGET_USE_FANCY_MATH_387
13888 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13889 || TARGET_MIX_SSE_I387)
13890 && flag_unsafe_math_optimizations"
13891 {
13892 rtx op0 = gen_reg_rtx (XFmode);
13893
13894 rtx one = gen_reg_rtx (<MODE>mode);
13895 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13896
13897 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13898 operands[1], op2));
13899 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13900 DONE;
13901 })
13902
13903 (define_insn "*fpatanxf3_i387"
13904 [(set (match_operand:XF 0 "register_operand" "=f")
13905 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13906 (match_operand:XF 2 "register_operand" "u")]
13907 UNSPEC_FPATAN))
13908 (clobber (match_scratch:XF 3 "=2"))]
13909 "TARGET_USE_FANCY_MATH_387
13910 && flag_unsafe_math_optimizations"
13911 "fpatan"
13912 [(set_attr "type" "fpspc")
13913 (set_attr "mode" "XF")])
13914
13915 (define_insn "fpatan_extend<mode>xf3_i387"
13916 [(set (match_operand:XF 0 "register_operand" "=f")
13917 (unspec:XF [(float_extend:XF
13918 (match_operand:MODEF 1 "register_operand" "0"))
13919 (float_extend:XF
13920 (match_operand:MODEF 2 "register_operand" "u"))]
13921 UNSPEC_FPATAN))
13922 (clobber (match_scratch:XF 3 "=2"))]
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 "fpatan"
13928 [(set_attr "type" "fpspc")
13929 (set_attr "mode" "XF")])
13930
13931 (define_expand "atan2xf3"
13932 [(parallel [(set (match_operand:XF 0 "register_operand")
13933 (unspec:XF [(match_operand:XF 2 "register_operand")
13934 (match_operand:XF 1 "register_operand")]
13935 UNSPEC_FPATAN))
13936 (clobber (match_scratch:XF 3))])]
13937 "TARGET_USE_FANCY_MATH_387
13938 && flag_unsafe_math_optimizations")
13939
13940 (define_expand "atan2<mode>3"
13941 [(use (match_operand:MODEF 0 "register_operand"))
13942 (use (match_operand:MODEF 1 "register_operand"))
13943 (use (match_operand:MODEF 2 "register_operand"))]
13944 "TARGET_USE_FANCY_MATH_387
13945 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13946 || TARGET_MIX_SSE_I387)
13947 && flag_unsafe_math_optimizations"
13948 {
13949 rtx op0 = gen_reg_rtx (XFmode);
13950
13951 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13952 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13953 DONE;
13954 })
13955
13956 (define_expand "atanxf2"
13957 [(parallel [(set (match_operand:XF 0 "register_operand")
13958 (unspec:XF [(match_dup 2)
13959 (match_operand:XF 1 "register_operand")]
13960 UNSPEC_FPATAN))
13961 (clobber (match_scratch:XF 3))])]
13962 "TARGET_USE_FANCY_MATH_387
13963 && flag_unsafe_math_optimizations"
13964 {
13965 operands[2] = gen_reg_rtx (XFmode);
13966 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13967 })
13968
13969 (define_expand "atan<mode>2"
13970 [(use (match_operand:MODEF 0 "register_operand"))
13971 (use (match_operand:MODEF 1 "register_operand"))]
13972 "TARGET_USE_FANCY_MATH_387
13973 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13974 || TARGET_MIX_SSE_I387)
13975 && flag_unsafe_math_optimizations"
13976 {
13977 rtx op0 = gen_reg_rtx (XFmode);
13978
13979 rtx op2 = gen_reg_rtx (<MODE>mode);
13980 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13981
13982 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13983 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13984 DONE;
13985 })
13986
13987 (define_expand "asinxf2"
13988 [(set (match_dup 2)
13989 (mult:XF (match_operand:XF 1 "register_operand")
13990 (match_dup 1)))
13991 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13992 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13993 (parallel [(set (match_operand:XF 0 "register_operand")
13994 (unspec:XF [(match_dup 5) (match_dup 1)]
13995 UNSPEC_FPATAN))
13996 (clobber (match_scratch:XF 6))])]
13997 "TARGET_USE_FANCY_MATH_387
13998 && flag_unsafe_math_optimizations"
13999 {
14000 int i;
14001
14002 if (optimize_insn_for_size_p ())
14003 FAIL;
14004
14005 for (i = 2; i < 6; i++)
14006 operands[i] = gen_reg_rtx (XFmode);
14007
14008 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14009 })
14010
14011 (define_expand "asin<mode>2"
14012 [(use (match_operand:MODEF 0 "register_operand"))
14013 (use (match_operand:MODEF 1 "general_operand"))]
14014 "TARGET_USE_FANCY_MATH_387
14015 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14016 || TARGET_MIX_SSE_I387)
14017 && flag_unsafe_math_optimizations"
14018 {
14019 rtx op0 = gen_reg_rtx (XFmode);
14020 rtx op1 = gen_reg_rtx (XFmode);
14021
14022 if (optimize_insn_for_size_p ())
14023 FAIL;
14024
14025 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14026 emit_insn (gen_asinxf2 (op0, op1));
14027 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14028 DONE;
14029 })
14030
14031 (define_expand "acosxf2"
14032 [(set (match_dup 2)
14033 (mult:XF (match_operand:XF 1 "register_operand")
14034 (match_dup 1)))
14035 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14036 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14037 (parallel [(set (match_operand:XF 0 "register_operand")
14038 (unspec:XF [(match_dup 1) (match_dup 5)]
14039 UNSPEC_FPATAN))
14040 (clobber (match_scratch:XF 6))])]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14043 {
14044 int i;
14045
14046 if (optimize_insn_for_size_p ())
14047 FAIL;
14048
14049 for (i = 2; i < 6; i++)
14050 operands[i] = gen_reg_rtx (XFmode);
14051
14052 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14053 })
14054
14055 (define_expand "acos<mode>2"
14056 [(use (match_operand:MODEF 0 "register_operand"))
14057 (use (match_operand:MODEF 1 "general_operand"))]
14058 "TARGET_USE_FANCY_MATH_387
14059 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14060 || TARGET_MIX_SSE_I387)
14061 && flag_unsafe_math_optimizations"
14062 {
14063 rtx op0 = gen_reg_rtx (XFmode);
14064 rtx op1 = gen_reg_rtx (XFmode);
14065
14066 if (optimize_insn_for_size_p ())
14067 FAIL;
14068
14069 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14070 emit_insn (gen_acosxf2 (op0, op1));
14071 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14072 DONE;
14073 })
14074
14075 (define_insn "fyl2xxf3_i387"
14076 [(set (match_operand:XF 0 "register_operand" "=f")
14077 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14078 (match_operand:XF 2 "register_operand" "u")]
14079 UNSPEC_FYL2X))
14080 (clobber (match_scratch:XF 3 "=2"))]
14081 "TARGET_USE_FANCY_MATH_387
14082 && flag_unsafe_math_optimizations"
14083 "fyl2x"
14084 [(set_attr "type" "fpspc")
14085 (set_attr "mode" "XF")])
14086
14087 (define_insn "fyl2x_extend<mode>xf3_i387"
14088 [(set (match_operand:XF 0 "register_operand" "=f")
14089 (unspec:XF [(float_extend:XF
14090 (match_operand:MODEF 1 "register_operand" "0"))
14091 (match_operand:XF 2 "register_operand" "u")]
14092 UNSPEC_FYL2X))
14093 (clobber (match_scratch:XF 3 "=2"))]
14094 "TARGET_USE_FANCY_MATH_387
14095 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14096 || TARGET_MIX_SSE_I387)
14097 && flag_unsafe_math_optimizations"
14098 "fyl2x"
14099 [(set_attr "type" "fpspc")
14100 (set_attr "mode" "XF")])
14101
14102 (define_expand "logxf2"
14103 [(parallel [(set (match_operand:XF 0 "register_operand")
14104 (unspec:XF [(match_operand:XF 1 "register_operand")
14105 (match_dup 2)] UNSPEC_FYL2X))
14106 (clobber (match_scratch:XF 3))])]
14107 "TARGET_USE_FANCY_MATH_387
14108 && flag_unsafe_math_optimizations"
14109 {
14110 operands[2] = gen_reg_rtx (XFmode);
14111 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14112 })
14113
14114 (define_expand "log<mode>2"
14115 [(use (match_operand:MODEF 0 "register_operand"))
14116 (use (match_operand:MODEF 1 "register_operand"))]
14117 "TARGET_USE_FANCY_MATH_387
14118 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14119 || TARGET_MIX_SSE_I387)
14120 && flag_unsafe_math_optimizations"
14121 {
14122 rtx op0 = gen_reg_rtx (XFmode);
14123
14124 rtx op2 = gen_reg_rtx (XFmode);
14125 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14126
14127 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14128 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14129 DONE;
14130 })
14131
14132 (define_expand "log10xf2"
14133 [(parallel [(set (match_operand:XF 0 "register_operand")
14134 (unspec:XF [(match_operand:XF 1 "register_operand")
14135 (match_dup 2)] UNSPEC_FYL2X))
14136 (clobber (match_scratch:XF 3))])]
14137 "TARGET_USE_FANCY_MATH_387
14138 && flag_unsafe_math_optimizations"
14139 {
14140 operands[2] = gen_reg_rtx (XFmode);
14141 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14142 })
14143
14144 (define_expand "log10<mode>2"
14145 [(use (match_operand:MODEF 0 "register_operand"))
14146 (use (match_operand:MODEF 1 "register_operand"))]
14147 "TARGET_USE_FANCY_MATH_387
14148 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14149 || TARGET_MIX_SSE_I387)
14150 && flag_unsafe_math_optimizations"
14151 {
14152 rtx op0 = gen_reg_rtx (XFmode);
14153
14154 rtx op2 = gen_reg_rtx (XFmode);
14155 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14156
14157 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14158 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14159 DONE;
14160 })
14161
14162 (define_expand "log2xf2"
14163 [(parallel [(set (match_operand:XF 0 "register_operand")
14164 (unspec:XF [(match_operand:XF 1 "register_operand")
14165 (match_dup 2)] UNSPEC_FYL2X))
14166 (clobber (match_scratch:XF 3))])]
14167 "TARGET_USE_FANCY_MATH_387
14168 && flag_unsafe_math_optimizations"
14169 {
14170 operands[2] = gen_reg_rtx (XFmode);
14171 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14172 })
14173
14174 (define_expand "log2<mode>2"
14175 [(use (match_operand:MODEF 0 "register_operand"))
14176 (use (match_operand:MODEF 1 "register_operand"))]
14177 "TARGET_USE_FANCY_MATH_387
14178 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14179 || TARGET_MIX_SSE_I387)
14180 && flag_unsafe_math_optimizations"
14181 {
14182 rtx op0 = gen_reg_rtx (XFmode);
14183
14184 rtx op2 = gen_reg_rtx (XFmode);
14185 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14186
14187 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14188 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14189 DONE;
14190 })
14191
14192 (define_insn "fyl2xp1xf3_i387"
14193 [(set (match_operand:XF 0 "register_operand" "=f")
14194 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14195 (match_operand:XF 2 "register_operand" "u")]
14196 UNSPEC_FYL2XP1))
14197 (clobber (match_scratch:XF 3 "=2"))]
14198 "TARGET_USE_FANCY_MATH_387
14199 && flag_unsafe_math_optimizations"
14200 "fyl2xp1"
14201 [(set_attr "type" "fpspc")
14202 (set_attr "mode" "XF")])
14203
14204 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14205 [(set (match_operand:XF 0 "register_operand" "=f")
14206 (unspec:XF [(float_extend:XF
14207 (match_operand:MODEF 1 "register_operand" "0"))
14208 (match_operand:XF 2 "register_operand" "u")]
14209 UNSPEC_FYL2XP1))
14210 (clobber (match_scratch:XF 3 "=2"))]
14211 "TARGET_USE_FANCY_MATH_387
14212 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14213 || TARGET_MIX_SSE_I387)
14214 && flag_unsafe_math_optimizations"
14215 "fyl2xp1"
14216 [(set_attr "type" "fpspc")
14217 (set_attr "mode" "XF")])
14218
14219 (define_expand "log1pxf2"
14220 [(use (match_operand:XF 0 "register_operand"))
14221 (use (match_operand:XF 1 "register_operand"))]
14222 "TARGET_USE_FANCY_MATH_387
14223 && flag_unsafe_math_optimizations"
14224 {
14225 if (optimize_insn_for_size_p ())
14226 FAIL;
14227
14228 ix86_emit_i387_log1p (operands[0], operands[1]);
14229 DONE;
14230 })
14231
14232 (define_expand "log1p<mode>2"
14233 [(use (match_operand:MODEF 0 "register_operand"))
14234 (use (match_operand:MODEF 1 "register_operand"))]
14235 "TARGET_USE_FANCY_MATH_387
14236 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14237 || TARGET_MIX_SSE_I387)
14238 && flag_unsafe_math_optimizations"
14239 {
14240 rtx op0;
14241
14242 if (optimize_insn_for_size_p ())
14243 FAIL;
14244
14245 op0 = gen_reg_rtx (XFmode);
14246
14247 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14248
14249 ix86_emit_i387_log1p (op0, operands[1]);
14250 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14251 DONE;
14252 })
14253
14254 (define_insn "fxtractxf3_i387"
14255 [(set (match_operand:XF 0 "register_operand" "=f")
14256 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14257 UNSPEC_XTRACT_FRACT))
14258 (set (match_operand:XF 1 "register_operand" "=u")
14259 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14260 "TARGET_USE_FANCY_MATH_387
14261 && flag_unsafe_math_optimizations"
14262 "fxtract"
14263 [(set_attr "type" "fpspc")
14264 (set_attr "mode" "XF")])
14265
14266 (define_insn "fxtract_extend<mode>xf3_i387"
14267 [(set (match_operand:XF 0 "register_operand" "=f")
14268 (unspec:XF [(float_extend:XF
14269 (match_operand:MODEF 2 "register_operand" "0"))]
14270 UNSPEC_XTRACT_FRACT))
14271 (set (match_operand:XF 1 "register_operand" "=u")
14272 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14273 "TARGET_USE_FANCY_MATH_387
14274 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14275 || TARGET_MIX_SSE_I387)
14276 && flag_unsafe_math_optimizations"
14277 "fxtract"
14278 [(set_attr "type" "fpspc")
14279 (set_attr "mode" "XF")])
14280
14281 (define_expand "logbxf2"
14282 [(parallel [(set (match_dup 2)
14283 (unspec:XF [(match_operand:XF 1 "register_operand")]
14284 UNSPEC_XTRACT_FRACT))
14285 (set (match_operand:XF 0 "register_operand")
14286 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14287 "TARGET_USE_FANCY_MATH_387
14288 && flag_unsafe_math_optimizations"
14289 "operands[2] = gen_reg_rtx (XFmode);")
14290
14291 (define_expand "logb<mode>2"
14292 [(use (match_operand:MODEF 0 "register_operand"))
14293 (use (match_operand:MODEF 1 "register_operand"))]
14294 "TARGET_USE_FANCY_MATH_387
14295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14296 || TARGET_MIX_SSE_I387)
14297 && flag_unsafe_math_optimizations"
14298 {
14299 rtx op0 = gen_reg_rtx (XFmode);
14300 rtx op1 = gen_reg_rtx (XFmode);
14301
14302 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14303 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14304 DONE;
14305 })
14306
14307 (define_expand "ilogbxf2"
14308 [(use (match_operand:SI 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 op0, op1;
14314
14315 if (optimize_insn_for_size_p ())
14316 FAIL;
14317
14318 op0 = gen_reg_rtx (XFmode);
14319 op1 = gen_reg_rtx (XFmode);
14320
14321 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14322 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14323 DONE;
14324 })
14325
14326 (define_expand "ilogb<mode>2"
14327 [(use (match_operand:SI 0 "register_operand"))
14328 (use (match_operand:MODEF 1 "register_operand"))]
14329 "TARGET_USE_FANCY_MATH_387
14330 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14331 || TARGET_MIX_SSE_I387)
14332 && flag_unsafe_math_optimizations"
14333 {
14334 rtx op0, op1;
14335
14336 if (optimize_insn_for_size_p ())
14337 FAIL;
14338
14339 op0 = gen_reg_rtx (XFmode);
14340 op1 = gen_reg_rtx (XFmode);
14341
14342 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14343 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14344 DONE;
14345 })
14346
14347 (define_insn "*f2xm1xf2_i387"
14348 [(set (match_operand:XF 0 "register_operand" "=f")
14349 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14350 UNSPEC_F2XM1))]
14351 "TARGET_USE_FANCY_MATH_387
14352 && flag_unsafe_math_optimizations"
14353 "f2xm1"
14354 [(set_attr "type" "fpspc")
14355 (set_attr "mode" "XF")])
14356
14357 (define_insn "*fscalexf4_i387"
14358 [(set (match_operand:XF 0 "register_operand" "=f")
14359 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14360 (match_operand:XF 3 "register_operand" "1")]
14361 UNSPEC_FSCALE_FRACT))
14362 (set (match_operand:XF 1 "register_operand" "=u")
14363 (unspec:XF [(match_dup 2) (match_dup 3)]
14364 UNSPEC_FSCALE_EXP))]
14365 "TARGET_USE_FANCY_MATH_387
14366 && flag_unsafe_math_optimizations"
14367 "fscale"
14368 [(set_attr "type" "fpspc")
14369 (set_attr "mode" "XF")])
14370
14371 (define_expand "expNcorexf3"
14372 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14373 (match_operand:XF 2 "register_operand")))
14374 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14375 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14376 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14377 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14378 (parallel [(set (match_operand:XF 0 "register_operand")
14379 (unspec:XF [(match_dup 8) (match_dup 4)]
14380 UNSPEC_FSCALE_FRACT))
14381 (set (match_dup 9)
14382 (unspec:XF [(match_dup 8) (match_dup 4)]
14383 UNSPEC_FSCALE_EXP))])]
14384 "TARGET_USE_FANCY_MATH_387
14385 && flag_unsafe_math_optimizations"
14386 {
14387 int i;
14388
14389 if (optimize_insn_for_size_p ())
14390 FAIL;
14391
14392 for (i = 3; i < 10; i++)
14393 operands[i] = gen_reg_rtx (XFmode);
14394
14395 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14396 })
14397
14398 (define_expand "expxf2"
14399 [(use (match_operand:XF 0 "register_operand"))
14400 (use (match_operand:XF 1 "register_operand"))]
14401 "TARGET_USE_FANCY_MATH_387
14402 && flag_unsafe_math_optimizations"
14403 {
14404 rtx op2;
14405
14406 if (optimize_insn_for_size_p ())
14407 FAIL;
14408
14409 op2 = gen_reg_rtx (XFmode);
14410 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14411
14412 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14413 DONE;
14414 })
14415
14416 (define_expand "exp<mode>2"
14417 [(use (match_operand:MODEF 0 "register_operand"))
14418 (use (match_operand:MODEF 1 "general_operand"))]
14419 "TARGET_USE_FANCY_MATH_387
14420 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14421 || TARGET_MIX_SSE_I387)
14422 && flag_unsafe_math_optimizations"
14423 {
14424 rtx op0, op1;
14425
14426 if (optimize_insn_for_size_p ())
14427 FAIL;
14428
14429 op0 = gen_reg_rtx (XFmode);
14430 op1 = gen_reg_rtx (XFmode);
14431
14432 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14433 emit_insn (gen_expxf2 (op0, op1));
14434 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14435 DONE;
14436 })
14437
14438 (define_expand "exp10xf2"
14439 [(use (match_operand:XF 0 "register_operand"))
14440 (use (match_operand:XF 1 "register_operand"))]
14441 "TARGET_USE_FANCY_MATH_387
14442 && flag_unsafe_math_optimizations"
14443 {
14444 rtx op2;
14445
14446 if (optimize_insn_for_size_p ())
14447 FAIL;
14448
14449 op2 = gen_reg_rtx (XFmode);
14450 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14451
14452 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14453 DONE;
14454 })
14455
14456 (define_expand "exp10<mode>2"
14457 [(use (match_operand:MODEF 0 "register_operand"))
14458 (use (match_operand:MODEF 1 "general_operand"))]
14459 "TARGET_USE_FANCY_MATH_387
14460 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14461 || TARGET_MIX_SSE_I387)
14462 && flag_unsafe_math_optimizations"
14463 {
14464 rtx op0, op1;
14465
14466 if (optimize_insn_for_size_p ())
14467 FAIL;
14468
14469 op0 = gen_reg_rtx (XFmode);
14470 op1 = gen_reg_rtx (XFmode);
14471
14472 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14473 emit_insn (gen_exp10xf2 (op0, op1));
14474 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14475 DONE;
14476 })
14477
14478 (define_expand "exp2xf2"
14479 [(use (match_operand:XF 0 "register_operand"))
14480 (use (match_operand:XF 1 "register_operand"))]
14481 "TARGET_USE_FANCY_MATH_387
14482 && flag_unsafe_math_optimizations"
14483 {
14484 rtx op2;
14485
14486 if (optimize_insn_for_size_p ())
14487 FAIL;
14488
14489 op2 = gen_reg_rtx (XFmode);
14490 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14491
14492 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14493 DONE;
14494 })
14495
14496 (define_expand "exp2<mode>2"
14497 [(use (match_operand:MODEF 0 "register_operand"))
14498 (use (match_operand:MODEF 1 "general_operand"))]
14499 "TARGET_USE_FANCY_MATH_387
14500 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14501 || TARGET_MIX_SSE_I387)
14502 && flag_unsafe_math_optimizations"
14503 {
14504 rtx op0, op1;
14505
14506 if (optimize_insn_for_size_p ())
14507 FAIL;
14508
14509 op0 = gen_reg_rtx (XFmode);
14510 op1 = gen_reg_rtx (XFmode);
14511
14512 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14513 emit_insn (gen_exp2xf2 (op0, op1));
14514 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14515 DONE;
14516 })
14517
14518 (define_expand "expm1xf2"
14519 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14520 (match_dup 2)))
14521 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14522 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14523 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14524 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14525 (parallel [(set (match_dup 7)
14526 (unspec:XF [(match_dup 6) (match_dup 4)]
14527 UNSPEC_FSCALE_FRACT))
14528 (set (match_dup 8)
14529 (unspec:XF [(match_dup 6) (match_dup 4)]
14530 UNSPEC_FSCALE_EXP))])
14531 (parallel [(set (match_dup 10)
14532 (unspec:XF [(match_dup 9) (match_dup 8)]
14533 UNSPEC_FSCALE_FRACT))
14534 (set (match_dup 11)
14535 (unspec:XF [(match_dup 9) (match_dup 8)]
14536 UNSPEC_FSCALE_EXP))])
14537 (set (match_dup 12) (minus:XF (match_dup 10)
14538 (float_extend:XF (match_dup 13))))
14539 (set (match_operand:XF 0 "register_operand")
14540 (plus:XF (match_dup 12) (match_dup 7)))]
14541 "TARGET_USE_FANCY_MATH_387
14542 && flag_unsafe_math_optimizations"
14543 {
14544 int i;
14545
14546 if (optimize_insn_for_size_p ())
14547 FAIL;
14548
14549 for (i = 2; i < 13; i++)
14550 operands[i] = gen_reg_rtx (XFmode);
14551
14552 operands[13]
14553 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14554
14555 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14556 })
14557
14558 (define_expand "expm1<mode>2"
14559 [(use (match_operand:MODEF 0 "register_operand"))
14560 (use (match_operand:MODEF 1 "general_operand"))]
14561 "TARGET_USE_FANCY_MATH_387
14562 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14563 || TARGET_MIX_SSE_I387)
14564 && flag_unsafe_math_optimizations"
14565 {
14566 rtx op0, op1;
14567
14568 if (optimize_insn_for_size_p ())
14569 FAIL;
14570
14571 op0 = gen_reg_rtx (XFmode);
14572 op1 = gen_reg_rtx (XFmode);
14573
14574 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14575 emit_insn (gen_expm1xf2 (op0, op1));
14576 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14577 DONE;
14578 })
14579
14580 (define_expand "ldexpxf3"
14581 [(set (match_dup 3)
14582 (float:XF (match_operand:SI 2 "register_operand")))
14583 (parallel [(set (match_operand:XF 0 " register_operand")
14584 (unspec:XF [(match_operand:XF 1 "register_operand")
14585 (match_dup 3)]
14586 UNSPEC_FSCALE_FRACT))
14587 (set (match_dup 4)
14588 (unspec:XF [(match_dup 1) (match_dup 3)]
14589 UNSPEC_FSCALE_EXP))])]
14590 "TARGET_USE_FANCY_MATH_387
14591 && flag_unsafe_math_optimizations"
14592 {
14593 if (optimize_insn_for_size_p ())
14594 FAIL;
14595
14596 operands[3] = gen_reg_rtx (XFmode);
14597 operands[4] = gen_reg_rtx (XFmode);
14598 })
14599
14600 (define_expand "ldexp<mode>3"
14601 [(use (match_operand:MODEF 0 "register_operand"))
14602 (use (match_operand:MODEF 1 "general_operand"))
14603 (use (match_operand:SI 2 "register_operand"))]
14604 "TARGET_USE_FANCY_MATH_387
14605 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14606 || TARGET_MIX_SSE_I387)
14607 && flag_unsafe_math_optimizations"
14608 {
14609 rtx op0, op1;
14610
14611 if (optimize_insn_for_size_p ())
14612 FAIL;
14613
14614 op0 = gen_reg_rtx (XFmode);
14615 op1 = gen_reg_rtx (XFmode);
14616
14617 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14618 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14619 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14620 DONE;
14621 })
14622
14623 (define_expand "scalbxf3"
14624 [(parallel [(set (match_operand:XF 0 " register_operand")
14625 (unspec:XF [(match_operand:XF 1 "register_operand")
14626 (match_operand:XF 2 "register_operand")]
14627 UNSPEC_FSCALE_FRACT))
14628 (set (match_dup 3)
14629 (unspec:XF [(match_dup 1) (match_dup 2)]
14630 UNSPEC_FSCALE_EXP))])]
14631 "TARGET_USE_FANCY_MATH_387
14632 && flag_unsafe_math_optimizations"
14633 {
14634 if (optimize_insn_for_size_p ())
14635 FAIL;
14636
14637 operands[3] = gen_reg_rtx (XFmode);
14638 })
14639
14640 (define_expand "scalb<mode>3"
14641 [(use (match_operand:MODEF 0 "register_operand"))
14642 (use (match_operand:MODEF 1 "general_operand"))
14643 (use (match_operand:MODEF 2 "general_operand"))]
14644 "TARGET_USE_FANCY_MATH_387
14645 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14646 || TARGET_MIX_SSE_I387)
14647 && flag_unsafe_math_optimizations"
14648 {
14649 rtx op0, op1, op2;
14650
14651 if (optimize_insn_for_size_p ())
14652 FAIL;
14653
14654 op0 = gen_reg_rtx (XFmode);
14655 op1 = gen_reg_rtx (XFmode);
14656 op2 = gen_reg_rtx (XFmode);
14657
14658 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14659 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14660 emit_insn (gen_scalbxf3 (op0, op1, op2));
14661 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14662 DONE;
14663 })
14664
14665 (define_expand "significandxf2"
14666 [(parallel [(set (match_operand:XF 0 "register_operand")
14667 (unspec:XF [(match_operand:XF 1 "register_operand")]
14668 UNSPEC_XTRACT_FRACT))
14669 (set (match_dup 2)
14670 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14671 "TARGET_USE_FANCY_MATH_387
14672 && flag_unsafe_math_optimizations"
14673 "operands[2] = gen_reg_rtx (XFmode);")
14674
14675 (define_expand "significand<mode>2"
14676 [(use (match_operand:MODEF 0 "register_operand"))
14677 (use (match_operand:MODEF 1 "register_operand"))]
14678 "TARGET_USE_FANCY_MATH_387
14679 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14680 || TARGET_MIX_SSE_I387)
14681 && flag_unsafe_math_optimizations"
14682 {
14683 rtx op0 = gen_reg_rtx (XFmode);
14684 rtx op1 = gen_reg_rtx (XFmode);
14685
14686 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14687 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14688 DONE;
14689 })
14690 \f
14691
14692 (define_insn "sse4_1_round<mode>2"
14693 [(set (match_operand:MODEF 0 "register_operand" "=x")
14694 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14695 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14696 UNSPEC_ROUND))]
14697 "TARGET_ROUND"
14698 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14699 [(set_attr "type" "ssecvt")
14700 (set_attr "prefix_extra" "1")
14701 (set_attr "prefix" "maybe_vex")
14702 (set_attr "mode" "<MODE>")])
14703
14704 (define_insn "rintxf2"
14705 [(set (match_operand:XF 0 "register_operand" "=f")
14706 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14707 UNSPEC_FRNDINT))]
14708 "TARGET_USE_FANCY_MATH_387
14709 && flag_unsafe_math_optimizations"
14710 "frndint"
14711 [(set_attr "type" "fpspc")
14712 (set_attr "mode" "XF")])
14713
14714 (define_expand "rint<mode>2"
14715 [(use (match_operand:MODEF 0 "register_operand"))
14716 (use (match_operand:MODEF 1 "register_operand"))]
14717 "(TARGET_USE_FANCY_MATH_387
14718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14719 || TARGET_MIX_SSE_I387)
14720 && flag_unsafe_math_optimizations)
14721 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14722 && !flag_trapping_math)"
14723 {
14724 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14725 && !flag_trapping_math)
14726 {
14727 if (TARGET_ROUND)
14728 emit_insn (gen_sse4_1_round<mode>2
14729 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14730 else if (optimize_insn_for_size_p ())
14731 FAIL;
14732 else
14733 ix86_expand_rint (operands[0], operands[1]);
14734 }
14735 else
14736 {
14737 rtx op0 = gen_reg_rtx (XFmode);
14738 rtx op1 = gen_reg_rtx (XFmode);
14739
14740 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14741 emit_insn (gen_rintxf2 (op0, op1));
14742
14743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14744 }
14745 DONE;
14746 })
14747
14748 (define_expand "round<mode>2"
14749 [(match_operand:X87MODEF 0 "register_operand")
14750 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14751 "(TARGET_USE_FANCY_MATH_387
14752 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14753 || TARGET_MIX_SSE_I387)
14754 && flag_unsafe_math_optimizations)
14755 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14756 && !flag_trapping_math && !flag_rounding_math)"
14757 {
14758 if (optimize_insn_for_size_p ())
14759 FAIL;
14760
14761 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14762 && !flag_trapping_math && !flag_rounding_math)
14763 {
14764 if (TARGET_ROUND)
14765 {
14766 operands[1] = force_reg (<MODE>mode, operands[1]);
14767 ix86_expand_round_sse4 (operands[0], operands[1]);
14768 }
14769 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14770 ix86_expand_round (operands[0], operands[1]);
14771 else
14772 ix86_expand_rounddf_32 (operands[0], operands[1]);
14773 }
14774 else
14775 {
14776 operands[1] = force_reg (<MODE>mode, operands[1]);
14777 ix86_emit_i387_round (operands[0], operands[1]);
14778 }
14779 DONE;
14780 })
14781
14782 (define_insn_and_split "*fistdi2_1"
14783 [(set (match_operand:DI 0 "nonimmediate_operand")
14784 (unspec:DI [(match_operand:XF 1 "register_operand")]
14785 UNSPEC_FIST))]
14786 "TARGET_USE_FANCY_MATH_387
14787 && can_create_pseudo_p ()"
14788 "#"
14789 "&& 1"
14790 [(const_int 0)]
14791 {
14792 if (memory_operand (operands[0], VOIDmode))
14793 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14794 else
14795 {
14796 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14797 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14798 operands[2]));
14799 }
14800 DONE;
14801 }
14802 [(set_attr "type" "fpspc")
14803 (set_attr "mode" "DI")])
14804
14805 (define_insn "fistdi2"
14806 [(set (match_operand:DI 0 "memory_operand" "=m")
14807 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14808 UNSPEC_FIST))
14809 (clobber (match_scratch:XF 2 "=&1f"))]
14810 "TARGET_USE_FANCY_MATH_387"
14811 "* return output_fix_trunc (insn, operands, false);"
14812 [(set_attr "type" "fpspc")
14813 (set_attr "mode" "DI")])
14814
14815 (define_insn "fistdi2_with_temp"
14816 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14817 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14818 UNSPEC_FIST))
14819 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14820 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14821 "TARGET_USE_FANCY_MATH_387"
14822 "#"
14823 [(set_attr "type" "fpspc")
14824 (set_attr "mode" "DI")])
14825
14826 (define_split
14827 [(set (match_operand:DI 0 "register_operand")
14828 (unspec:DI [(match_operand:XF 1 "register_operand")]
14829 UNSPEC_FIST))
14830 (clobber (match_operand:DI 2 "memory_operand"))
14831 (clobber (match_scratch 3))]
14832 "reload_completed"
14833 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14834 (clobber (match_dup 3))])
14835 (set (match_dup 0) (match_dup 2))])
14836
14837 (define_split
14838 [(set (match_operand:DI 0 "memory_operand")
14839 (unspec:DI [(match_operand:XF 1 "register_operand")]
14840 UNSPEC_FIST))
14841 (clobber (match_operand:DI 2 "memory_operand"))
14842 (clobber (match_scratch 3))]
14843 "reload_completed"
14844 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14845 (clobber (match_dup 3))])])
14846
14847 (define_insn_and_split "*fist<mode>2_1"
14848 [(set (match_operand:SWI24 0 "register_operand")
14849 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14850 UNSPEC_FIST))]
14851 "TARGET_USE_FANCY_MATH_387
14852 && can_create_pseudo_p ()"
14853 "#"
14854 "&& 1"
14855 [(const_int 0)]
14856 {
14857 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14858 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14859 operands[2]));
14860 DONE;
14861 }
14862 [(set_attr "type" "fpspc")
14863 (set_attr "mode" "<MODE>")])
14864
14865 (define_insn "fist<mode>2"
14866 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14867 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14868 UNSPEC_FIST))]
14869 "TARGET_USE_FANCY_MATH_387"
14870 "* return output_fix_trunc (insn, operands, false);"
14871 [(set_attr "type" "fpspc")
14872 (set_attr "mode" "<MODE>")])
14873
14874 (define_insn "fist<mode>2_with_temp"
14875 [(set (match_operand:SWI24 0 "register_operand" "=r")
14876 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14877 UNSPEC_FIST))
14878 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14879 "TARGET_USE_FANCY_MATH_387"
14880 "#"
14881 [(set_attr "type" "fpspc")
14882 (set_attr "mode" "<MODE>")])
14883
14884 (define_split
14885 [(set (match_operand:SWI24 0 "register_operand")
14886 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14887 UNSPEC_FIST))
14888 (clobber (match_operand:SWI24 2 "memory_operand"))]
14889 "reload_completed"
14890 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14891 (set (match_dup 0) (match_dup 2))])
14892
14893 (define_split
14894 [(set (match_operand:SWI24 0 "memory_operand")
14895 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14896 UNSPEC_FIST))
14897 (clobber (match_operand:SWI24 2 "memory_operand"))]
14898 "reload_completed"
14899 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14900
14901 (define_expand "lrintxf<mode>2"
14902 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14903 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14904 UNSPEC_FIST))]
14905 "TARGET_USE_FANCY_MATH_387")
14906
14907 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14908 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14909 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14910 UNSPEC_FIX_NOTRUNC))]
14911 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14912
14913 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14914 [(match_operand:SWI248x 0 "nonimmediate_operand")
14915 (match_operand:X87MODEF 1 "register_operand")]
14916 "(TARGET_USE_FANCY_MATH_387
14917 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14918 || TARGET_MIX_SSE_I387)
14919 && flag_unsafe_math_optimizations)
14920 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14921 && <SWI248x:MODE>mode != HImode
14922 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14923 && !flag_trapping_math && !flag_rounding_math)"
14924 {
14925 if (optimize_insn_for_size_p ())
14926 FAIL;
14927
14928 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14929 && <SWI248x:MODE>mode != HImode
14930 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14931 && !flag_trapping_math && !flag_rounding_math)
14932 ix86_expand_lround (operands[0], operands[1]);
14933 else
14934 ix86_emit_i387_round (operands[0], operands[1]);
14935 DONE;
14936 })
14937
14938 (define_int_iterator FRNDINT_ROUNDING
14939 [UNSPEC_FRNDINT_FLOOR
14940 UNSPEC_FRNDINT_CEIL
14941 UNSPEC_FRNDINT_TRUNC])
14942
14943 (define_int_iterator FIST_ROUNDING
14944 [UNSPEC_FIST_FLOOR
14945 UNSPEC_FIST_CEIL])
14946
14947 ;; Base name for define_insn
14948 (define_int_attr rounding_insn
14949 [(UNSPEC_FRNDINT_FLOOR "floor")
14950 (UNSPEC_FRNDINT_CEIL "ceil")
14951 (UNSPEC_FRNDINT_TRUNC "btrunc")
14952 (UNSPEC_FIST_FLOOR "floor")
14953 (UNSPEC_FIST_CEIL "ceil")])
14954
14955 (define_int_attr rounding
14956 [(UNSPEC_FRNDINT_FLOOR "floor")
14957 (UNSPEC_FRNDINT_CEIL "ceil")
14958 (UNSPEC_FRNDINT_TRUNC "trunc")
14959 (UNSPEC_FIST_FLOOR "floor")
14960 (UNSPEC_FIST_CEIL "ceil")])
14961
14962 (define_int_attr ROUNDING
14963 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14964 (UNSPEC_FRNDINT_CEIL "CEIL")
14965 (UNSPEC_FRNDINT_TRUNC "TRUNC")
14966 (UNSPEC_FIST_FLOOR "FLOOR")
14967 (UNSPEC_FIST_CEIL "CEIL")])
14968
14969 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14970 (define_insn_and_split "frndintxf2_<rounding>"
14971 [(set (match_operand:XF 0 "register_operand")
14972 (unspec:XF [(match_operand:XF 1 "register_operand")]
14973 FRNDINT_ROUNDING))
14974 (clobber (reg:CC FLAGS_REG))]
14975 "TARGET_USE_FANCY_MATH_387
14976 && flag_unsafe_math_optimizations
14977 && can_create_pseudo_p ()"
14978 "#"
14979 "&& 1"
14980 [(const_int 0)]
14981 {
14982 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14983
14984 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14985 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14986
14987 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14988 operands[2], operands[3]));
14989 DONE;
14990 }
14991 [(set_attr "type" "frndint")
14992 (set_attr "i387_cw" "<rounding>")
14993 (set_attr "mode" "XF")])
14994
14995 (define_insn "frndintxf2_<rounding>_i387"
14996 [(set (match_operand:XF 0 "register_operand" "=f")
14997 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14998 FRNDINT_ROUNDING))
14999 (use (match_operand:HI 2 "memory_operand" "m"))
15000 (use (match_operand:HI 3 "memory_operand" "m"))]
15001 "TARGET_USE_FANCY_MATH_387
15002 && flag_unsafe_math_optimizations"
15003 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15004 [(set_attr "type" "frndint")
15005 (set_attr "i387_cw" "<rounding>")
15006 (set_attr "mode" "XF")])
15007
15008 (define_expand "<rounding_insn>xf2"
15009 [(parallel [(set (match_operand:XF 0 "register_operand")
15010 (unspec:XF [(match_operand:XF 1 "register_operand")]
15011 FRNDINT_ROUNDING))
15012 (clobber (reg:CC FLAGS_REG))])]
15013 "TARGET_USE_FANCY_MATH_387
15014 && flag_unsafe_math_optimizations
15015 && !optimize_insn_for_size_p ()")
15016
15017 (define_expand "<rounding_insn><mode>2"
15018 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15019 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15020 FRNDINT_ROUNDING))
15021 (clobber (reg:CC FLAGS_REG))])]
15022 "(TARGET_USE_FANCY_MATH_387
15023 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15024 || TARGET_MIX_SSE_I387)
15025 && flag_unsafe_math_optimizations)
15026 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15027 && !flag_trapping_math)"
15028 {
15029 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15030 && !flag_trapping_math)
15031 {
15032 if (TARGET_ROUND)
15033 emit_insn (gen_sse4_1_round<mode>2
15034 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15035 else if (optimize_insn_for_size_p ())
15036 FAIL;
15037 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15038 {
15039 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15040 ix86_expand_floorceil (operands[0], operands[1], true);
15041 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15042 ix86_expand_floorceil (operands[0], operands[1], false);
15043 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15044 ix86_expand_trunc (operands[0], operands[1]);
15045 else
15046 gcc_unreachable ();
15047 }
15048 else
15049 {
15050 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15051 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15052 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15053 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15054 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15055 ix86_expand_truncdf_32 (operands[0], operands[1]);
15056 else
15057 gcc_unreachable ();
15058 }
15059 }
15060 else
15061 {
15062 rtx op0, op1;
15063
15064 if (optimize_insn_for_size_p ())
15065 FAIL;
15066
15067 op0 = gen_reg_rtx (XFmode);
15068 op1 = gen_reg_rtx (XFmode);
15069 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15070 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15071
15072 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15073 }
15074 DONE;
15075 })
15076
15077 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15078 (define_insn_and_split "frndintxf2_mask_pm"
15079 [(set (match_operand:XF 0 "register_operand")
15080 (unspec:XF [(match_operand:XF 1 "register_operand")]
15081 UNSPEC_FRNDINT_MASK_PM))
15082 (clobber (reg:CC FLAGS_REG))]
15083 "TARGET_USE_FANCY_MATH_387
15084 && flag_unsafe_math_optimizations
15085 && can_create_pseudo_p ()"
15086 "#"
15087 "&& 1"
15088 [(const_int 0)]
15089 {
15090 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15091
15092 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15093 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15094
15095 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15096 operands[2], operands[3]));
15097 DONE;
15098 }
15099 [(set_attr "type" "frndint")
15100 (set_attr "i387_cw" "mask_pm")
15101 (set_attr "mode" "XF")])
15102
15103 (define_insn "frndintxf2_mask_pm_i387"
15104 [(set (match_operand:XF 0 "register_operand" "=f")
15105 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15106 UNSPEC_FRNDINT_MASK_PM))
15107 (use (match_operand:HI 2 "memory_operand" "m"))
15108 (use (match_operand:HI 3 "memory_operand" "m"))]
15109 "TARGET_USE_FANCY_MATH_387
15110 && flag_unsafe_math_optimizations"
15111 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15112 [(set_attr "type" "frndint")
15113 (set_attr "i387_cw" "mask_pm")
15114 (set_attr "mode" "XF")])
15115
15116 (define_expand "nearbyintxf2"
15117 [(parallel [(set (match_operand:XF 0 "register_operand")
15118 (unspec:XF [(match_operand:XF 1 "register_operand")]
15119 UNSPEC_FRNDINT_MASK_PM))
15120 (clobber (reg:CC FLAGS_REG))])]
15121 "TARGET_USE_FANCY_MATH_387
15122 && flag_unsafe_math_optimizations")
15123
15124 (define_expand "nearbyint<mode>2"
15125 [(use (match_operand:MODEF 0 "register_operand"))
15126 (use (match_operand:MODEF 1 "register_operand"))]
15127 "TARGET_USE_FANCY_MATH_387
15128 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15129 || TARGET_MIX_SSE_I387)
15130 && flag_unsafe_math_optimizations"
15131 {
15132 rtx op0 = gen_reg_rtx (XFmode);
15133 rtx op1 = gen_reg_rtx (XFmode);
15134
15135 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15136 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15137
15138 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15139 DONE;
15140 })
15141
15142 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15143 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15144 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15145 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15146 FIST_ROUNDING))
15147 (clobber (reg:CC FLAGS_REG))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && flag_unsafe_math_optimizations
15150 && can_create_pseudo_p ()"
15151 "#"
15152 "&& 1"
15153 [(const_int 0)]
15154 {
15155 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15156
15157 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15158 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15159 if (memory_operand (operands[0], VOIDmode))
15160 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15161 operands[2], operands[3]));
15162 else
15163 {
15164 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15165 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15166 (operands[0], operands[1], operands[2],
15167 operands[3], operands[4]));
15168 }
15169 DONE;
15170 }
15171 [(set_attr "type" "fistp")
15172 (set_attr "i387_cw" "<rounding>")
15173 (set_attr "mode" "<MODE>")])
15174
15175 (define_insn "fistdi2_<rounding>"
15176 [(set (match_operand:DI 0 "memory_operand" "=m")
15177 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15178 FIST_ROUNDING))
15179 (use (match_operand:HI 2 "memory_operand" "m"))
15180 (use (match_operand:HI 3 "memory_operand" "m"))
15181 (clobber (match_scratch:XF 4 "=&1f"))]
15182 "TARGET_USE_FANCY_MATH_387
15183 && flag_unsafe_math_optimizations"
15184 "* return output_fix_trunc (insn, operands, false);"
15185 [(set_attr "type" "fistp")
15186 (set_attr "i387_cw" "<rounding>")
15187 (set_attr "mode" "DI")])
15188
15189 (define_insn "fistdi2_<rounding>_with_temp"
15190 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15191 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15192 FIST_ROUNDING))
15193 (use (match_operand:HI 2 "memory_operand" "m,m"))
15194 (use (match_operand:HI 3 "memory_operand" "m,m"))
15195 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15196 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15197 "TARGET_USE_FANCY_MATH_387
15198 && flag_unsafe_math_optimizations"
15199 "#"
15200 [(set_attr "type" "fistp")
15201 (set_attr "i387_cw" "<rounding>")
15202 (set_attr "mode" "DI")])
15203
15204 (define_split
15205 [(set (match_operand:DI 0 "register_operand")
15206 (unspec:DI [(match_operand:XF 1 "register_operand")]
15207 FIST_ROUNDING))
15208 (use (match_operand:HI 2 "memory_operand"))
15209 (use (match_operand:HI 3 "memory_operand"))
15210 (clobber (match_operand:DI 4 "memory_operand"))
15211 (clobber (match_scratch 5))]
15212 "reload_completed"
15213 [(parallel [(set (match_dup 4)
15214 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15215 (use (match_dup 2))
15216 (use (match_dup 3))
15217 (clobber (match_dup 5))])
15218 (set (match_dup 0) (match_dup 4))])
15219
15220 (define_split
15221 [(set (match_operand:DI 0 "memory_operand")
15222 (unspec:DI [(match_operand:XF 1 "register_operand")]
15223 FIST_ROUNDING))
15224 (use (match_operand:HI 2 "memory_operand"))
15225 (use (match_operand:HI 3 "memory_operand"))
15226 (clobber (match_operand:DI 4 "memory_operand"))
15227 (clobber (match_scratch 5))]
15228 "reload_completed"
15229 [(parallel [(set (match_dup 0)
15230 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15231 (use (match_dup 2))
15232 (use (match_dup 3))
15233 (clobber (match_dup 5))])])
15234
15235 (define_insn "fist<mode>2_<rounding>"
15236 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15237 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15238 FIST_ROUNDING))
15239 (use (match_operand:HI 2 "memory_operand" "m"))
15240 (use (match_operand:HI 3 "memory_operand" "m"))]
15241 "TARGET_USE_FANCY_MATH_387
15242 && flag_unsafe_math_optimizations"
15243 "* return output_fix_trunc (insn, operands, false);"
15244 [(set_attr "type" "fistp")
15245 (set_attr "i387_cw" "<rounding>")
15246 (set_attr "mode" "<MODE>")])
15247
15248 (define_insn "fist<mode>2_<rounding>_with_temp"
15249 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15250 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15251 FIST_ROUNDING))
15252 (use (match_operand:HI 2 "memory_operand" "m,m"))
15253 (use (match_operand:HI 3 "memory_operand" "m,m"))
15254 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15255 "TARGET_USE_FANCY_MATH_387
15256 && flag_unsafe_math_optimizations"
15257 "#"
15258 [(set_attr "type" "fistp")
15259 (set_attr "i387_cw" "<rounding>")
15260 (set_attr "mode" "<MODE>")])
15261
15262 (define_split
15263 [(set (match_operand:SWI24 0 "register_operand")
15264 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15265 FIST_ROUNDING))
15266 (use (match_operand:HI 2 "memory_operand"))
15267 (use (match_operand:HI 3 "memory_operand"))
15268 (clobber (match_operand:SWI24 4 "memory_operand"))]
15269 "reload_completed"
15270 [(parallel [(set (match_dup 4)
15271 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15272 (use (match_dup 2))
15273 (use (match_dup 3))])
15274 (set (match_dup 0) (match_dup 4))])
15275
15276 (define_split
15277 [(set (match_operand:SWI24 0 "memory_operand")
15278 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15279 FIST_ROUNDING))
15280 (use (match_operand:HI 2 "memory_operand"))
15281 (use (match_operand:HI 3 "memory_operand"))
15282 (clobber (match_operand:SWI24 4 "memory_operand"))]
15283 "reload_completed"
15284 [(parallel [(set (match_dup 0)
15285 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15286 (use (match_dup 2))
15287 (use (match_dup 3))])])
15288
15289 (define_expand "l<rounding_insn>xf<mode>2"
15290 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15291 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15292 FIST_ROUNDING))
15293 (clobber (reg:CC FLAGS_REG))])]
15294 "TARGET_USE_FANCY_MATH_387
15295 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15296 && flag_unsafe_math_optimizations")
15297
15298 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15299 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15300 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15301 FIST_ROUNDING))
15302 (clobber (reg:CC FLAGS_REG))])]
15303 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15304 && !flag_trapping_math"
15305 {
15306 if (TARGET_64BIT && optimize_insn_for_size_p ())
15307 FAIL;
15308
15309 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15310 ix86_expand_lfloorceil (operands[0], operands[1], true);
15311 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15312 ix86_expand_lfloorceil (operands[0], operands[1], false);
15313 else
15314 gcc_unreachable ();
15315
15316 DONE;
15317 })
15318
15319 (define_insn "fxam<mode>2_i387"
15320 [(set (match_operand:HI 0 "register_operand" "=a")
15321 (unspec:HI
15322 [(match_operand:X87MODEF 1 "register_operand" "f")]
15323 UNSPEC_FXAM))]
15324 "TARGET_USE_FANCY_MATH_387"
15325 "fxam\n\tfnstsw\t%0"
15326 [(set_attr "type" "multi")
15327 (set_attr "length" "4")
15328 (set_attr "unit" "i387")
15329 (set_attr "mode" "<MODE>")])
15330
15331 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15332 [(set (match_operand:HI 0 "register_operand")
15333 (unspec:HI
15334 [(match_operand:MODEF 1 "memory_operand")]
15335 UNSPEC_FXAM_MEM))]
15336 "TARGET_USE_FANCY_MATH_387
15337 && can_create_pseudo_p ()"
15338 "#"
15339 "&& 1"
15340 [(set (match_dup 2)(match_dup 1))
15341 (set (match_dup 0)
15342 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15343 {
15344 operands[2] = gen_reg_rtx (<MODE>mode);
15345
15346 MEM_VOLATILE_P (operands[1]) = 1;
15347 }
15348 [(set_attr "type" "multi")
15349 (set_attr "unit" "i387")
15350 (set_attr "mode" "<MODE>")])
15351
15352 (define_expand "isinfxf2"
15353 [(use (match_operand:SI 0 "register_operand"))
15354 (use (match_operand:XF 1 "register_operand"))]
15355 "TARGET_USE_FANCY_MATH_387
15356 && ix86_libc_has_function (function_c99_misc)"
15357 {
15358 rtx mask = GEN_INT (0x45);
15359 rtx val = GEN_INT (0x05);
15360
15361 rtx cond;
15362
15363 rtx scratch = gen_reg_rtx (HImode);
15364 rtx res = gen_reg_rtx (QImode);
15365
15366 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15367
15368 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15369 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15370 cond = gen_rtx_fmt_ee (EQ, QImode,
15371 gen_rtx_REG (CCmode, FLAGS_REG),
15372 const0_rtx);
15373 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15374 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15375 DONE;
15376 })
15377
15378 (define_expand "isinf<mode>2"
15379 [(use (match_operand:SI 0 "register_operand"))
15380 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15381 "TARGET_USE_FANCY_MATH_387
15382 && ix86_libc_has_function (function_c99_misc)
15383 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15384 {
15385 rtx mask = GEN_INT (0x45);
15386 rtx val = GEN_INT (0x05);
15387
15388 rtx cond;
15389
15390 rtx scratch = gen_reg_rtx (HImode);
15391 rtx res = gen_reg_rtx (QImode);
15392
15393 /* Remove excess precision by forcing value through memory. */
15394 if (memory_operand (operands[1], VOIDmode))
15395 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15396 else
15397 {
15398 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15399
15400 emit_move_insn (temp, operands[1]);
15401 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15402 }
15403
15404 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15405 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15406 cond = gen_rtx_fmt_ee (EQ, QImode,
15407 gen_rtx_REG (CCmode, FLAGS_REG),
15408 const0_rtx);
15409 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15410 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15411 DONE;
15412 })
15413
15414 (define_expand "signbitxf2"
15415 [(use (match_operand:SI 0 "register_operand"))
15416 (use (match_operand:XF 1 "register_operand"))]
15417 "TARGET_USE_FANCY_MATH_387"
15418 {
15419 rtx scratch = gen_reg_rtx (HImode);
15420
15421 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15422 emit_insn (gen_andsi3 (operands[0],
15423 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15424 DONE;
15425 })
15426
15427 (define_insn "movmsk_df"
15428 [(set (match_operand:SI 0 "register_operand" "=r")
15429 (unspec:SI
15430 [(match_operand:DF 1 "register_operand" "x")]
15431 UNSPEC_MOVMSK))]
15432 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15433 "%vmovmskpd\t{%1, %0|%0, %1}"
15434 [(set_attr "type" "ssemov")
15435 (set_attr "prefix" "maybe_vex")
15436 (set_attr "mode" "DF")])
15437
15438 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15439 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15440 (define_expand "signbitdf2"
15441 [(use (match_operand:SI 0 "register_operand"))
15442 (use (match_operand:DF 1 "register_operand"))]
15443 "TARGET_USE_FANCY_MATH_387
15444 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15445 {
15446 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15447 {
15448 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15449 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15450 }
15451 else
15452 {
15453 rtx scratch = gen_reg_rtx (HImode);
15454
15455 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15456 emit_insn (gen_andsi3 (operands[0],
15457 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15458 }
15459 DONE;
15460 })
15461
15462 (define_expand "signbitsf2"
15463 [(use (match_operand:SI 0 "register_operand"))
15464 (use (match_operand:SF 1 "register_operand"))]
15465 "TARGET_USE_FANCY_MATH_387
15466 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15467 {
15468 rtx scratch = gen_reg_rtx (HImode);
15469
15470 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15471 emit_insn (gen_andsi3 (operands[0],
15472 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15473 DONE;
15474 })
15475 \f
15476 ;; Block operation instructions
15477
15478 (define_insn "cld"
15479 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15480 ""
15481 "cld"
15482 [(set_attr "length" "1")
15483 (set_attr "length_immediate" "0")
15484 (set_attr "modrm" "0")])
15485
15486 (define_expand "movmem<mode>"
15487 [(use (match_operand:BLK 0 "memory_operand"))
15488 (use (match_operand:BLK 1 "memory_operand"))
15489 (use (match_operand:SWI48 2 "nonmemory_operand"))
15490 (use (match_operand:SWI48 3 "const_int_operand"))
15491 (use (match_operand:SI 4 "const_int_operand"))
15492 (use (match_operand:SI 5 "const_int_operand"))]
15493 ""
15494 {
15495 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15496 operands[4], operands[5]))
15497 DONE;
15498 else
15499 FAIL;
15500 })
15501
15502 ;; Most CPUs don't like single string operations
15503 ;; Handle this case here to simplify previous expander.
15504
15505 (define_expand "strmov"
15506 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15507 (set (match_operand 1 "memory_operand") (match_dup 4))
15508 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15509 (clobber (reg:CC FLAGS_REG))])
15510 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15511 (clobber (reg:CC FLAGS_REG))])]
15512 ""
15513 {
15514 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15515
15516 /* If .md ever supports :P for Pmode, these can be directly
15517 in the pattern above. */
15518 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15519 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15520
15521 /* Can't use this if the user has appropriated esi or edi. */
15522 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15523 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15524 {
15525 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15526 operands[2], operands[3],
15527 operands[5], operands[6]));
15528 DONE;
15529 }
15530
15531 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15532 })
15533
15534 (define_expand "strmov_singleop"
15535 [(parallel [(set (match_operand 1 "memory_operand")
15536 (match_operand 3 "memory_operand"))
15537 (set (match_operand 0 "register_operand")
15538 (match_operand 4))
15539 (set (match_operand 2 "register_operand")
15540 (match_operand 5))])]
15541 ""
15542 "ix86_current_function_needs_cld = 1;")
15543
15544 (define_insn "*strmovdi_rex_1"
15545 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15546 (mem:DI (match_operand:P 3 "register_operand" "1")))
15547 (set (match_operand:P 0 "register_operand" "=D")
15548 (plus:P (match_dup 2)
15549 (const_int 8)))
15550 (set (match_operand:P 1 "register_operand" "=S")
15551 (plus:P (match_dup 3)
15552 (const_int 8)))]
15553 "TARGET_64BIT
15554 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15555 "%^movsq"
15556 [(set_attr "type" "str")
15557 (set_attr "memory" "both")
15558 (set_attr "mode" "DI")])
15559
15560 (define_insn "*strmovsi_1"
15561 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15562 (mem:SI (match_operand:P 3 "register_operand" "1")))
15563 (set (match_operand:P 0 "register_operand" "=D")
15564 (plus:P (match_dup 2)
15565 (const_int 4)))
15566 (set (match_operand:P 1 "register_operand" "=S")
15567 (plus:P (match_dup 3)
15568 (const_int 4)))]
15569 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15570 "%^movs{l|d}"
15571 [(set_attr "type" "str")
15572 (set_attr "memory" "both")
15573 (set_attr "mode" "SI")])
15574
15575 (define_insn "*strmovhi_1"
15576 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15577 (mem:HI (match_operand:P 3 "register_operand" "1")))
15578 (set (match_operand:P 0 "register_operand" "=D")
15579 (plus:P (match_dup 2)
15580 (const_int 2)))
15581 (set (match_operand:P 1 "register_operand" "=S")
15582 (plus:P (match_dup 3)
15583 (const_int 2)))]
15584 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15585 "%^movsw"
15586 [(set_attr "type" "str")
15587 (set_attr "memory" "both")
15588 (set_attr "mode" "HI")])
15589
15590 (define_insn "*strmovqi_1"
15591 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15592 (mem:QI (match_operand:P 3 "register_operand" "1")))
15593 (set (match_operand:P 0 "register_operand" "=D")
15594 (plus:P (match_dup 2)
15595 (const_int 1)))
15596 (set (match_operand:P 1 "register_operand" "=S")
15597 (plus:P (match_dup 3)
15598 (const_int 1)))]
15599 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15600 "%^movsb"
15601 [(set_attr "type" "str")
15602 (set_attr "memory" "both")
15603 (set (attr "prefix_rex")
15604 (if_then_else
15605 (match_test "<P:MODE>mode == DImode")
15606 (const_string "0")
15607 (const_string "*")))
15608 (set_attr "mode" "QI")])
15609
15610 (define_expand "rep_mov"
15611 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15612 (set (match_operand 0 "register_operand")
15613 (match_operand 5))
15614 (set (match_operand 2 "register_operand")
15615 (match_operand 6))
15616 (set (match_operand 1 "memory_operand")
15617 (match_operand 3 "memory_operand"))
15618 (use (match_dup 4))])]
15619 ""
15620 "ix86_current_function_needs_cld = 1;")
15621
15622 (define_insn "*rep_movdi_rex64"
15623 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15624 (set (match_operand:P 0 "register_operand" "=D")
15625 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15626 (const_int 3))
15627 (match_operand:P 3 "register_operand" "0")))
15628 (set (match_operand:P 1 "register_operand" "=S")
15629 (plus:P (ashift:P (match_dup 5) (const_int 3))
15630 (match_operand:P 4 "register_operand" "1")))
15631 (set (mem:BLK (match_dup 3))
15632 (mem:BLK (match_dup 4)))
15633 (use (match_dup 5))]
15634 "TARGET_64BIT
15635 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15636 "%^rep{%;} movsq"
15637 [(set_attr "type" "str")
15638 (set_attr "prefix_rep" "1")
15639 (set_attr "memory" "both")
15640 (set_attr "mode" "DI")])
15641
15642 (define_insn "*rep_movsi"
15643 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15644 (set (match_operand:P 0 "register_operand" "=D")
15645 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15646 (const_int 2))
15647 (match_operand:P 3 "register_operand" "0")))
15648 (set (match_operand:P 1 "register_operand" "=S")
15649 (plus:P (ashift:P (match_dup 5) (const_int 2))
15650 (match_operand:P 4 "register_operand" "1")))
15651 (set (mem:BLK (match_dup 3))
15652 (mem:BLK (match_dup 4)))
15653 (use (match_dup 5))]
15654 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15655 "%^rep{%;} movs{l|d}"
15656 [(set_attr "type" "str")
15657 (set_attr "prefix_rep" "1")
15658 (set_attr "memory" "both")
15659 (set_attr "mode" "SI")])
15660
15661 (define_insn "*rep_movqi"
15662 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15663 (set (match_operand:P 0 "register_operand" "=D")
15664 (plus:P (match_operand:P 3 "register_operand" "0")
15665 (match_operand:P 5 "register_operand" "2")))
15666 (set (match_operand:P 1 "register_operand" "=S")
15667 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15668 (set (mem:BLK (match_dup 3))
15669 (mem:BLK (match_dup 4)))
15670 (use (match_dup 5))]
15671 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15672 "%^rep{%;} movsb"
15673 [(set_attr "type" "str")
15674 (set_attr "prefix_rep" "1")
15675 (set_attr "memory" "both")
15676 (set_attr "mode" "QI")])
15677
15678 (define_expand "setmem<mode>"
15679 [(use (match_operand:BLK 0 "memory_operand"))
15680 (use (match_operand:SWI48 1 "nonmemory_operand"))
15681 (use (match_operand:QI 2 "nonmemory_operand"))
15682 (use (match_operand 3 "const_int_operand"))
15683 (use (match_operand:SI 4 "const_int_operand"))
15684 (use (match_operand:SI 5 "const_int_operand"))]
15685 ""
15686 {
15687 if (ix86_expand_setmem (operands[0], operands[1],
15688 operands[2], operands[3],
15689 operands[4], operands[5]))
15690 DONE;
15691 else
15692 FAIL;
15693 })
15694
15695 ;; Most CPUs don't like single string operations
15696 ;; Handle this case here to simplify previous expander.
15697
15698 (define_expand "strset"
15699 [(set (match_operand 1 "memory_operand")
15700 (match_operand 2 "register_operand"))
15701 (parallel [(set (match_operand 0 "register_operand")
15702 (match_dup 3))
15703 (clobber (reg:CC FLAGS_REG))])]
15704 ""
15705 {
15706 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15707 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15708
15709 /* If .md ever supports :P for Pmode, this can be directly
15710 in the pattern above. */
15711 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15712 GEN_INT (GET_MODE_SIZE (GET_MODE
15713 (operands[2]))));
15714 /* Can't use this if the user has appropriated eax or edi. */
15715 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15716 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15717 {
15718 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15719 operands[3]));
15720 DONE;
15721 }
15722 })
15723
15724 (define_expand "strset_singleop"
15725 [(parallel [(set (match_operand 1 "memory_operand")
15726 (match_operand 2 "register_operand"))
15727 (set (match_operand 0 "register_operand")
15728 (match_operand 3))
15729 (unspec [(const_int 0)] UNSPEC_STOS)])]
15730 ""
15731 "ix86_current_function_needs_cld = 1;")
15732
15733 (define_insn "*strsetdi_rex_1"
15734 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15735 (match_operand:DI 2 "register_operand" "a"))
15736 (set (match_operand:P 0 "register_operand" "=D")
15737 (plus:P (match_dup 1)
15738 (const_int 8)))
15739 (unspec [(const_int 0)] UNSPEC_STOS)]
15740 "TARGET_64BIT
15741 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15742 "%^stosq"
15743 [(set_attr "type" "str")
15744 (set_attr "memory" "store")
15745 (set_attr "mode" "DI")])
15746
15747 (define_insn "*strsetsi_1"
15748 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15749 (match_operand:SI 2 "register_operand" "a"))
15750 (set (match_operand:P 0 "register_operand" "=D")
15751 (plus:P (match_dup 1)
15752 (const_int 4)))
15753 (unspec [(const_int 0)] UNSPEC_STOS)]
15754 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15755 "%^stos{l|d}"
15756 [(set_attr "type" "str")
15757 (set_attr "memory" "store")
15758 (set_attr "mode" "SI")])
15759
15760 (define_insn "*strsethi_1"
15761 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15762 (match_operand:HI 2 "register_operand" "a"))
15763 (set (match_operand:P 0 "register_operand" "=D")
15764 (plus:P (match_dup 1)
15765 (const_int 2)))
15766 (unspec [(const_int 0)] UNSPEC_STOS)]
15767 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15768 "%^stosw"
15769 [(set_attr "type" "str")
15770 (set_attr "memory" "store")
15771 (set_attr "mode" "HI")])
15772
15773 (define_insn "*strsetqi_1"
15774 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15775 (match_operand:QI 2 "register_operand" "a"))
15776 (set (match_operand:P 0 "register_operand" "=D")
15777 (plus:P (match_dup 1)
15778 (const_int 1)))
15779 (unspec [(const_int 0)] UNSPEC_STOS)]
15780 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15781 "%^stosb"
15782 [(set_attr "type" "str")
15783 (set_attr "memory" "store")
15784 (set (attr "prefix_rex")
15785 (if_then_else
15786 (match_test "<P:MODE>mode == DImode")
15787 (const_string "0")
15788 (const_string "*")))
15789 (set_attr "mode" "QI")])
15790
15791 (define_expand "rep_stos"
15792 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15793 (set (match_operand 0 "register_operand")
15794 (match_operand 4))
15795 (set (match_operand 2 "memory_operand") (const_int 0))
15796 (use (match_operand 3 "register_operand"))
15797 (use (match_dup 1))])]
15798 ""
15799 "ix86_current_function_needs_cld = 1;")
15800
15801 (define_insn "*rep_stosdi_rex64"
15802 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15803 (set (match_operand:P 0 "register_operand" "=D")
15804 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15805 (const_int 3))
15806 (match_operand:P 3 "register_operand" "0")))
15807 (set (mem:BLK (match_dup 3))
15808 (const_int 0))
15809 (use (match_operand:DI 2 "register_operand" "a"))
15810 (use (match_dup 4))]
15811 "TARGET_64BIT
15812 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15813 "%^rep{%;} stosq"
15814 [(set_attr "type" "str")
15815 (set_attr "prefix_rep" "1")
15816 (set_attr "memory" "store")
15817 (set_attr "mode" "DI")])
15818
15819 (define_insn "*rep_stossi"
15820 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15821 (set (match_operand:P 0 "register_operand" "=D")
15822 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15823 (const_int 2))
15824 (match_operand:P 3 "register_operand" "0")))
15825 (set (mem:BLK (match_dup 3))
15826 (const_int 0))
15827 (use (match_operand:SI 2 "register_operand" "a"))
15828 (use (match_dup 4))]
15829 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15830 "%^rep{%;} stos{l|d}"
15831 [(set_attr "type" "str")
15832 (set_attr "prefix_rep" "1")
15833 (set_attr "memory" "store")
15834 (set_attr "mode" "SI")])
15835
15836 (define_insn "*rep_stosqi"
15837 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15838 (set (match_operand:P 0 "register_operand" "=D")
15839 (plus:P (match_operand:P 3 "register_operand" "0")
15840 (match_operand:P 4 "register_operand" "1")))
15841 (set (mem:BLK (match_dup 3))
15842 (const_int 0))
15843 (use (match_operand:QI 2 "register_operand" "a"))
15844 (use (match_dup 4))]
15845 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15846 "%^rep{%;} stosb"
15847 [(set_attr "type" "str")
15848 (set_attr "prefix_rep" "1")
15849 (set_attr "memory" "store")
15850 (set (attr "prefix_rex")
15851 (if_then_else
15852 (match_test "<P:MODE>mode == DImode")
15853 (const_string "0")
15854 (const_string "*")))
15855 (set_attr "mode" "QI")])
15856
15857 (define_expand "cmpstrnsi"
15858 [(set (match_operand:SI 0 "register_operand")
15859 (compare:SI (match_operand:BLK 1 "general_operand")
15860 (match_operand:BLK 2 "general_operand")))
15861 (use (match_operand 3 "general_operand"))
15862 (use (match_operand 4 "immediate_operand"))]
15863 ""
15864 {
15865 rtx addr1, addr2, out, outlow, count, countreg, align;
15866
15867 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15868 FAIL;
15869
15870 /* Can't use this if the user has appropriated ecx, esi or edi. */
15871 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15872 FAIL;
15873
15874 out = operands[0];
15875 if (!REG_P (out))
15876 out = gen_reg_rtx (SImode);
15877
15878 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15879 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15880 if (addr1 != XEXP (operands[1], 0))
15881 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15882 if (addr2 != XEXP (operands[2], 0))
15883 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15884
15885 count = operands[3];
15886 countreg = ix86_zero_extend_to_Pmode (count);
15887
15888 /* %%% Iff we are testing strict equality, we can use known alignment
15889 to good advantage. This may be possible with combine, particularly
15890 once cc0 is dead. */
15891 align = operands[4];
15892
15893 if (CONST_INT_P (count))
15894 {
15895 if (INTVAL (count) == 0)
15896 {
15897 emit_move_insn (operands[0], const0_rtx);
15898 DONE;
15899 }
15900 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15901 operands[1], operands[2]));
15902 }
15903 else
15904 {
15905 rtx (*gen_cmp) (rtx, rtx);
15906
15907 gen_cmp = (TARGET_64BIT
15908 ? gen_cmpdi_1 : gen_cmpsi_1);
15909
15910 emit_insn (gen_cmp (countreg, countreg));
15911 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15912 operands[1], operands[2]));
15913 }
15914
15915 outlow = gen_lowpart (QImode, out);
15916 emit_insn (gen_cmpintqi (outlow));
15917 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15918
15919 if (operands[0] != out)
15920 emit_move_insn (operands[0], out);
15921
15922 DONE;
15923 })
15924
15925 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15926
15927 (define_expand "cmpintqi"
15928 [(set (match_dup 1)
15929 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15930 (set (match_dup 2)
15931 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15932 (parallel [(set (match_operand:QI 0 "register_operand")
15933 (minus:QI (match_dup 1)
15934 (match_dup 2)))
15935 (clobber (reg:CC FLAGS_REG))])]
15936 ""
15937 {
15938 operands[1] = gen_reg_rtx (QImode);
15939 operands[2] = gen_reg_rtx (QImode);
15940 })
15941
15942 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15943 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15944
15945 (define_expand "cmpstrnqi_nz_1"
15946 [(parallel [(set (reg:CC FLAGS_REG)
15947 (compare:CC (match_operand 4 "memory_operand")
15948 (match_operand 5 "memory_operand")))
15949 (use (match_operand 2 "register_operand"))
15950 (use (match_operand:SI 3 "immediate_operand"))
15951 (clobber (match_operand 0 "register_operand"))
15952 (clobber (match_operand 1 "register_operand"))
15953 (clobber (match_dup 2))])]
15954 ""
15955 "ix86_current_function_needs_cld = 1;")
15956
15957 (define_insn "*cmpstrnqi_nz_1"
15958 [(set (reg:CC FLAGS_REG)
15959 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15960 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15961 (use (match_operand:P 6 "register_operand" "2"))
15962 (use (match_operand:SI 3 "immediate_operand" "i"))
15963 (clobber (match_operand:P 0 "register_operand" "=S"))
15964 (clobber (match_operand:P 1 "register_operand" "=D"))
15965 (clobber (match_operand:P 2 "register_operand" "=c"))]
15966 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15967 "%^repz{%;} cmpsb"
15968 [(set_attr "type" "str")
15969 (set_attr "mode" "QI")
15970 (set (attr "prefix_rex")
15971 (if_then_else
15972 (match_test "<P:MODE>mode == DImode")
15973 (const_string "0")
15974 (const_string "*")))
15975 (set_attr "prefix_rep" "1")])
15976
15977 ;; The same, but the count is not known to not be zero.
15978
15979 (define_expand "cmpstrnqi_1"
15980 [(parallel [(set (reg:CC FLAGS_REG)
15981 (if_then_else:CC (ne (match_operand 2 "register_operand")
15982 (const_int 0))
15983 (compare:CC (match_operand 4 "memory_operand")
15984 (match_operand 5 "memory_operand"))
15985 (const_int 0)))
15986 (use (match_operand:SI 3 "immediate_operand"))
15987 (use (reg:CC FLAGS_REG))
15988 (clobber (match_operand 0 "register_operand"))
15989 (clobber (match_operand 1 "register_operand"))
15990 (clobber (match_dup 2))])]
15991 ""
15992 "ix86_current_function_needs_cld = 1;")
15993
15994 (define_insn "*cmpstrnqi_1"
15995 [(set (reg:CC FLAGS_REG)
15996 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15997 (const_int 0))
15998 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15999 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16000 (const_int 0)))
16001 (use (match_operand:SI 3 "immediate_operand" "i"))
16002 (use (reg:CC FLAGS_REG))
16003 (clobber (match_operand:P 0 "register_operand" "=S"))
16004 (clobber (match_operand:P 1 "register_operand" "=D"))
16005 (clobber (match_operand:P 2 "register_operand" "=c"))]
16006 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16007 "%^repz{%;} cmpsb"
16008 [(set_attr "type" "str")
16009 (set_attr "mode" "QI")
16010 (set (attr "prefix_rex")
16011 (if_then_else
16012 (match_test "<P:MODE>mode == DImode")
16013 (const_string "0")
16014 (const_string "*")))
16015 (set_attr "prefix_rep" "1")])
16016
16017 (define_expand "strlen<mode>"
16018 [(set (match_operand:P 0 "register_operand")
16019 (unspec:P [(match_operand:BLK 1 "general_operand")
16020 (match_operand:QI 2 "immediate_operand")
16021 (match_operand 3 "immediate_operand")]
16022 UNSPEC_SCAS))]
16023 ""
16024 {
16025 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16026 DONE;
16027 else
16028 FAIL;
16029 })
16030
16031 (define_expand "strlenqi_1"
16032 [(parallel [(set (match_operand 0 "register_operand")
16033 (match_operand 2))
16034 (clobber (match_operand 1 "register_operand"))
16035 (clobber (reg:CC FLAGS_REG))])]
16036 ""
16037 "ix86_current_function_needs_cld = 1;")
16038
16039 (define_insn "*strlenqi_1"
16040 [(set (match_operand:P 0 "register_operand" "=&c")
16041 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16042 (match_operand:QI 2 "register_operand" "a")
16043 (match_operand:P 3 "immediate_operand" "i")
16044 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16045 (clobber (match_operand:P 1 "register_operand" "=D"))
16046 (clobber (reg:CC FLAGS_REG))]
16047 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16048 "%^repnz{%;} scasb"
16049 [(set_attr "type" "str")
16050 (set_attr "mode" "QI")
16051 (set (attr "prefix_rex")
16052 (if_then_else
16053 (match_test "<P:MODE>mode == DImode")
16054 (const_string "0")
16055 (const_string "*")))
16056 (set_attr "prefix_rep" "1")])
16057
16058 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16059 ;; handled in combine, but it is not currently up to the task.
16060 ;; When used for their truth value, the cmpstrn* expanders generate
16061 ;; code like this:
16062 ;;
16063 ;; repz cmpsb
16064 ;; seta %al
16065 ;; setb %dl
16066 ;; cmpb %al, %dl
16067 ;; jcc label
16068 ;;
16069 ;; The intermediate three instructions are unnecessary.
16070
16071 ;; This one handles cmpstrn*_nz_1...
16072 (define_peephole2
16073 [(parallel[
16074 (set (reg:CC FLAGS_REG)
16075 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16076 (mem:BLK (match_operand 5 "register_operand"))))
16077 (use (match_operand 6 "register_operand"))
16078 (use (match_operand:SI 3 "immediate_operand"))
16079 (clobber (match_operand 0 "register_operand"))
16080 (clobber (match_operand 1 "register_operand"))
16081 (clobber (match_operand 2 "register_operand"))])
16082 (set (match_operand:QI 7 "register_operand")
16083 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16084 (set (match_operand:QI 8 "register_operand")
16085 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16086 (set (reg FLAGS_REG)
16087 (compare (match_dup 7) (match_dup 8)))
16088 ]
16089 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16090 [(parallel[
16091 (set (reg:CC FLAGS_REG)
16092 (compare:CC (mem:BLK (match_dup 4))
16093 (mem:BLK (match_dup 5))))
16094 (use (match_dup 6))
16095 (use (match_dup 3))
16096 (clobber (match_dup 0))
16097 (clobber (match_dup 1))
16098 (clobber (match_dup 2))])])
16099
16100 ;; ...and this one handles cmpstrn*_1.
16101 (define_peephole2
16102 [(parallel[
16103 (set (reg:CC FLAGS_REG)
16104 (if_then_else:CC (ne (match_operand 6 "register_operand")
16105 (const_int 0))
16106 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16107 (mem:BLK (match_operand 5 "register_operand")))
16108 (const_int 0)))
16109 (use (match_operand:SI 3 "immediate_operand"))
16110 (use (reg:CC FLAGS_REG))
16111 (clobber (match_operand 0 "register_operand"))
16112 (clobber (match_operand 1 "register_operand"))
16113 (clobber (match_operand 2 "register_operand"))])
16114 (set (match_operand:QI 7 "register_operand")
16115 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16116 (set (match_operand:QI 8 "register_operand")
16117 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16118 (set (reg FLAGS_REG)
16119 (compare (match_dup 7) (match_dup 8)))
16120 ]
16121 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16122 [(parallel[
16123 (set (reg:CC FLAGS_REG)
16124 (if_then_else:CC (ne (match_dup 6)
16125 (const_int 0))
16126 (compare:CC (mem:BLK (match_dup 4))
16127 (mem:BLK (match_dup 5)))
16128 (const_int 0)))
16129 (use (match_dup 3))
16130 (use (reg:CC FLAGS_REG))
16131 (clobber (match_dup 0))
16132 (clobber (match_dup 1))
16133 (clobber (match_dup 2))])])
16134 \f
16135 ;; Conditional move instructions.
16136
16137 (define_expand "mov<mode>cc"
16138 [(set (match_operand:SWIM 0 "register_operand")
16139 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16140 (match_operand:SWIM 2 "<general_operand>")
16141 (match_operand:SWIM 3 "<general_operand>")))]
16142 ""
16143 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16144
16145 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16146 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16147 ;; So just document what we're doing explicitly.
16148
16149 (define_expand "x86_mov<mode>cc_0_m1"
16150 [(parallel
16151 [(set (match_operand:SWI48 0 "register_operand")
16152 (if_then_else:SWI48
16153 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16154 [(match_operand 1 "flags_reg_operand")
16155 (const_int 0)])
16156 (const_int -1)
16157 (const_int 0)))
16158 (clobber (reg:CC FLAGS_REG))])])
16159
16160 (define_insn "*x86_mov<mode>cc_0_m1"
16161 [(set (match_operand:SWI48 0 "register_operand" "=r")
16162 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16163 [(reg FLAGS_REG) (const_int 0)])
16164 (const_int -1)
16165 (const_int 0)))
16166 (clobber (reg:CC FLAGS_REG))]
16167 ""
16168 "sbb{<imodesuffix>}\t%0, %0"
16169 ; Since we don't have the proper number of operands for an alu insn,
16170 ; fill in all the blanks.
16171 [(set_attr "type" "alu")
16172 (set_attr "use_carry" "1")
16173 (set_attr "pent_pair" "pu")
16174 (set_attr "memory" "none")
16175 (set_attr "imm_disp" "false")
16176 (set_attr "mode" "<MODE>")
16177 (set_attr "length_immediate" "0")])
16178
16179 (define_insn "*x86_mov<mode>cc_0_m1_se"
16180 [(set (match_operand:SWI48 0 "register_operand" "=r")
16181 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16182 [(reg FLAGS_REG) (const_int 0)])
16183 (const_int 1)
16184 (const_int 0)))
16185 (clobber (reg:CC FLAGS_REG))]
16186 ""
16187 "sbb{<imodesuffix>}\t%0, %0"
16188 [(set_attr "type" "alu")
16189 (set_attr "use_carry" "1")
16190 (set_attr "pent_pair" "pu")
16191 (set_attr "memory" "none")
16192 (set_attr "imm_disp" "false")
16193 (set_attr "mode" "<MODE>")
16194 (set_attr "length_immediate" "0")])
16195
16196 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16197 [(set (match_operand:SWI48 0 "register_operand" "=r")
16198 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16199 [(reg FLAGS_REG) (const_int 0)])))
16200 (clobber (reg:CC FLAGS_REG))]
16201 ""
16202 "sbb{<imodesuffix>}\t%0, %0"
16203 [(set_attr "type" "alu")
16204 (set_attr "use_carry" "1")
16205 (set_attr "pent_pair" "pu")
16206 (set_attr "memory" "none")
16207 (set_attr "imm_disp" "false")
16208 (set_attr "mode" "<MODE>")
16209 (set_attr "length_immediate" "0")])
16210
16211 (define_insn "*mov<mode>cc_noc"
16212 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16213 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16214 [(reg FLAGS_REG) (const_int 0)])
16215 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16216 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16217 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16218 "@
16219 cmov%O2%C1\t{%2, %0|%0, %2}
16220 cmov%O2%c1\t{%3, %0|%0, %3}"
16221 [(set_attr "type" "icmov")
16222 (set_attr "mode" "<MODE>")])
16223
16224 ;; Don't do conditional moves with memory inputs. This splitter helps
16225 ;; register starved x86_32 by forcing inputs into registers before reload.
16226 (define_split
16227 [(set (match_operand:SWI248 0 "register_operand")
16228 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16229 [(reg FLAGS_REG) (const_int 0)])
16230 (match_operand:SWI248 2 "nonimmediate_operand")
16231 (match_operand:SWI248 3 "nonimmediate_operand")))]
16232 "!TARGET_64BIT && TARGET_CMOVE
16233 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16234 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16235 && can_create_pseudo_p ()
16236 && optimize_insn_for_speed_p ()"
16237 [(set (match_dup 0)
16238 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16239 {
16240 if (MEM_P (operands[2]))
16241 operands[2] = force_reg (<MODE>mode, operands[2]);
16242 if (MEM_P (operands[3]))
16243 operands[3] = force_reg (<MODE>mode, operands[3]);
16244 })
16245
16246 (define_insn "*movqicc_noc"
16247 [(set (match_operand:QI 0 "register_operand" "=r,r")
16248 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16249 [(reg FLAGS_REG) (const_int 0)])
16250 (match_operand:QI 2 "register_operand" "r,0")
16251 (match_operand:QI 3 "register_operand" "0,r")))]
16252 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16253 "#"
16254 [(set_attr "type" "icmov")
16255 (set_attr "mode" "QI")])
16256
16257 (define_split
16258 [(set (match_operand:SWI12 0 "register_operand")
16259 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16260 [(reg FLAGS_REG) (const_int 0)])
16261 (match_operand:SWI12 2 "register_operand")
16262 (match_operand:SWI12 3 "register_operand")))]
16263 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16264 && reload_completed"
16265 [(set (match_dup 0)
16266 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16267 {
16268 operands[0] = gen_lowpart (SImode, operands[0]);
16269 operands[2] = gen_lowpart (SImode, operands[2]);
16270 operands[3] = gen_lowpart (SImode, operands[3]);
16271 })
16272
16273 ;; Don't do conditional moves with memory inputs
16274 (define_peephole2
16275 [(match_scratch:SWI248 2 "r")
16276 (set (match_operand:SWI248 0 "register_operand")
16277 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16278 [(reg FLAGS_REG) (const_int 0)])
16279 (match_dup 0)
16280 (match_operand:SWI248 3 "memory_operand")))]
16281 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16282 && optimize_insn_for_speed_p ()"
16283 [(set (match_dup 2) (match_dup 3))
16284 (set (match_dup 0)
16285 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16286
16287 (define_peephole2
16288 [(match_scratch:SWI248 2 "r")
16289 (set (match_operand:SWI248 0 "register_operand")
16290 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16291 [(reg FLAGS_REG) (const_int 0)])
16292 (match_operand:SWI248 3 "memory_operand")
16293 (match_dup 0)))]
16294 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16295 && optimize_insn_for_speed_p ()"
16296 [(set (match_dup 2) (match_dup 3))
16297 (set (match_dup 0)
16298 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16299
16300 (define_expand "mov<mode>cc"
16301 [(set (match_operand:X87MODEF 0 "register_operand")
16302 (if_then_else:X87MODEF
16303 (match_operand 1 "comparison_operator")
16304 (match_operand:X87MODEF 2 "register_operand")
16305 (match_operand:X87MODEF 3 "register_operand")))]
16306 "(TARGET_80387 && TARGET_CMOVE)
16307 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16308 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16309
16310 (define_insn "*movxfcc_1"
16311 [(set (match_operand:XF 0 "register_operand" "=f,f")
16312 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16313 [(reg FLAGS_REG) (const_int 0)])
16314 (match_operand:XF 2 "register_operand" "f,0")
16315 (match_operand:XF 3 "register_operand" "0,f")))]
16316 "TARGET_80387 && TARGET_CMOVE"
16317 "@
16318 fcmov%F1\t{%2, %0|%0, %2}
16319 fcmov%f1\t{%3, %0|%0, %3}"
16320 [(set_attr "type" "fcmov")
16321 (set_attr "mode" "XF")])
16322
16323 (define_insn "*movdfcc_1"
16324 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16325 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16326 [(reg FLAGS_REG) (const_int 0)])
16327 (match_operand:DF 2 "nonimmediate_operand"
16328 "f ,0,rm,0 ,rm,0")
16329 (match_operand:DF 3 "nonimmediate_operand"
16330 "0 ,f,0 ,rm,0, rm")))]
16331 "TARGET_80387 && TARGET_CMOVE
16332 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16333 "@
16334 fcmov%F1\t{%2, %0|%0, %2}
16335 fcmov%f1\t{%3, %0|%0, %3}
16336 #
16337 #
16338 cmov%O2%C1\t{%2, %0|%0, %2}
16339 cmov%O2%c1\t{%3, %0|%0, %3}"
16340 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16341 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16342 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16343
16344 (define_split
16345 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16346 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16347 [(reg FLAGS_REG) (const_int 0)])
16348 (match_operand:DF 2 "nonimmediate_operand")
16349 (match_operand:DF 3 "nonimmediate_operand")))]
16350 "!TARGET_64BIT && reload_completed"
16351 [(set (match_dup 2)
16352 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16353 (set (match_dup 3)
16354 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16355 {
16356 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16357 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16358 })
16359
16360 (define_insn "*movsfcc_1_387"
16361 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16362 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16363 [(reg FLAGS_REG) (const_int 0)])
16364 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16365 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16366 "TARGET_80387 && TARGET_CMOVE
16367 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16368 "@
16369 fcmov%F1\t{%2, %0|%0, %2}
16370 fcmov%f1\t{%3, %0|%0, %3}
16371 cmov%O2%C1\t{%2, %0|%0, %2}
16372 cmov%O2%c1\t{%3, %0|%0, %3}"
16373 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16374 (set_attr "mode" "SF,SF,SI,SI")])
16375
16376 ;; Don't do conditional moves with memory inputs. This splitter helps
16377 ;; register starved x86_32 by forcing inputs into registers before reload.
16378 (define_split
16379 [(set (match_operand:MODEF 0 "register_operand")
16380 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16381 [(reg FLAGS_REG) (const_int 0)])
16382 (match_operand:MODEF 2 "nonimmediate_operand")
16383 (match_operand:MODEF 3 "nonimmediate_operand")))]
16384 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16385 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16386 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16387 && can_create_pseudo_p ()
16388 && optimize_insn_for_speed_p ()"
16389 [(set (match_dup 0)
16390 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16391 {
16392 if (MEM_P (operands[2]))
16393 operands[2] = force_reg (<MODE>mode, operands[2]);
16394 if (MEM_P (operands[3]))
16395 operands[3] = force_reg (<MODE>mode, operands[3]);
16396 })
16397
16398 ;; Don't do conditional moves with memory inputs
16399 (define_peephole2
16400 [(match_scratch:MODEF 2 "r")
16401 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16402 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16403 [(reg FLAGS_REG) (const_int 0)])
16404 (match_dup 0)
16405 (match_operand:MODEF 3 "memory_operand")))]
16406 "(<MODE>mode != DFmode || TARGET_64BIT)
16407 && TARGET_80387 && TARGET_CMOVE
16408 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16409 && optimize_insn_for_speed_p ()"
16410 [(set (match_dup 2) (match_dup 3))
16411 (set (match_dup 0)
16412 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16413
16414 (define_peephole2
16415 [(match_scratch:MODEF 2 "r")
16416 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16417 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16418 [(reg FLAGS_REG) (const_int 0)])
16419 (match_operand:MODEF 3 "memory_operand")
16420 (match_dup 0)))]
16421 "(<MODE>mode != DFmode || TARGET_64BIT)
16422 && TARGET_80387 && TARGET_CMOVE
16423 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16424 && optimize_insn_for_speed_p ()"
16425 [(set (match_dup 2) (match_dup 3))
16426 (set (match_dup 0)
16427 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16428
16429 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16430 ;; the scalar versions to have only XMM registers as operands.
16431
16432 ;; XOP conditional move
16433 (define_insn "*xop_pcmov_<mode>"
16434 [(set (match_operand:MODEF 0 "register_operand" "=x")
16435 (if_then_else:MODEF
16436 (match_operand:MODEF 1 "register_operand" "x")
16437 (match_operand:MODEF 2 "register_operand" "x")
16438 (match_operand:MODEF 3 "register_operand" "x")))]
16439 "TARGET_XOP"
16440 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16441 [(set_attr "type" "sse4arg")])
16442
16443 ;; These versions of the min/max patterns are intentionally ignorant of
16444 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16445 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16446 ;; are undefined in this condition, we're certain this is correct.
16447
16448 (define_insn "<code><mode>3"
16449 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16450 (smaxmin:MODEF
16451 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16452 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16453 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16454 "@
16455 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16456 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16457 [(set_attr "isa" "noavx,avx")
16458 (set_attr "prefix" "orig,vex")
16459 (set_attr "type" "sseadd")
16460 (set_attr "mode" "<MODE>")])
16461
16462 ;; These versions of the min/max patterns implement exactly the operations
16463 ;; min = (op1 < op2 ? op1 : op2)
16464 ;; max = (!(op1 < op2) ? op1 : op2)
16465 ;; Their operands are not commutative, and thus they may be used in the
16466 ;; presence of -0.0 and NaN.
16467
16468 (define_int_iterator IEEE_MAXMIN
16469 [UNSPEC_IEEE_MAX
16470 UNSPEC_IEEE_MIN])
16471
16472 (define_int_attr ieee_maxmin
16473 [(UNSPEC_IEEE_MAX "max")
16474 (UNSPEC_IEEE_MIN "min")])
16475
16476 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16477 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16478 (unspec:MODEF
16479 [(match_operand:MODEF 1 "register_operand" "0,x")
16480 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16481 IEEE_MAXMIN))]
16482 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16483 "@
16484 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16485 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16486 [(set_attr "isa" "noavx,avx")
16487 (set_attr "prefix" "orig,vex")
16488 (set_attr "type" "sseadd")
16489 (set_attr "mode" "<MODE>")])
16490
16491 ;; Make two stack loads independent:
16492 ;; fld aa fld aa
16493 ;; fld %st(0) -> fld bb
16494 ;; fmul bb fmul %st(1), %st
16495 ;;
16496 ;; Actually we only match the last two instructions for simplicity.
16497 (define_peephole2
16498 [(set (match_operand 0 "fp_register_operand")
16499 (match_operand 1 "fp_register_operand"))
16500 (set (match_dup 0)
16501 (match_operator 2 "binary_fp_operator"
16502 [(match_dup 0)
16503 (match_operand 3 "memory_operand")]))]
16504 "REGNO (operands[0]) != REGNO (operands[1])"
16505 [(set (match_dup 0) (match_dup 3))
16506 (set (match_dup 0) (match_dup 4))]
16507
16508 ;; The % modifier is not operational anymore in peephole2's, so we have to
16509 ;; swap the operands manually in the case of addition and multiplication.
16510 {
16511 rtx op0, op1;
16512
16513 if (COMMUTATIVE_ARITH_P (operands[2]))
16514 op0 = operands[0], op1 = operands[1];
16515 else
16516 op0 = operands[1], op1 = operands[0];
16517
16518 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16519 GET_MODE (operands[2]),
16520 op0, op1);
16521 })
16522
16523 ;; Conditional addition patterns
16524 (define_expand "add<mode>cc"
16525 [(match_operand:SWI 0 "register_operand")
16526 (match_operand 1 "ordered_comparison_operator")
16527 (match_operand:SWI 2 "register_operand")
16528 (match_operand:SWI 3 "const_int_operand")]
16529 ""
16530 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16531 \f
16532 ;; Misc patterns (?)
16533
16534 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16535 ;; Otherwise there will be nothing to keep
16536 ;;
16537 ;; [(set (reg ebp) (reg esp))]
16538 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16539 ;; (clobber (eflags)]
16540 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16541 ;;
16542 ;; in proper program order.
16543
16544 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16545 [(set (match_operand:P 0 "register_operand" "=r,r")
16546 (plus:P (match_operand:P 1 "register_operand" "0,r")
16547 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16548 (clobber (reg:CC FLAGS_REG))
16549 (clobber (mem:BLK (scratch)))]
16550 ""
16551 {
16552 switch (get_attr_type (insn))
16553 {
16554 case TYPE_IMOV:
16555 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16556
16557 case TYPE_ALU:
16558 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16559 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16560 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16561
16562 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16563
16564 default:
16565 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16566 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16567 }
16568 }
16569 [(set (attr "type")
16570 (cond [(and (eq_attr "alternative" "0")
16571 (not (match_test "TARGET_OPT_AGU")))
16572 (const_string "alu")
16573 (match_operand:<MODE> 2 "const0_operand")
16574 (const_string "imov")
16575 ]
16576 (const_string "lea")))
16577 (set (attr "length_immediate")
16578 (cond [(eq_attr "type" "imov")
16579 (const_string "0")
16580 (and (eq_attr "type" "alu")
16581 (match_operand 2 "const128_operand"))
16582 (const_string "1")
16583 ]
16584 (const_string "*")))
16585 (set_attr "mode" "<MODE>")])
16586
16587 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16588 [(set (match_operand:P 0 "register_operand" "=r")
16589 (minus:P (match_operand:P 1 "register_operand" "0")
16590 (match_operand:P 2 "register_operand" "r")))
16591 (clobber (reg:CC FLAGS_REG))
16592 (clobber (mem:BLK (scratch)))]
16593 ""
16594 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16595 [(set_attr "type" "alu")
16596 (set_attr "mode" "<MODE>")])
16597
16598 (define_insn "allocate_stack_worker_probe_<mode>"
16599 [(set (match_operand:P 0 "register_operand" "=a")
16600 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16601 UNSPECV_STACK_PROBE))
16602 (clobber (reg:CC FLAGS_REG))]
16603 "ix86_target_stack_probe ()"
16604 "call\t___chkstk_ms"
16605 [(set_attr "type" "multi")
16606 (set_attr "length" "5")])
16607
16608 (define_expand "allocate_stack"
16609 [(match_operand 0 "register_operand")
16610 (match_operand 1 "general_operand")]
16611 "ix86_target_stack_probe ()"
16612 {
16613 rtx x;
16614
16615 #ifndef CHECK_STACK_LIMIT
16616 #define CHECK_STACK_LIMIT 0
16617 #endif
16618
16619 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16620 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16621 x = operands[1];
16622 else
16623 {
16624 rtx (*insn) (rtx, rtx);
16625
16626 x = copy_to_mode_reg (Pmode, operands[1]);
16627
16628 insn = (TARGET_64BIT
16629 ? gen_allocate_stack_worker_probe_di
16630 : gen_allocate_stack_worker_probe_si);
16631
16632 emit_insn (insn (x, x));
16633 }
16634
16635 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16636 stack_pointer_rtx, 0, OPTAB_DIRECT);
16637
16638 if (x != stack_pointer_rtx)
16639 emit_move_insn (stack_pointer_rtx, x);
16640
16641 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16642 DONE;
16643 })
16644
16645 ;; Use IOR for stack probes, this is shorter.
16646 (define_expand "probe_stack"
16647 [(match_operand 0 "memory_operand")]
16648 ""
16649 {
16650 rtx (*gen_ior3) (rtx, rtx, rtx);
16651
16652 gen_ior3 = (GET_MODE (operands[0]) == DImode
16653 ? gen_iordi3 : gen_iorsi3);
16654
16655 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16656 DONE;
16657 })
16658
16659 (define_insn "adjust_stack_and_probe<mode>"
16660 [(set (match_operand:P 0 "register_operand" "=r")
16661 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16662 UNSPECV_PROBE_STACK_RANGE))
16663 (set (reg:P SP_REG)
16664 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16665 (clobber (reg:CC FLAGS_REG))
16666 (clobber (mem:BLK (scratch)))]
16667 ""
16668 "* return output_adjust_stack_and_probe (operands[0]);"
16669 [(set_attr "type" "multi")])
16670
16671 (define_insn "probe_stack_range<mode>"
16672 [(set (match_operand:P 0 "register_operand" "=r")
16673 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16674 (match_operand:P 2 "const_int_operand" "n")]
16675 UNSPECV_PROBE_STACK_RANGE))
16676 (clobber (reg:CC FLAGS_REG))]
16677 ""
16678 "* return output_probe_stack_range (operands[0], operands[2]);"
16679 [(set_attr "type" "multi")])
16680
16681 (define_expand "builtin_setjmp_receiver"
16682 [(label_ref (match_operand 0))]
16683 "!TARGET_64BIT && flag_pic"
16684 {
16685 #if TARGET_MACHO
16686 if (TARGET_MACHO)
16687 {
16688 rtx xops[3];
16689 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16690 rtx label_rtx = gen_label_rtx ();
16691 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16692 xops[0] = xops[1] = picreg;
16693 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16694 ix86_expand_binary_operator (MINUS, SImode, xops);
16695 }
16696 else
16697 #endif
16698 emit_insn (gen_set_got (pic_offset_table_rtx));
16699 DONE;
16700 })
16701
16702 (define_insn_and_split "nonlocal_goto_receiver"
16703 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16704 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16705 "#"
16706 "&& reload_completed"
16707 [(const_int 0)]
16708 {
16709 if (crtl->uses_pic_offset_table)
16710 {
16711 rtx xops[3];
16712 rtx label_rtx = gen_label_rtx ();
16713 rtx tmp;
16714
16715 /* Get a new pic base. */
16716 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16717 /* Correct this with the offset from the new to the old. */
16718 xops[0] = xops[1] = pic_offset_table_rtx;
16719 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16720 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16721 UNSPEC_MACHOPIC_OFFSET);
16722 xops[2] = gen_rtx_CONST (Pmode, tmp);
16723 ix86_expand_binary_operator (MINUS, SImode, xops);
16724 }
16725 else
16726 /* No pic reg restore needed. */
16727 emit_note (NOTE_INSN_DELETED);
16728
16729 DONE;
16730 })
16731
16732 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16733 ;; Do not split instructions with mask registers.
16734 (define_split
16735 [(set (match_operand 0 "general_reg_operand")
16736 (match_operator 3 "promotable_binary_operator"
16737 [(match_operand 1 "general_reg_operand")
16738 (match_operand 2 "aligned_operand")]))
16739 (clobber (reg:CC FLAGS_REG))]
16740 "! TARGET_PARTIAL_REG_STALL && reload_completed
16741 && ((GET_MODE (operands[0]) == HImode
16742 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16743 /* ??? next two lines just !satisfies_constraint_K (...) */
16744 || !CONST_INT_P (operands[2])
16745 || satisfies_constraint_K (operands[2])))
16746 || (GET_MODE (operands[0]) == QImode
16747 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16748 [(parallel [(set (match_dup 0)
16749 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16750 (clobber (reg:CC FLAGS_REG))])]
16751 {
16752 operands[0] = gen_lowpart (SImode, operands[0]);
16753 operands[1] = gen_lowpart (SImode, operands[1]);
16754 if (GET_CODE (operands[3]) != ASHIFT)
16755 operands[2] = gen_lowpart (SImode, operands[2]);
16756 PUT_MODE (operands[3], SImode);
16757 })
16758
16759 ; Promote the QImode tests, as i386 has encoding of the AND
16760 ; instruction with 32-bit sign-extended immediate and thus the
16761 ; instruction size is unchanged, except in the %eax case for
16762 ; which it is increased by one byte, hence the ! optimize_size.
16763 (define_split
16764 [(set (match_operand 0 "flags_reg_operand")
16765 (match_operator 2 "compare_operator"
16766 [(and (match_operand 3 "aligned_operand")
16767 (match_operand 4 "const_int_operand"))
16768 (const_int 0)]))
16769 (set (match_operand 1 "register_operand")
16770 (and (match_dup 3) (match_dup 4)))]
16771 "! TARGET_PARTIAL_REG_STALL && reload_completed
16772 && optimize_insn_for_speed_p ()
16773 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16774 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16775 /* Ensure that the operand will remain sign-extended immediate. */
16776 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16777 [(parallel [(set (match_dup 0)
16778 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16779 (const_int 0)]))
16780 (set (match_dup 1)
16781 (and:SI (match_dup 3) (match_dup 4)))])]
16782 {
16783 operands[4]
16784 = gen_int_mode (INTVAL (operands[4])
16785 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16786 operands[1] = gen_lowpart (SImode, operands[1]);
16787 operands[3] = gen_lowpart (SImode, operands[3]);
16788 })
16789
16790 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16791 ; the TEST instruction with 32-bit sign-extended immediate and thus
16792 ; the instruction size would at least double, which is not what we
16793 ; want even with ! optimize_size.
16794 (define_split
16795 [(set (match_operand 0 "flags_reg_operand")
16796 (match_operator 1 "compare_operator"
16797 [(and (match_operand:HI 2 "aligned_operand")
16798 (match_operand:HI 3 "const_int_operand"))
16799 (const_int 0)]))]
16800 "! TARGET_PARTIAL_REG_STALL && reload_completed
16801 && ! TARGET_FAST_PREFIX
16802 && optimize_insn_for_speed_p ()
16803 /* Ensure that the operand will remain sign-extended immediate. */
16804 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16805 [(set (match_dup 0)
16806 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16807 (const_int 0)]))]
16808 {
16809 operands[3]
16810 = gen_int_mode (INTVAL (operands[3])
16811 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16812 operands[2] = gen_lowpart (SImode, operands[2]);
16813 })
16814
16815 (define_split
16816 [(set (match_operand 0 "register_operand")
16817 (neg (match_operand 1 "register_operand")))
16818 (clobber (reg:CC FLAGS_REG))]
16819 "! TARGET_PARTIAL_REG_STALL && reload_completed
16820 && (GET_MODE (operands[0]) == HImode
16821 || (GET_MODE (operands[0]) == QImode
16822 && (TARGET_PROMOTE_QImode
16823 || optimize_insn_for_size_p ())))"
16824 [(parallel [(set (match_dup 0)
16825 (neg:SI (match_dup 1)))
16826 (clobber (reg:CC FLAGS_REG))])]
16827 {
16828 operands[0] = gen_lowpart (SImode, operands[0]);
16829 operands[1] = gen_lowpart (SImode, operands[1]);
16830 })
16831
16832 ;; Do not split instructions with mask regs.
16833 (define_split
16834 [(set (match_operand 0 "general_reg_operand")
16835 (not (match_operand 1 "general_reg_operand")))]
16836 "! TARGET_PARTIAL_REG_STALL && reload_completed
16837 && (GET_MODE (operands[0]) == HImode
16838 || (GET_MODE (operands[0]) == QImode
16839 && (TARGET_PROMOTE_QImode
16840 || optimize_insn_for_size_p ())))"
16841 [(set (match_dup 0)
16842 (not:SI (match_dup 1)))]
16843 {
16844 operands[0] = gen_lowpart (SImode, operands[0]);
16845 operands[1] = gen_lowpart (SImode, operands[1]);
16846 })
16847 \f
16848 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16849 ;; transform a complex memory operation into two memory to register operations.
16850
16851 ;; Don't push memory operands
16852 (define_peephole2
16853 [(set (match_operand:SWI 0 "push_operand")
16854 (match_operand:SWI 1 "memory_operand"))
16855 (match_scratch:SWI 2 "<r>")]
16856 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16857 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16858 [(set (match_dup 2) (match_dup 1))
16859 (set (match_dup 0) (match_dup 2))])
16860
16861 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16862 ;; SImode pushes.
16863 (define_peephole2
16864 [(set (match_operand:SF 0 "push_operand")
16865 (match_operand:SF 1 "memory_operand"))
16866 (match_scratch:SF 2 "r")]
16867 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16868 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16869 [(set (match_dup 2) (match_dup 1))
16870 (set (match_dup 0) (match_dup 2))])
16871
16872 ;; Don't move an immediate directly to memory when the instruction
16873 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16874 (define_peephole2
16875 [(match_scratch:SWI124 1 "<r>")
16876 (set (match_operand:SWI124 0 "memory_operand")
16877 (const_int 0))]
16878 "optimize_insn_for_speed_p ()
16879 && ((<MODE>mode == HImode
16880 && TARGET_LCP_STALL)
16881 || (!TARGET_USE_MOV0
16882 && TARGET_SPLIT_LONG_MOVES
16883 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16884 && peep2_regno_dead_p (0, FLAGS_REG)"
16885 [(parallel [(set (match_dup 2) (const_int 0))
16886 (clobber (reg:CC FLAGS_REG))])
16887 (set (match_dup 0) (match_dup 1))]
16888 "operands[2] = gen_lowpart (SImode, operands[1]);")
16889
16890 (define_peephole2
16891 [(match_scratch:SWI124 2 "<r>")
16892 (set (match_operand:SWI124 0 "memory_operand")
16893 (match_operand:SWI124 1 "immediate_operand"))]
16894 "optimize_insn_for_speed_p ()
16895 && ((<MODE>mode == HImode
16896 && TARGET_LCP_STALL)
16897 || (TARGET_SPLIT_LONG_MOVES
16898 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16899 [(set (match_dup 2) (match_dup 1))
16900 (set (match_dup 0) (match_dup 2))])
16901
16902 ;; Don't compare memory with zero, load and use a test instead.
16903 (define_peephole2
16904 [(set (match_operand 0 "flags_reg_operand")
16905 (match_operator 1 "compare_operator"
16906 [(match_operand:SI 2 "memory_operand")
16907 (const_int 0)]))
16908 (match_scratch:SI 3 "r")]
16909 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16910 [(set (match_dup 3) (match_dup 2))
16911 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16912
16913 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16914 ;; Don't split NOTs with a displacement operand, because resulting XOR
16915 ;; will not be pairable anyway.
16916 ;;
16917 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16918 ;; represented using a modRM byte. The XOR replacement is long decoded,
16919 ;; so this split helps here as well.
16920 ;;
16921 ;; Note: Can't do this as a regular split because we can't get proper
16922 ;; lifetime information then.
16923
16924 (define_peephole2
16925 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16926 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16927 "optimize_insn_for_speed_p ()
16928 && ((TARGET_NOT_UNPAIRABLE
16929 && (!MEM_P (operands[0])
16930 || !memory_displacement_operand (operands[0], <MODE>mode)))
16931 || (TARGET_NOT_VECTORMODE
16932 && long_memory_operand (operands[0], <MODE>mode)))
16933 && peep2_regno_dead_p (0, FLAGS_REG)"
16934 [(parallel [(set (match_dup 0)
16935 (xor:SWI124 (match_dup 1) (const_int -1)))
16936 (clobber (reg:CC FLAGS_REG))])])
16937
16938 ;; Non pairable "test imm, reg" instructions can be translated to
16939 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16940 ;; byte opcode instead of two, have a short form for byte operands),
16941 ;; so do it for other CPUs as well. Given that the value was dead,
16942 ;; this should not create any new dependencies. Pass on the sub-word
16943 ;; versions if we're concerned about partial register stalls.
16944
16945 (define_peephole2
16946 [(set (match_operand 0 "flags_reg_operand")
16947 (match_operator 1 "compare_operator"
16948 [(and:SI (match_operand:SI 2 "register_operand")
16949 (match_operand:SI 3 "immediate_operand"))
16950 (const_int 0)]))]
16951 "ix86_match_ccmode (insn, CCNOmode)
16952 && (true_regnum (operands[2]) != AX_REG
16953 || satisfies_constraint_K (operands[3]))
16954 && peep2_reg_dead_p (1, operands[2])"
16955 [(parallel
16956 [(set (match_dup 0)
16957 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16958 (const_int 0)]))
16959 (set (match_dup 2)
16960 (and:SI (match_dup 2) (match_dup 3)))])])
16961
16962 ;; We don't need to handle HImode case, because it will be promoted to SImode
16963 ;; on ! TARGET_PARTIAL_REG_STALL
16964
16965 (define_peephole2
16966 [(set (match_operand 0 "flags_reg_operand")
16967 (match_operator 1 "compare_operator"
16968 [(and:QI (match_operand:QI 2 "register_operand")
16969 (match_operand:QI 3 "immediate_operand"))
16970 (const_int 0)]))]
16971 "! TARGET_PARTIAL_REG_STALL
16972 && ix86_match_ccmode (insn, CCNOmode)
16973 && true_regnum (operands[2]) != AX_REG
16974 && peep2_reg_dead_p (1, operands[2])"
16975 [(parallel
16976 [(set (match_dup 0)
16977 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16978 (const_int 0)]))
16979 (set (match_dup 2)
16980 (and:QI (match_dup 2) (match_dup 3)))])])
16981
16982 (define_peephole2
16983 [(set (match_operand 0 "flags_reg_operand")
16984 (match_operator 1 "compare_operator"
16985 [(and:SI
16986 (zero_extract:SI
16987 (match_operand 2 "ext_register_operand")
16988 (const_int 8)
16989 (const_int 8))
16990 (match_operand 3 "const_int_operand"))
16991 (const_int 0)]))]
16992 "! TARGET_PARTIAL_REG_STALL
16993 && ix86_match_ccmode (insn, CCNOmode)
16994 && true_regnum (operands[2]) != AX_REG
16995 && peep2_reg_dead_p (1, operands[2])"
16996 [(parallel [(set (match_dup 0)
16997 (match_op_dup 1
16998 [(and:SI
16999 (zero_extract:SI
17000 (match_dup 2)
17001 (const_int 8)
17002 (const_int 8))
17003 (match_dup 3))
17004 (const_int 0)]))
17005 (set (zero_extract:SI (match_dup 2)
17006 (const_int 8)
17007 (const_int 8))
17008 (and:SI
17009 (zero_extract:SI
17010 (match_dup 2)
17011 (const_int 8)
17012 (const_int 8))
17013 (match_dup 3)))])])
17014
17015 ;; Don't do logical operations with memory inputs.
17016 (define_peephole2
17017 [(match_scratch:SI 2 "r")
17018 (parallel [(set (match_operand:SI 0 "register_operand")
17019 (match_operator:SI 3 "arith_or_logical_operator"
17020 [(match_dup 0)
17021 (match_operand:SI 1 "memory_operand")]))
17022 (clobber (reg:CC FLAGS_REG))])]
17023 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17024 [(set (match_dup 2) (match_dup 1))
17025 (parallel [(set (match_dup 0)
17026 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17027 (clobber (reg:CC FLAGS_REG))])])
17028
17029 (define_peephole2
17030 [(match_scratch:SI 2 "r")
17031 (parallel [(set (match_operand:SI 0 "register_operand")
17032 (match_operator:SI 3 "arith_or_logical_operator"
17033 [(match_operand:SI 1 "memory_operand")
17034 (match_dup 0)]))
17035 (clobber (reg:CC FLAGS_REG))])]
17036 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17037 [(set (match_dup 2) (match_dup 1))
17038 (parallel [(set (match_dup 0)
17039 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17040 (clobber (reg:CC FLAGS_REG))])])
17041
17042 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17043 ;; refers to the destination of the load!
17044
17045 (define_peephole2
17046 [(set (match_operand:SI 0 "register_operand")
17047 (match_operand:SI 1 "register_operand"))
17048 (parallel [(set (match_dup 0)
17049 (match_operator:SI 3 "commutative_operator"
17050 [(match_dup 0)
17051 (match_operand:SI 2 "memory_operand")]))
17052 (clobber (reg:CC FLAGS_REG))])]
17053 "REGNO (operands[0]) != REGNO (operands[1])
17054 && GENERAL_REGNO_P (REGNO (operands[0]))
17055 && GENERAL_REGNO_P (REGNO (operands[1]))"
17056 [(set (match_dup 0) (match_dup 4))
17057 (parallel [(set (match_dup 0)
17058 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17059 (clobber (reg:CC FLAGS_REG))])]
17060 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17061
17062 (define_peephole2
17063 [(set (match_operand 0 "register_operand")
17064 (match_operand 1 "register_operand"))
17065 (set (match_dup 0)
17066 (match_operator 3 "commutative_operator"
17067 [(match_dup 0)
17068 (match_operand 2 "memory_operand")]))]
17069 "REGNO (operands[0]) != REGNO (operands[1])
17070 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17071 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17072 [(set (match_dup 0) (match_dup 2))
17073 (set (match_dup 0)
17074 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17075
17076 ; Don't do logical operations with memory outputs
17077 ;
17078 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17079 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17080 ; the same decoder scheduling characteristics as the original.
17081
17082 (define_peephole2
17083 [(match_scratch:SI 2 "r")
17084 (parallel [(set (match_operand:SI 0 "memory_operand")
17085 (match_operator:SI 3 "arith_or_logical_operator"
17086 [(match_dup 0)
17087 (match_operand:SI 1 "nonmemory_operand")]))
17088 (clobber (reg:CC FLAGS_REG))])]
17089 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17090 /* Do not split stack checking probes. */
17091 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17092 [(set (match_dup 2) (match_dup 0))
17093 (parallel [(set (match_dup 2)
17094 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17095 (clobber (reg:CC FLAGS_REG))])
17096 (set (match_dup 0) (match_dup 2))])
17097
17098 (define_peephole2
17099 [(match_scratch:SI 2 "r")
17100 (parallel [(set (match_operand:SI 0 "memory_operand")
17101 (match_operator:SI 3 "arith_or_logical_operator"
17102 [(match_operand:SI 1 "nonmemory_operand")
17103 (match_dup 0)]))
17104 (clobber (reg:CC FLAGS_REG))])]
17105 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17106 /* Do not split stack checking probes. */
17107 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17108 [(set (match_dup 2) (match_dup 0))
17109 (parallel [(set (match_dup 2)
17110 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17111 (clobber (reg:CC FLAGS_REG))])
17112 (set (match_dup 0) (match_dup 2))])
17113
17114 ;; Attempt to use arith or logical operations with memory outputs with
17115 ;; setting of flags.
17116 (define_peephole2
17117 [(set (match_operand:SWI 0 "register_operand")
17118 (match_operand:SWI 1 "memory_operand"))
17119 (parallel [(set (match_dup 0)
17120 (match_operator:SWI 3 "plusminuslogic_operator"
17121 [(match_dup 0)
17122 (match_operand:SWI 2 "<nonmemory_operand>")]))
17123 (clobber (reg:CC FLAGS_REG))])
17124 (set (match_dup 1) (match_dup 0))
17125 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17126 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17127 && peep2_reg_dead_p (4, operands[0])
17128 && !reg_overlap_mentioned_p (operands[0], operands[1])
17129 && !reg_overlap_mentioned_p (operands[0], operands[2])
17130 && (<MODE>mode != QImode
17131 || immediate_operand (operands[2], QImode)
17132 || q_regs_operand (operands[2], QImode))
17133 && ix86_match_ccmode (peep2_next_insn (3),
17134 (GET_CODE (operands[3]) == PLUS
17135 || GET_CODE (operands[3]) == MINUS)
17136 ? CCGOCmode : CCNOmode)"
17137 [(parallel [(set (match_dup 4) (match_dup 5))
17138 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17139 (match_dup 2)]))])]
17140 {
17141 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17142 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17143 copy_rtx (operands[1]),
17144 copy_rtx (operands[2]));
17145 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17146 operands[5], const0_rtx);
17147 })
17148
17149 (define_peephole2
17150 [(parallel [(set (match_operand:SWI 0 "register_operand")
17151 (match_operator:SWI 2 "plusminuslogic_operator"
17152 [(match_dup 0)
17153 (match_operand:SWI 1 "memory_operand")]))
17154 (clobber (reg:CC FLAGS_REG))])
17155 (set (match_dup 1) (match_dup 0))
17156 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17157 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17158 && GET_CODE (operands[2]) != MINUS
17159 && peep2_reg_dead_p (3, operands[0])
17160 && !reg_overlap_mentioned_p (operands[0], operands[1])
17161 && ix86_match_ccmode (peep2_next_insn (2),
17162 GET_CODE (operands[2]) == PLUS
17163 ? CCGOCmode : CCNOmode)"
17164 [(parallel [(set (match_dup 3) (match_dup 4))
17165 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17166 (match_dup 0)]))])]
17167 {
17168 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17169 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17170 copy_rtx (operands[1]),
17171 copy_rtx (operands[0]));
17172 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17173 operands[4], const0_rtx);
17174 })
17175
17176 (define_peephole2
17177 [(set (match_operand:SWI12 0 "register_operand")
17178 (match_operand:SWI12 1 "memory_operand"))
17179 (parallel [(set (match_operand:SI 4 "register_operand")
17180 (match_operator:SI 3 "plusminuslogic_operator"
17181 [(match_dup 4)
17182 (match_operand:SI 2 "nonmemory_operand")]))
17183 (clobber (reg:CC FLAGS_REG))])
17184 (set (match_dup 1) (match_dup 0))
17185 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17186 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17187 && REG_P (operands[0]) && REG_P (operands[4])
17188 && REGNO (operands[0]) == REGNO (operands[4])
17189 && peep2_reg_dead_p (4, operands[0])
17190 && (<MODE>mode != QImode
17191 || immediate_operand (operands[2], SImode)
17192 || q_regs_operand (operands[2], SImode))
17193 && !reg_overlap_mentioned_p (operands[0], operands[1])
17194 && !reg_overlap_mentioned_p (operands[0], operands[2])
17195 && ix86_match_ccmode (peep2_next_insn (3),
17196 (GET_CODE (operands[3]) == PLUS
17197 || GET_CODE (operands[3]) == MINUS)
17198 ? CCGOCmode : CCNOmode)"
17199 [(parallel [(set (match_dup 4) (match_dup 5))
17200 (set (match_dup 1) (match_dup 6))])]
17201 {
17202 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17203 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17204 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17205 copy_rtx (operands[1]), operands[2]);
17206 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17207 operands[5], const0_rtx);
17208 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17209 copy_rtx (operands[1]),
17210 copy_rtx (operands[2]));
17211 })
17212
17213 ;; Attempt to always use XOR for zeroing registers.
17214 (define_peephole2
17215 [(set (match_operand 0 "register_operand")
17216 (match_operand 1 "const0_operand"))]
17217 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17218 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17219 && GENERAL_REG_P (operands[0])
17220 && peep2_regno_dead_p (0, FLAGS_REG)"
17221 [(parallel [(set (match_dup 0) (const_int 0))
17222 (clobber (reg:CC FLAGS_REG))])]
17223 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17224
17225 (define_peephole2
17226 [(set (strict_low_part (match_operand 0 "register_operand"))
17227 (const_int 0))]
17228 "(GET_MODE (operands[0]) == QImode
17229 || GET_MODE (operands[0]) == HImode)
17230 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17231 && peep2_regno_dead_p (0, FLAGS_REG)"
17232 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17233 (clobber (reg:CC FLAGS_REG))])])
17234
17235 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17236 (define_peephole2
17237 [(set (match_operand:SWI248 0 "register_operand")
17238 (const_int -1))]
17239 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17240 && peep2_regno_dead_p (0, FLAGS_REG)"
17241 [(parallel [(set (match_dup 0) (const_int -1))
17242 (clobber (reg:CC FLAGS_REG))])]
17243 {
17244 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17245 operands[0] = gen_lowpart (SImode, operands[0]);
17246 })
17247
17248 ;; Attempt to convert simple lea to add/shift.
17249 ;; These can be created by move expanders.
17250 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17251 ;; relevant lea instructions were already split.
17252
17253 (define_peephole2
17254 [(set (match_operand:SWI48 0 "register_operand")
17255 (plus:SWI48 (match_dup 0)
17256 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17257 "!TARGET_OPT_AGU
17258 && peep2_regno_dead_p (0, FLAGS_REG)"
17259 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17260 (clobber (reg:CC FLAGS_REG))])])
17261
17262 (define_peephole2
17263 [(set (match_operand:SWI48 0 "register_operand")
17264 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17265 (match_dup 0)))]
17266 "!TARGET_OPT_AGU
17267 && peep2_regno_dead_p (0, FLAGS_REG)"
17268 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17269 (clobber (reg:CC FLAGS_REG))])])
17270
17271 (define_peephole2
17272 [(set (match_operand:DI 0 "register_operand")
17273 (zero_extend:DI
17274 (plus:SI (match_operand:SI 1 "register_operand")
17275 (match_operand:SI 2 "nonmemory_operand"))))]
17276 "TARGET_64BIT && !TARGET_OPT_AGU
17277 && REGNO (operands[0]) == REGNO (operands[1])
17278 && peep2_regno_dead_p (0, FLAGS_REG)"
17279 [(parallel [(set (match_dup 0)
17280 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17281 (clobber (reg:CC FLAGS_REG))])])
17282
17283 (define_peephole2
17284 [(set (match_operand:DI 0 "register_operand")
17285 (zero_extend:DI
17286 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17287 (match_operand:SI 2 "register_operand"))))]
17288 "TARGET_64BIT && !TARGET_OPT_AGU
17289 && REGNO (operands[0]) == REGNO (operands[2])
17290 && peep2_regno_dead_p (0, FLAGS_REG)"
17291 [(parallel [(set (match_dup 0)
17292 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17293 (clobber (reg:CC FLAGS_REG))])])
17294
17295 (define_peephole2
17296 [(set (match_operand:SWI48 0 "register_operand")
17297 (mult:SWI48 (match_dup 0)
17298 (match_operand:SWI48 1 "const_int_operand")))]
17299 "exact_log2 (INTVAL (operands[1])) >= 0
17300 && peep2_regno_dead_p (0, FLAGS_REG)"
17301 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17302 (clobber (reg:CC FLAGS_REG))])]
17303 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17304
17305 (define_peephole2
17306 [(set (match_operand:DI 0 "register_operand")
17307 (zero_extend:DI
17308 (mult:SI (match_operand:SI 1 "register_operand")
17309 (match_operand:SI 2 "const_int_operand"))))]
17310 "TARGET_64BIT
17311 && exact_log2 (INTVAL (operands[2])) >= 0
17312 && REGNO (operands[0]) == REGNO (operands[1])
17313 && peep2_regno_dead_p (0, FLAGS_REG)"
17314 [(parallel [(set (match_dup 0)
17315 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
17316 (clobber (reg:CC FLAGS_REG))])]
17317 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17318
17319 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17320 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17321 ;; On many CPUs it is also faster, since special hardware to avoid esp
17322 ;; dependencies is present.
17323
17324 ;; While some of these conversions may be done using splitters, we use
17325 ;; peepholes in order to allow combine_stack_adjustments pass to see
17326 ;; nonobfuscated RTL.
17327
17328 ;; Convert prologue esp subtractions to push.
17329 ;; We need register to push. In order to keep verify_flow_info happy we have
17330 ;; two choices
17331 ;; - use scratch and clobber it in order to avoid dependencies
17332 ;; - use already live register
17333 ;; We can't use the second way right now, since there is no reliable way how to
17334 ;; verify that given register is live. First choice will also most likely in
17335 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17336 ;; call clobbered registers are dead. We may want to use base pointer as an
17337 ;; alternative when no register is available later.
17338
17339 (define_peephole2
17340 [(match_scratch:W 1 "r")
17341 (parallel [(set (reg:P SP_REG)
17342 (plus:P (reg:P SP_REG)
17343 (match_operand:P 0 "const_int_operand")))
17344 (clobber (reg:CC FLAGS_REG))
17345 (clobber (mem:BLK (scratch)))])]
17346 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17347 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17348 [(clobber (match_dup 1))
17349 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17350 (clobber (mem:BLK (scratch)))])])
17351
17352 (define_peephole2
17353 [(match_scratch:W 1 "r")
17354 (parallel [(set (reg:P SP_REG)
17355 (plus:P (reg:P SP_REG)
17356 (match_operand:P 0 "const_int_operand")))
17357 (clobber (reg:CC FLAGS_REG))
17358 (clobber (mem:BLK (scratch)))])]
17359 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17360 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17361 [(clobber (match_dup 1))
17362 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17363 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17364 (clobber (mem:BLK (scratch)))])])
17365
17366 ;; Convert esp subtractions to push.
17367 (define_peephole2
17368 [(match_scratch:W 1 "r")
17369 (parallel [(set (reg:P SP_REG)
17370 (plus:P (reg:P SP_REG)
17371 (match_operand:P 0 "const_int_operand")))
17372 (clobber (reg:CC FLAGS_REG))])]
17373 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17374 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17375 [(clobber (match_dup 1))
17376 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17377
17378 (define_peephole2
17379 [(match_scratch:W 1 "r")
17380 (parallel [(set (reg:P SP_REG)
17381 (plus:P (reg:P SP_REG)
17382 (match_operand:P 0 "const_int_operand")))
17383 (clobber (reg:CC FLAGS_REG))])]
17384 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17385 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17386 [(clobber (match_dup 1))
17387 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17388 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17389
17390 ;; Convert epilogue deallocator to pop.
17391 (define_peephole2
17392 [(match_scratch:W 1 "r")
17393 (parallel [(set (reg:P SP_REG)
17394 (plus:P (reg:P SP_REG)
17395 (match_operand:P 0 "const_int_operand")))
17396 (clobber (reg:CC FLAGS_REG))
17397 (clobber (mem:BLK (scratch)))])]
17398 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17399 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17400 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17401 (clobber (mem:BLK (scratch)))])])
17402
17403 ;; Two pops case is tricky, since pop causes dependency
17404 ;; on destination register. We use two registers if available.
17405 (define_peephole2
17406 [(match_scratch:W 1 "r")
17407 (match_scratch:W 2 "r")
17408 (parallel [(set (reg:P SP_REG)
17409 (plus:P (reg:P SP_REG)
17410 (match_operand:P 0 "const_int_operand")))
17411 (clobber (reg:CC FLAGS_REG))
17412 (clobber (mem:BLK (scratch)))])]
17413 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17414 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17415 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17416 (clobber (mem:BLK (scratch)))])
17417 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17418
17419 (define_peephole2
17420 [(match_scratch:W 1 "r")
17421 (parallel [(set (reg:P SP_REG)
17422 (plus:P (reg:P SP_REG)
17423 (match_operand:P 0 "const_int_operand")))
17424 (clobber (reg:CC FLAGS_REG))
17425 (clobber (mem:BLK (scratch)))])]
17426 "optimize_insn_for_size_p ()
17427 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17428 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17429 (clobber (mem:BLK (scratch)))])
17430 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17431
17432 ;; Convert esp additions to pop.
17433 (define_peephole2
17434 [(match_scratch:W 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 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17440 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17441
17442 ;; Two pops case is tricky, since pop causes dependency
17443 ;; on destination register. We use two registers if available.
17444 (define_peephole2
17445 [(match_scratch:W 1 "r")
17446 (match_scratch:W 2 "r")
17447 (parallel [(set (reg:P SP_REG)
17448 (plus:P (reg:P SP_REG)
17449 (match_operand:P 0 "const_int_operand")))
17450 (clobber (reg:CC FLAGS_REG))])]
17451 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17452 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17453 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17454
17455 (define_peephole2
17456 [(match_scratch:W 1 "r")
17457 (parallel [(set (reg:P SP_REG)
17458 (plus:P (reg:P SP_REG)
17459 (match_operand:P 0 "const_int_operand")))
17460 (clobber (reg:CC FLAGS_REG))])]
17461 "optimize_insn_for_size_p ()
17462 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17463 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17464 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17465 \f
17466 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17467 ;; required and register dies. Similarly for 128 to -128.
17468 (define_peephole2
17469 [(set (match_operand 0 "flags_reg_operand")
17470 (match_operator 1 "compare_operator"
17471 [(match_operand 2 "register_operand")
17472 (match_operand 3 "const_int_operand")]))]
17473 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17474 && incdec_operand (operands[3], GET_MODE (operands[3])))
17475 || (!TARGET_FUSE_CMP_AND_BRANCH
17476 && INTVAL (operands[3]) == 128))
17477 && ix86_match_ccmode (insn, CCGCmode)
17478 && peep2_reg_dead_p (1, operands[2])"
17479 [(parallel [(set (match_dup 0)
17480 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17481 (clobber (match_dup 2))])])
17482 \f
17483 ;; Convert imul by three, five and nine into lea
17484 (define_peephole2
17485 [(parallel
17486 [(set (match_operand:SWI48 0 "register_operand")
17487 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17488 (match_operand:SWI48 2 "const359_operand")))
17489 (clobber (reg:CC FLAGS_REG))])]
17490 "!TARGET_PARTIAL_REG_STALL
17491 || <MODE>mode == SImode
17492 || optimize_function_for_size_p (cfun)"
17493 [(set (match_dup 0)
17494 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17495 (match_dup 1)))]
17496 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17497
17498 (define_peephole2
17499 [(parallel
17500 [(set (match_operand:SWI48 0 "register_operand")
17501 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17502 (match_operand:SWI48 2 "const359_operand")))
17503 (clobber (reg:CC FLAGS_REG))])]
17504 "optimize_insn_for_speed_p ()
17505 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17506 [(set (match_dup 0) (match_dup 1))
17507 (set (match_dup 0)
17508 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17509 (match_dup 0)))]
17510 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17511
17512 ;; imul $32bit_imm, mem, reg is vector decoded, while
17513 ;; imul $32bit_imm, reg, reg is direct decoded.
17514 (define_peephole2
17515 [(match_scratch:SWI48 3 "r")
17516 (parallel [(set (match_operand:SWI48 0 "register_operand")
17517 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17518 (match_operand:SWI48 2 "immediate_operand")))
17519 (clobber (reg:CC FLAGS_REG))])]
17520 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17521 && !satisfies_constraint_K (operands[2])"
17522 [(set (match_dup 3) (match_dup 1))
17523 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17524 (clobber (reg:CC FLAGS_REG))])])
17525
17526 (define_peephole2
17527 [(match_scratch:SI 3 "r")
17528 (parallel [(set (match_operand:DI 0 "register_operand")
17529 (zero_extend:DI
17530 (mult:SI (match_operand:SI 1 "memory_operand")
17531 (match_operand:SI 2 "immediate_operand"))))
17532 (clobber (reg:CC FLAGS_REG))])]
17533 "TARGET_64BIT
17534 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17535 && !satisfies_constraint_K (operands[2])"
17536 [(set (match_dup 3) (match_dup 1))
17537 (parallel [(set (match_dup 0)
17538 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17539 (clobber (reg:CC FLAGS_REG))])])
17540
17541 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17542 ;; Convert it into imul reg, reg
17543 ;; It would be better to force assembler to encode instruction using long
17544 ;; immediate, but there is apparently no way to do so.
17545 (define_peephole2
17546 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17547 (mult:SWI248
17548 (match_operand:SWI248 1 "nonimmediate_operand")
17549 (match_operand:SWI248 2 "const_int_operand")))
17550 (clobber (reg:CC FLAGS_REG))])
17551 (match_scratch:SWI248 3 "r")]
17552 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17553 && satisfies_constraint_K (operands[2])"
17554 [(set (match_dup 3) (match_dup 2))
17555 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17556 (clobber (reg:CC FLAGS_REG))])]
17557 {
17558 if (!rtx_equal_p (operands[0], operands[1]))
17559 emit_move_insn (operands[0], operands[1]);
17560 })
17561
17562 ;; After splitting up read-modify operations, array accesses with memory
17563 ;; operands might end up in form:
17564 ;; sall $2, %eax
17565 ;; movl 4(%esp), %edx
17566 ;; addl %edx, %eax
17567 ;; instead of pre-splitting:
17568 ;; sall $2, %eax
17569 ;; addl 4(%esp), %eax
17570 ;; Turn it into:
17571 ;; movl 4(%esp), %edx
17572 ;; leal (%edx,%eax,4), %eax
17573
17574 (define_peephole2
17575 [(match_scratch:W 5 "r")
17576 (parallel [(set (match_operand 0 "register_operand")
17577 (ashift (match_operand 1 "register_operand")
17578 (match_operand 2 "const_int_operand")))
17579 (clobber (reg:CC FLAGS_REG))])
17580 (parallel [(set (match_operand 3 "register_operand")
17581 (plus (match_dup 0)
17582 (match_operand 4 "x86_64_general_operand")))
17583 (clobber (reg:CC FLAGS_REG))])]
17584 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17585 /* Validate MODE for lea. */
17586 && ((!TARGET_PARTIAL_REG_STALL
17587 && (GET_MODE (operands[0]) == QImode
17588 || GET_MODE (operands[0]) == HImode))
17589 || GET_MODE (operands[0]) == SImode
17590 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17591 && (rtx_equal_p (operands[0], operands[3])
17592 || peep2_reg_dead_p (2, operands[0]))
17593 /* We reorder load and the shift. */
17594 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17595 [(set (match_dup 5) (match_dup 4))
17596 (set (match_dup 0) (match_dup 1))]
17597 {
17598 enum machine_mode op1mode = GET_MODE (operands[1]);
17599 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17600 int scale = 1 << INTVAL (operands[2]);
17601 rtx index = gen_lowpart (word_mode, operands[1]);
17602 rtx base = gen_lowpart (word_mode, operands[5]);
17603 rtx dest = gen_lowpart (mode, operands[3]);
17604
17605 operands[1] = gen_rtx_PLUS (word_mode, base,
17606 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17607 operands[5] = base;
17608 if (mode != word_mode)
17609 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17610 if (op1mode != word_mode)
17611 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17612 operands[0] = dest;
17613 })
17614 \f
17615 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17616 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17617 ;; caught for use by garbage collectors and the like. Using an insn that
17618 ;; maps to SIGILL makes it more likely the program will rightfully die.
17619 ;; Keeping with tradition, "6" is in honor of #UD.
17620 (define_insn "trap"
17621 [(trap_if (const_int 1) (const_int 6))]
17622 ""
17623 { return ASM_SHORT "0x0b0f"; }
17624 [(set_attr "length" "2")])
17625
17626 (define_expand "prefetch"
17627 [(prefetch (match_operand 0 "address_operand")
17628 (match_operand:SI 1 "const_int_operand")
17629 (match_operand:SI 2 "const_int_operand"))]
17630 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_AVX512PF"
17631 {
17632 bool write = INTVAL (operands[1]) != 0;
17633 int locality = INTVAL (operands[2]);
17634
17635 gcc_assert (IN_RANGE (locality, 0, 3));
17636
17637 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17638 supported by SSE counterpart or the SSE prefetch is not available
17639 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17640 of locality. */
17641 if (TARGET_AVX512PF && write)
17642 operands[2] = const1_rtx;
17643 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17644 operands[2] = GEN_INT (3);
17645 else
17646 operands[1] = const0_rtx;
17647 })
17648
17649 (define_insn "*prefetch_sse"
17650 [(prefetch (match_operand 0 "address_operand" "p")
17651 (const_int 0)
17652 (match_operand:SI 1 "const_int_operand"))]
17653 "TARGET_PREFETCH_SSE"
17654 {
17655 static const char * const patterns[4] = {
17656 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17657 };
17658
17659 int locality = INTVAL (operands[1]);
17660 gcc_assert (IN_RANGE (locality, 0, 3));
17661
17662 return patterns[locality];
17663 }
17664 [(set_attr "type" "sse")
17665 (set_attr "atom_sse_attr" "prefetch")
17666 (set (attr "length_address")
17667 (symbol_ref "memory_address_length (operands[0], false)"))
17668 (set_attr "memory" "none")])
17669
17670 (define_insn "*prefetch_3dnow"
17671 [(prefetch (match_operand 0 "address_operand" "p")
17672 (match_operand:SI 1 "const_int_operand" "n")
17673 (const_int 3))]
17674 "TARGET_PRFCHW"
17675 {
17676 if (INTVAL (operands[1]) == 0)
17677 return "prefetch\t%a0";
17678 else
17679 return "prefetchw\t%a0";
17680 }
17681 [(set_attr "type" "mmx")
17682 (set (attr "length_address")
17683 (symbol_ref "memory_address_length (operands[0], false)"))
17684 (set_attr "memory" "none")])
17685
17686 (define_insn "*prefetch_avx512pf_<mode>"
17687 [(prefetch (match_operand:P 0 "address_operand" "p")
17688 (const_int 1)
17689 (const_int 1))]
17690 "TARGET_AVX512PF"
17691 "prefetchwt1\t%a0";
17692 [(set_attr "type" "sse")
17693 (set_attr "prefix" "evex")
17694 (set (attr "length_address")
17695 (symbol_ref "memory_address_length (operands[0], false)"))
17696 (set_attr "memory" "none")])
17697
17698 (define_expand "stack_protect_set"
17699 [(match_operand 0 "memory_operand")
17700 (match_operand 1 "memory_operand")]
17701 "TARGET_SSP_TLS_GUARD"
17702 {
17703 rtx (*insn)(rtx, rtx);
17704
17705 #ifdef TARGET_THREAD_SSP_OFFSET
17706 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17707 insn = (TARGET_LP64
17708 ? gen_stack_tls_protect_set_di
17709 : gen_stack_tls_protect_set_si);
17710 #else
17711 insn = (TARGET_LP64
17712 ? gen_stack_protect_set_di
17713 : gen_stack_protect_set_si);
17714 #endif
17715
17716 emit_insn (insn (operands[0], operands[1]));
17717 DONE;
17718 })
17719
17720 (define_insn "stack_protect_set_<mode>"
17721 [(set (match_operand:PTR 0 "memory_operand" "=m")
17722 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17723 UNSPEC_SP_SET))
17724 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17725 (clobber (reg:CC FLAGS_REG))]
17726 "TARGET_SSP_TLS_GUARD"
17727 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17728 [(set_attr "type" "multi")])
17729
17730 (define_insn "stack_tls_protect_set_<mode>"
17731 [(set (match_operand:PTR 0 "memory_operand" "=m")
17732 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17733 UNSPEC_SP_TLS_SET))
17734 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17735 (clobber (reg:CC FLAGS_REG))]
17736 ""
17737 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17738 [(set_attr "type" "multi")])
17739
17740 (define_expand "stack_protect_test"
17741 [(match_operand 0 "memory_operand")
17742 (match_operand 1 "memory_operand")
17743 (match_operand 2)]
17744 "TARGET_SSP_TLS_GUARD"
17745 {
17746 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17747
17748 rtx (*insn)(rtx, rtx, rtx);
17749
17750 #ifdef TARGET_THREAD_SSP_OFFSET
17751 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17752 insn = (TARGET_LP64
17753 ? gen_stack_tls_protect_test_di
17754 : gen_stack_tls_protect_test_si);
17755 #else
17756 insn = (TARGET_LP64
17757 ? gen_stack_protect_test_di
17758 : gen_stack_protect_test_si);
17759 #endif
17760
17761 emit_insn (insn (flags, operands[0], operands[1]));
17762
17763 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17764 flags, const0_rtx, operands[2]));
17765 DONE;
17766 })
17767
17768 (define_insn "stack_protect_test_<mode>"
17769 [(set (match_operand:CCZ 0 "flags_reg_operand")
17770 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17771 (match_operand:PTR 2 "memory_operand" "m")]
17772 UNSPEC_SP_TEST))
17773 (clobber (match_scratch:PTR 3 "=&r"))]
17774 "TARGET_SSP_TLS_GUARD"
17775 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17776 [(set_attr "type" "multi")])
17777
17778 (define_insn "stack_tls_protect_test_<mode>"
17779 [(set (match_operand:CCZ 0 "flags_reg_operand")
17780 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17781 (match_operand:PTR 2 "const_int_operand" "i")]
17782 UNSPEC_SP_TLS_TEST))
17783 (clobber (match_scratch:PTR 3 "=r"))]
17784 ""
17785 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17786 [(set_attr "type" "multi")])
17787
17788 (define_insn "sse4_2_crc32<mode>"
17789 [(set (match_operand:SI 0 "register_operand" "=r")
17790 (unspec:SI
17791 [(match_operand:SI 1 "register_operand" "0")
17792 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17793 UNSPEC_CRC32))]
17794 "TARGET_SSE4_2 || TARGET_CRC32"
17795 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17796 [(set_attr "type" "sselog1")
17797 (set_attr "prefix_rep" "1")
17798 (set_attr "prefix_extra" "1")
17799 (set (attr "prefix_data16")
17800 (if_then_else (match_operand:HI 2)
17801 (const_string "1")
17802 (const_string "*")))
17803 (set (attr "prefix_rex")
17804 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17805 (const_string "1")
17806 (const_string "*")))
17807 (set_attr "mode" "SI")])
17808
17809 (define_insn "sse4_2_crc32di"
17810 [(set (match_operand:DI 0 "register_operand" "=r")
17811 (unspec:DI
17812 [(match_operand:DI 1 "register_operand" "0")
17813 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17814 UNSPEC_CRC32))]
17815 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17816 "crc32{q}\t{%2, %0|%0, %2}"
17817 [(set_attr "type" "sselog1")
17818 (set_attr "prefix_rep" "1")
17819 (set_attr "prefix_extra" "1")
17820 (set_attr "mode" "DI")])
17821
17822 (define_insn "rdpmc"
17823 [(set (match_operand:DI 0 "register_operand" "=A")
17824 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17825 UNSPECV_RDPMC))]
17826 "!TARGET_64BIT"
17827 "rdpmc"
17828 [(set_attr "type" "other")
17829 (set_attr "length" "2")])
17830
17831 (define_insn "rdpmc_rex64"
17832 [(set (match_operand:DI 0 "register_operand" "=a")
17833 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17834 UNSPECV_RDPMC))
17835 (set (match_operand:DI 1 "register_operand" "=d")
17836 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17837 "TARGET_64BIT"
17838 "rdpmc"
17839 [(set_attr "type" "other")
17840 (set_attr "length" "2")])
17841
17842 (define_insn "rdtsc"
17843 [(set (match_operand:DI 0 "register_operand" "=A")
17844 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17845 "!TARGET_64BIT"
17846 "rdtsc"
17847 [(set_attr "type" "other")
17848 (set_attr "length" "2")])
17849
17850 (define_insn "rdtsc_rex64"
17851 [(set (match_operand:DI 0 "register_operand" "=a")
17852 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17853 (set (match_operand:DI 1 "register_operand" "=d")
17854 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17855 "TARGET_64BIT"
17856 "rdtsc"
17857 [(set_attr "type" "other")
17858 (set_attr "length" "2")])
17859
17860 (define_insn "rdtscp"
17861 [(set (match_operand:DI 0 "register_operand" "=A")
17862 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17863 (set (match_operand:SI 1 "register_operand" "=c")
17864 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17865 "!TARGET_64BIT"
17866 "rdtscp"
17867 [(set_attr "type" "other")
17868 (set_attr "length" "3")])
17869
17870 (define_insn "rdtscp_rex64"
17871 [(set (match_operand:DI 0 "register_operand" "=a")
17872 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17873 (set (match_operand:DI 1 "register_operand" "=d")
17874 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17875 (set (match_operand:SI 2 "register_operand" "=c")
17876 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17877 "TARGET_64BIT"
17878 "rdtscp"
17879 [(set_attr "type" "other")
17880 (set_attr "length" "3")])
17881
17882 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17883 ;;
17884 ;; FXSR, XSAVE and XSAVEOPT instructions
17885 ;;
17886 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17887
17888 (define_insn "fxsave"
17889 [(set (match_operand:BLK 0 "memory_operand" "=m")
17890 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17891 "TARGET_FXSR"
17892 "fxsave\t%0"
17893 [(set_attr "type" "other")
17894 (set_attr "memory" "store")
17895 (set (attr "length")
17896 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17897
17898 (define_insn "fxsave64"
17899 [(set (match_operand:BLK 0 "memory_operand" "=m")
17900 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17901 "TARGET_64BIT && TARGET_FXSR"
17902 "fxsave64\t%0"
17903 [(set_attr "type" "other")
17904 (set_attr "memory" "store")
17905 (set (attr "length")
17906 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17907
17908 (define_insn "fxrstor"
17909 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17910 UNSPECV_FXRSTOR)]
17911 "TARGET_FXSR"
17912 "fxrstor\t%0"
17913 [(set_attr "type" "other")
17914 (set_attr "memory" "load")
17915 (set (attr "length")
17916 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17917
17918 (define_insn "fxrstor64"
17919 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17920 UNSPECV_FXRSTOR64)]
17921 "TARGET_64BIT && TARGET_FXSR"
17922 "fxrstor64\t%0"
17923 [(set_attr "type" "other")
17924 (set_attr "memory" "load")
17925 (set (attr "length")
17926 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17927
17928 (define_int_iterator ANY_XSAVE
17929 [UNSPECV_XSAVE
17930 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17931
17932 (define_int_iterator ANY_XSAVE64
17933 [UNSPECV_XSAVE64
17934 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17935
17936 (define_int_attr xsave
17937 [(UNSPECV_XSAVE "xsave")
17938 (UNSPECV_XSAVE64 "xsave64")
17939 (UNSPECV_XSAVEOPT "xsaveopt")
17940 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17941
17942 (define_insn "<xsave>"
17943 [(set (match_operand:BLK 0 "memory_operand" "=m")
17944 (unspec_volatile:BLK
17945 [(match_operand:DI 1 "register_operand" "A")]
17946 ANY_XSAVE))]
17947 "!TARGET_64BIT && TARGET_XSAVE"
17948 "<xsave>\t%0"
17949 [(set_attr "type" "other")
17950 (set_attr "memory" "store")
17951 (set (attr "length")
17952 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17953
17954 (define_insn "<xsave>_rex64"
17955 [(set (match_operand:BLK 0 "memory_operand" "=m")
17956 (unspec_volatile:BLK
17957 [(match_operand:SI 1 "register_operand" "a")
17958 (match_operand:SI 2 "register_operand" "d")]
17959 ANY_XSAVE))]
17960 "TARGET_64BIT && TARGET_XSAVE"
17961 "<xsave>\t%0"
17962 [(set_attr "type" "other")
17963 (set_attr "memory" "store")
17964 (set (attr "length")
17965 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17966
17967 (define_insn "<xsave>"
17968 [(set (match_operand:BLK 0 "memory_operand" "=m")
17969 (unspec_volatile:BLK
17970 [(match_operand:SI 1 "register_operand" "a")
17971 (match_operand:SI 2 "register_operand" "d")]
17972 ANY_XSAVE64))]
17973 "TARGET_64BIT && TARGET_XSAVE"
17974 "<xsave>\t%0"
17975 [(set_attr "type" "other")
17976 (set_attr "memory" "store")
17977 (set (attr "length")
17978 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17979
17980 (define_insn "xrstor"
17981 [(unspec_volatile:BLK
17982 [(match_operand:BLK 0 "memory_operand" "m")
17983 (match_operand:DI 1 "register_operand" "A")]
17984 UNSPECV_XRSTOR)]
17985 "!TARGET_64BIT && TARGET_XSAVE"
17986 "xrstor\t%0"
17987 [(set_attr "type" "other")
17988 (set_attr "memory" "load")
17989 (set (attr "length")
17990 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17991
17992 (define_insn "xrstor_rex64"
17993 [(unspec_volatile:BLK
17994 [(match_operand:BLK 0 "memory_operand" "m")
17995 (match_operand:SI 1 "register_operand" "a")
17996 (match_operand:SI 2 "register_operand" "d")]
17997 UNSPECV_XRSTOR)]
17998 "TARGET_64BIT && TARGET_XSAVE"
17999 "xrstor\t%0"
18000 [(set_attr "type" "other")
18001 (set_attr "memory" "load")
18002 (set (attr "length")
18003 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18004
18005 (define_insn "xrstor64"
18006 [(unspec_volatile:BLK
18007 [(match_operand:BLK 0 "memory_operand" "m")
18008 (match_operand:SI 1 "register_operand" "a")
18009 (match_operand:SI 2 "register_operand" "d")]
18010 UNSPECV_XRSTOR64)]
18011 "TARGET_64BIT && TARGET_XSAVE"
18012 "xrstor64\t%0"
18013 [(set_attr "type" "other")
18014 (set_attr "memory" "load")
18015 (set (attr "length")
18016 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18017
18018 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18019 ;;
18020 ;; LWP instructions
18021 ;;
18022 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18023
18024 (define_expand "lwp_llwpcb"
18025 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18026 UNSPECV_LLWP_INTRINSIC)]
18027 "TARGET_LWP")
18028
18029 (define_insn "*lwp_llwpcb<mode>1"
18030 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18031 UNSPECV_LLWP_INTRINSIC)]
18032 "TARGET_LWP"
18033 "llwpcb\t%0"
18034 [(set_attr "type" "lwp")
18035 (set_attr "mode" "<MODE>")
18036 (set_attr "length" "5")])
18037
18038 (define_expand "lwp_slwpcb"
18039 [(set (match_operand 0 "register_operand" "=r")
18040 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18041 "TARGET_LWP"
18042 {
18043 rtx (*insn)(rtx);
18044
18045 insn = (Pmode == DImode
18046 ? gen_lwp_slwpcbdi
18047 : gen_lwp_slwpcbsi);
18048
18049 emit_insn (insn (operands[0]));
18050 DONE;
18051 })
18052
18053 (define_insn "lwp_slwpcb<mode>"
18054 [(set (match_operand:P 0 "register_operand" "=r")
18055 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18056 "TARGET_LWP"
18057 "slwpcb\t%0"
18058 [(set_attr "type" "lwp")
18059 (set_attr "mode" "<MODE>")
18060 (set_attr "length" "5")])
18061
18062 (define_expand "lwp_lwpval<mode>3"
18063 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18064 (match_operand:SI 2 "nonimmediate_operand" "rm")
18065 (match_operand:SI 3 "const_int_operand" "i")]
18066 UNSPECV_LWPVAL_INTRINSIC)]
18067 "TARGET_LWP"
18068 ;; Avoid unused variable warning.
18069 "(void) operands[0];")
18070
18071 (define_insn "*lwp_lwpval<mode>3_1"
18072 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18073 (match_operand:SI 1 "nonimmediate_operand" "rm")
18074 (match_operand:SI 2 "const_int_operand" "i")]
18075 UNSPECV_LWPVAL_INTRINSIC)]
18076 "TARGET_LWP"
18077 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18078 [(set_attr "type" "lwp")
18079 (set_attr "mode" "<MODE>")
18080 (set (attr "length")
18081 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18082
18083 (define_expand "lwp_lwpins<mode>3"
18084 [(set (reg:CCC FLAGS_REG)
18085 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18086 (match_operand:SI 2 "nonimmediate_operand" "rm")
18087 (match_operand:SI 3 "const_int_operand" "i")]
18088 UNSPECV_LWPINS_INTRINSIC))
18089 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18090 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18091 "TARGET_LWP")
18092
18093 (define_insn "*lwp_lwpins<mode>3_1"
18094 [(set (reg:CCC FLAGS_REG)
18095 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18096 (match_operand:SI 1 "nonimmediate_operand" "rm")
18097 (match_operand:SI 2 "const_int_operand" "i")]
18098 UNSPECV_LWPINS_INTRINSIC))]
18099 "TARGET_LWP"
18100 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18101 [(set_attr "type" "lwp")
18102 (set_attr "mode" "<MODE>")
18103 (set (attr "length")
18104 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18105
18106 (define_int_iterator RDFSGSBASE
18107 [UNSPECV_RDFSBASE
18108 UNSPECV_RDGSBASE])
18109
18110 (define_int_iterator WRFSGSBASE
18111 [UNSPECV_WRFSBASE
18112 UNSPECV_WRGSBASE])
18113
18114 (define_int_attr fsgs
18115 [(UNSPECV_RDFSBASE "fs")
18116 (UNSPECV_RDGSBASE "gs")
18117 (UNSPECV_WRFSBASE "fs")
18118 (UNSPECV_WRGSBASE "gs")])
18119
18120 (define_insn "rd<fsgs>base<mode>"
18121 [(set (match_operand:SWI48 0 "register_operand" "=r")
18122 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18123 "TARGET_64BIT && TARGET_FSGSBASE"
18124 "rd<fsgs>base\t%0"
18125 [(set_attr "type" "other")
18126 (set_attr "prefix_extra" "2")])
18127
18128 (define_insn "wr<fsgs>base<mode>"
18129 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18130 WRFSGSBASE)]
18131 "TARGET_64BIT && TARGET_FSGSBASE"
18132 "wr<fsgs>base\t%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_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18139 (set (reg:CCC FLAGS_REG)
18140 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18141 "TARGET_RDRND"
18142 "rdrand\t%0"
18143 [(set_attr "type" "other")
18144 (set_attr "prefix_extra" "1")])
18145
18146 (define_insn "rdseed<mode>_1"
18147 [(set (match_operand:SWI248 0 "register_operand" "=r")
18148 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18149 (set (reg:CCC FLAGS_REG)
18150 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18151 "TARGET_RDSEED"
18152 "rdseed\t%0"
18153 [(set_attr "type" "other")
18154 (set_attr "prefix_extra" "1")])
18155
18156 (define_expand "pause"
18157 [(set (match_dup 0)
18158 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18159 ""
18160 {
18161 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18162 MEM_VOLATILE_P (operands[0]) = 1;
18163 })
18164
18165 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18166 ;; They have the same encoding.
18167 (define_insn "*pause"
18168 [(set (match_operand:BLK 0)
18169 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18170 ""
18171 "rep%; nop"
18172 [(set_attr "length" "2")
18173 (set_attr "memory" "unknown")])
18174
18175 (define_expand "xbegin"
18176 [(set (match_operand:SI 0 "register_operand")
18177 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18178 "TARGET_RTM"
18179 {
18180 rtx label = gen_label_rtx ();
18181
18182 /* xbegin is emitted as jump_insn, so reload won't be able
18183 to reload its operand. Force the value into AX hard register. */
18184 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18185 emit_move_insn (ax_reg, constm1_rtx);
18186
18187 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18188
18189 emit_label (label);
18190 LABEL_NUSES (label) = 1;
18191
18192 emit_move_insn (operands[0], ax_reg);
18193
18194 DONE;
18195 })
18196
18197 (define_insn "xbegin_1"
18198 [(set (pc)
18199 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18200 (const_int 0))
18201 (label_ref (match_operand 1))
18202 (pc)))
18203 (set (match_operand:SI 0 "register_operand" "+a")
18204 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18205 "TARGET_RTM"
18206 "xbegin\t%l1"
18207 [(set_attr "type" "other")
18208 (set_attr "length" "6")])
18209
18210 (define_insn "xend"
18211 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18212 "TARGET_RTM"
18213 "xend"
18214 [(set_attr "type" "other")
18215 (set_attr "length" "3")])
18216
18217 (define_insn "xabort"
18218 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18219 UNSPECV_XABORT)]
18220 "TARGET_RTM"
18221 "xabort\t%0"
18222 [(set_attr "type" "other")
18223 (set_attr "length" "3")])
18224
18225 (define_expand "xtest"
18226 [(set (match_operand:QI 0 "register_operand")
18227 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18228 "TARGET_RTM"
18229 {
18230 emit_insn (gen_xtest_1 ());
18231
18232 ix86_expand_setcc (operands[0], NE,
18233 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18234 DONE;
18235 })
18236
18237 (define_insn "xtest_1"
18238 [(set (reg:CCZ FLAGS_REG)
18239 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18240 "TARGET_RTM"
18241 "xtest"
18242 [(set_attr "type" "other")
18243 (set_attr "length" "3")])
18244
18245 ;; MPX instructions
18246
18247 (define_expand "<mode>_mk"
18248 [(set (match_operand:BND 0 "register_operand")
18249 (unspec:BND
18250 [(mem:<bnd_ptr>
18251 (match_par_dup 3
18252 [(match_operand:<bnd_ptr> 1 "register_operand")
18253 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18254 UNSPEC_BNDMK))]
18255 "TARGET_MPX"
18256 {
18257 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18258 operands[2]),
18259 UNSPEC_BNDMK_ADDR);
18260 })
18261
18262 (define_insn "*<mode>_mk"
18263 [(set (match_operand:BND 0 "register_operand" "=B")
18264 (unspec:BND
18265 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18266 [(unspec:<bnd_ptr>
18267 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18268 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18269 UNSPEC_BNDMK_ADDR)])]
18270 UNSPEC_BNDMK))]
18271 "TARGET_MPX"
18272 "bndmk\t{%3, %0|%0, %3}"
18273 [(set_attr "type" "mpxmk")])
18274
18275 (define_expand "mov<mode>"
18276 [(set (match_operand:BND 0 "general_operand")
18277 (match_operand:BND 1 "general_operand"))]
18278 "TARGET_MPX"
18279 {
18280 ix86_expand_move (<MODE>mode, operands);DONE;
18281 })
18282
18283 (define_insn "*mov<mode>_internal_mpx"
18284 [(set (match_operand:BND 0 "nonimmediate_operand" "=B,m")
18285 (match_operand:BND 1 "general_operand" "Bm,B"))]
18286 "TARGET_MPX"
18287 "bndmov\t{%1, %0|%0, %1}"
18288 [(set_attr "type" "mpxmov")])
18289
18290 (define_expand "<mode>_<bndcheck>"
18291 [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18292 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18293 (set (match_dup 2)
18294 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18295 "TARGET_MPX"
18296 {
18297 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18298 MEM_VOLATILE_P (operands[2]) = 1;
18299 })
18300
18301 (define_insn "*<mode>_<bndcheck>"
18302 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "B")
18303 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "p")] BNDCHECK)
18304 (set (match_operand:BLK 2 "bnd_mem_operator")
18305 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18306 "TARGET_MPX"
18307 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18308 [(set_attr "type" "mpxchk")])
18309
18310 (define_expand "<mode>_ldx"
18311 [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18312 (unspec:BND
18313 [(mem:<bnd_ptr>
18314 (match_par_dup 3
18315 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18316 (match_operand:<bnd_ptr> 2 "register_operand")]))]
18317 UNSPEC_BNDLDX))
18318 (use (mem:BLK (match_dup 1)))])]
18319 "TARGET_MPX"
18320 {
18321 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18322 operands[2]),
18323 UNSPEC_BNDLDX_ADDR);
18324 })
18325
18326 (define_insn "*<mode>_ldx"
18327 [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=B")
18328 (unspec:BND
18329 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18330 [(unspec:<bnd_ptr>
18331 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18332 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18333 UNSPEC_BNDLDX_ADDR)])]
18334 UNSPEC_BNDLDX))
18335 (use (mem:BLK (match_dup 1)))])]
18336 "TARGET_MPX"
18337 "bndldx\t{%3, %0|%0, %3}"
18338 [(set_attr "type" "mpxld")])
18339
18340 (define_expand "<mode>_stx"
18341 [(parallel [(unspec [(mem:<bnd_ptr>
18342 (match_par_dup 3
18343 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18344 (match_operand:<bnd_ptr> 1 "register_operand")]))
18345 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18346 (set (match_dup 4)
18347 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18348 "TARGET_MPX"
18349 {
18350 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18351 operands[1]),
18352 UNSPEC_BNDLDX_ADDR);
18353 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18354 MEM_VOLATILE_P (operands[4]) = 1;
18355 })
18356
18357 (define_insn "*<mode>_stx"
18358 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18359 [(unspec:<bnd_ptr>
18360 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18361 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18362 UNSPEC_BNDLDX_ADDR)])
18363 (match_operand:BND 2 "register_operand" "B")] UNSPEC_BNDSTX)
18364 (set (match_operand:BLK 4 "bnd_mem_operator")
18365 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18366 "TARGET_MPX"
18367 "bndstx\t{%2, %3|%3, %2}"
18368 [(set_attr "type" "mpxst")])
18369
18370 (include "mmx.md")
18371 (include "sse.md")
18372 (include "sync.md")