]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2017 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 UNSPEC_SIZEOF
83
84 ;; Prologue support
85 UNSPEC_STACK_ALLOC
86 UNSPEC_SET_GOT
87 UNSPEC_SET_RIP
88 UNSPEC_SET_GOT_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
90 UNSPEC_STACK_CHECK
91 UNSPEC_PROBE_STACK
92
93 ;; TLS support
94 UNSPEC_TP
95 UNSPEC_TLS_GD
96 UNSPEC_TLS_LD_BASE
97 UNSPEC_TLSDESC
98 UNSPEC_TLS_IE_SUN
99
100 ;; Other random patterns
101 UNSPEC_SCAS
102 UNSPEC_FNSTSW
103 UNSPEC_SAHF
104 UNSPEC_PARITY
105 UNSPEC_FSTCW
106 UNSPEC_FLDCW
107 UNSPEC_REP
108 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_TRUNC_NOOP
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_PAUSE
112 UNSPEC_LEA_ADDR
113 UNSPEC_XBEGIN_ABORT
114 UNSPEC_STOS
115 UNSPEC_PEEPSIB
116 UNSPEC_INSN_FALSE_DEP
117
118 ;; For SSE/MMX support:
119 UNSPEC_FIX_NOTRUNC
120 UNSPEC_MASKMOV
121 UNSPEC_MOVMSK
122 UNSPEC_RCP
123 UNSPEC_RSQRT
124 UNSPEC_PSADBW
125
126 ;; Generic math support
127 UNSPEC_COPYSIGN
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
130
131 ;; x87 Floating point
132 UNSPEC_SIN
133 UNSPEC_COS
134 UNSPEC_FPATAN
135 UNSPEC_FYL2X
136 UNSPEC_FYL2XP1
137 UNSPEC_FRNDINT
138 UNSPEC_FIST
139 UNSPEC_F2XM1
140 UNSPEC_TAN
141 UNSPEC_FXAM
142
143 ;; x87 Rounding
144 UNSPEC_FRNDINT_FLOOR
145 UNSPEC_FRNDINT_CEIL
146 UNSPEC_FRNDINT_TRUNC
147 UNSPEC_FRNDINT_MASK_PM
148 UNSPEC_FIST_FLOOR
149 UNSPEC_FIST_CEIL
150
151 ;; x87 Double output FP
152 UNSPEC_SINCOS_COS
153 UNSPEC_SINCOS_SIN
154 UNSPEC_XTRACT_FRACT
155 UNSPEC_XTRACT_EXP
156 UNSPEC_FSCALE_FRACT
157 UNSPEC_FSCALE_EXP
158 UNSPEC_FPREM_F
159 UNSPEC_FPREM_U
160 UNSPEC_FPREM1_F
161 UNSPEC_FPREM1_U
162
163 UNSPEC_C2_FLAG
164 UNSPEC_FXAM_MEM
165
166 ;; SSP patterns
167 UNSPEC_SP_SET
168 UNSPEC_SP_TEST
169 UNSPEC_SP_TLS_SET
170 UNSPEC_SP_TLS_TEST
171
172 ;; For ROUND support
173 UNSPEC_ROUND
174
175 ;; For CRC32 support
176 UNSPEC_CRC32
177
178 ;; For LZCNT suppoprt
179 UNSPEC_LZCNT
180
181 ;; For BMI support
182 UNSPEC_TZCNT
183 UNSPEC_BEXTR
184
185 ;; For BMI2 support
186 UNSPEC_PDEP
187 UNSPEC_PEXT
188
189 UNSPEC_BNDMK
190 UNSPEC_BNDMK_ADDR
191 UNSPEC_BNDSTX
192 UNSPEC_BNDLDX
193 UNSPEC_BNDLDX_ADDR
194 UNSPEC_BNDCL
195 UNSPEC_BNDCU
196 UNSPEC_BNDCN
197 UNSPEC_MPX_FENCE
198
199 ;; IRET support
200 UNSPEC_INTERRUPT_RETURN
201 ])
202
203 (define_c_enum "unspecv" [
204 UNSPECV_BLOCKAGE
205 UNSPECV_STACK_PROBE
206 UNSPECV_PROBE_STACK_RANGE
207 UNSPECV_ALIGN
208 UNSPECV_PROLOGUE_USE
209 UNSPECV_SPLIT_STACK_RETURN
210 UNSPECV_CLD
211 UNSPECV_NOPS
212 UNSPECV_RDTSC
213 UNSPECV_RDTSCP
214 UNSPECV_RDPMC
215 UNSPECV_LLWP_INTRINSIC
216 UNSPECV_SLWP_INTRINSIC
217 UNSPECV_LWPVAL_INTRINSIC
218 UNSPECV_LWPINS_INTRINSIC
219 UNSPECV_RDFSBASE
220 UNSPECV_RDGSBASE
221 UNSPECV_WRFSBASE
222 UNSPECV_WRGSBASE
223 UNSPECV_FXSAVE
224 UNSPECV_FXRSTOR
225 UNSPECV_FXSAVE64
226 UNSPECV_FXRSTOR64
227 UNSPECV_XSAVE
228 UNSPECV_XRSTOR
229 UNSPECV_XSAVE64
230 UNSPECV_XRSTOR64
231 UNSPECV_XSAVEOPT
232 UNSPECV_XSAVEOPT64
233 UNSPECV_XSAVES
234 UNSPECV_XRSTORS
235 UNSPECV_XSAVES64
236 UNSPECV_XRSTORS64
237 UNSPECV_XSAVEC
238 UNSPECV_XSAVEC64
239
240 ;; For atomic compound assignments.
241 UNSPECV_FNSTENV
242 UNSPECV_FLDENV
243 UNSPECV_FNSTSW
244 UNSPECV_FNCLEX
245
246 ;; For RDRAND support
247 UNSPECV_RDRAND
248
249 ;; For RDSEED support
250 UNSPECV_RDSEED
251
252 ;; For RTM support
253 UNSPECV_XBEGIN
254 UNSPECV_XEND
255 UNSPECV_XABORT
256 UNSPECV_XTEST
257
258 UNSPECV_NLGR
259
260 ;; For CLWB support
261 UNSPECV_CLWB
262
263 ;; For CLFLUSHOPT support
264 UNSPECV_CLFLUSHOPT
265
266 ;; For MONITORX and MWAITX support
267 UNSPECV_MONITORX
268 UNSPECV_MWAITX
269
270 ;; For CLZERO support
271 UNSPECV_CLZERO
272
273 ;; For RDPKRU and WRPKRU support
274 UNSPECV_PKU
275 ])
276
277 ;; Constants to represent rounding modes in the ROUND instruction
278 (define_constants
279 [(ROUND_FLOOR 0x1)
280 (ROUND_CEIL 0x2)
281 (ROUND_TRUNC 0x3)
282 (ROUND_MXCSR 0x4)
283 (ROUND_NO_EXC 0x8)
284 ])
285
286 ;; Constants to represent AVX512F embeded rounding
287 (define_constants
288 [(ROUND_NEAREST_INT 0)
289 (ROUND_NEG_INF 1)
290 (ROUND_POS_INF 2)
291 (ROUND_ZERO 3)
292 (NO_ROUND 4)
293 (ROUND_SAE 8)
294 ])
295
296 ;; Constants to represent pcomtrue/pcomfalse variants
297 (define_constants
298 [(PCOM_FALSE 0)
299 (PCOM_TRUE 1)
300 (COM_FALSE_S 2)
301 (COM_FALSE_P 3)
302 (COM_TRUE_S 4)
303 (COM_TRUE_P 5)
304 ])
305
306 ;; Constants used in the XOP pperm instruction
307 (define_constants
308 [(PPERM_SRC 0x00) /* copy source */
309 (PPERM_INVERT 0x20) /* invert source */
310 (PPERM_REVERSE 0x40) /* bit reverse source */
311 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
312 (PPERM_ZERO 0x80) /* all 0's */
313 (PPERM_ONES 0xa0) /* all 1's */
314 (PPERM_SIGN 0xc0) /* propagate sign bit */
315 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
316 (PPERM_SRC1 0x00) /* use first source byte */
317 (PPERM_SRC2 0x10) /* use second source byte */
318 ])
319
320 ;; Registers by name.
321 (define_constants
322 [(AX_REG 0)
323 (DX_REG 1)
324 (CX_REG 2)
325 (BX_REG 3)
326 (SI_REG 4)
327 (DI_REG 5)
328 (BP_REG 6)
329 (SP_REG 7)
330 (ST0_REG 8)
331 (ST1_REG 9)
332 (ST2_REG 10)
333 (ST3_REG 11)
334 (ST4_REG 12)
335 (ST5_REG 13)
336 (ST6_REG 14)
337 (ST7_REG 15)
338 (ARGP_REG 16)
339 (FLAGS_REG 17)
340 (FPSR_REG 18)
341 (FPCR_REG 19)
342 (FRAME_REG 20)
343 (XMM0_REG 21)
344 (XMM1_REG 22)
345 (XMM2_REG 23)
346 (XMM3_REG 24)
347 (XMM4_REG 25)
348 (XMM5_REG 26)
349 (XMM6_REG 27)
350 (XMM7_REG 28)
351 (MM0_REG 29)
352 (MM1_REG 30)
353 (MM2_REG 31)
354 (MM3_REG 32)
355 (MM4_REG 33)
356 (MM5_REG 34)
357 (MM6_REG 35)
358 (MM7_REG 36)
359 (R8_REG 37)
360 (R9_REG 38)
361 (R10_REG 39)
362 (R11_REG 40)
363 (R12_REG 41)
364 (R13_REG 42)
365 (R14_REG 43)
366 (R15_REG 44)
367 (XMM8_REG 45)
368 (XMM9_REG 46)
369 (XMM10_REG 47)
370 (XMM11_REG 48)
371 (XMM12_REG 49)
372 (XMM13_REG 50)
373 (XMM14_REG 51)
374 (XMM15_REG 52)
375 (XMM16_REG 53)
376 (XMM17_REG 54)
377 (XMM18_REG 55)
378 (XMM19_REG 56)
379 (XMM20_REG 57)
380 (XMM21_REG 58)
381 (XMM22_REG 59)
382 (XMM23_REG 60)
383 (XMM24_REG 61)
384 (XMM25_REG 62)
385 (XMM26_REG 63)
386 (XMM27_REG 64)
387 (XMM28_REG 65)
388 (XMM29_REG 66)
389 (XMM30_REG 67)
390 (XMM31_REG 68)
391 (MASK0_REG 69)
392 (MASK1_REG 70)
393 (MASK2_REG 71)
394 (MASK3_REG 72)
395 (MASK4_REG 73)
396 (MASK5_REG 74)
397 (MASK6_REG 75)
398 (MASK7_REG 76)
399 (BND0_REG 77)
400 (BND1_REG 78)
401 (BND2_REG 79)
402 (BND3_REG 80)
403 (FIRST_PSEUDO_REG 81)
404 ])
405
406 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
407 ;; from i386.c.
408
409 ;; In C guard expressions, put expressions which may be compile-time
410 ;; constants first. This allows for better optimization. For
411 ;; example, write "TARGET_64BIT && reload_completed", not
412 ;; "reload_completed && TARGET_64BIT".
413
414 \f
415 ;; Processor type.
416 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
417 atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
418 bdver4,btver2,znver1"
419 (const (symbol_ref "ix86_schedule")))
420
421 ;; A basic instruction type. Refinements due to arguments to be
422 ;; provided in other attributes.
423 (define_attr "type"
424 "other,multi,
425 alu,alu1,negnot,imov,imovx,lea,
426 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
427 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
428 push,pop,call,callv,leave,
429 str,bitmanip,
430 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
431 fxch,fistp,fisttp,frndint,
432 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
433 ssemul,sseimul,ssediv,sselog,sselog1,
434 sseishft,sseishft1,ssecmp,ssecomi,
435 ssecvt,ssecvt1,sseicvt,sseins,
436 sseshuf,sseshuf1,ssemuladd,sse4arg,
437 lwp,mskmov,msklog,
438 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
439 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
440 (const_string "other"))
441
442 ;; Main data type used by the insn
443 (define_attr "mode"
444 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
445 V2DF,V2SF,V1DF,V8DF"
446 (const_string "unknown"))
447
448 ;; The CPU unit operations uses.
449 (define_attr "unit" "integer,i387,sse,mmx,unknown"
450 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
451 fxch,fistp,fisttp,frndint")
452 (const_string "i387")
453 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
454 ssemul,sseimul,ssediv,sselog,sselog1,
455 sseishft,sseishft1,ssecmp,ssecomi,
456 ssecvt,ssecvt1,sseicvt,sseins,
457 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
458 (const_string "sse")
459 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
460 (const_string "mmx")
461 (eq_attr "type" "other")
462 (const_string "unknown")]
463 (const_string "integer")))
464
465 ;; The (bounding maximum) length of an instruction immediate.
466 (define_attr "length_immediate" ""
467 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
468 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
469 mpxld,mpxst")
470 (const_int 0)
471 (eq_attr "unit" "i387,sse,mmx")
472 (const_int 0)
473 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
474 rotate,rotatex,rotate1,imul,icmp,push,pop")
475 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
476 (eq_attr "type" "imov,test")
477 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
478 (eq_attr "type" "call")
479 (if_then_else (match_operand 0 "constant_call_address_operand")
480 (const_int 4)
481 (const_int 0))
482 (eq_attr "type" "callv")
483 (if_then_else (match_operand 1 "constant_call_address_operand")
484 (const_int 4)
485 (const_int 0))
486 ;; We don't know the size before shorten_branches. Expect
487 ;; the instruction to fit for better scheduling.
488 (eq_attr "type" "ibr")
489 (const_int 1)
490 ]
491 (symbol_ref "/* Update immediate_length and other attributes! */
492 gcc_unreachable (),1")))
493
494 ;; The (bounding maximum) length of an instruction address.
495 (define_attr "length_address" ""
496 (cond [(eq_attr "type" "str,other,multi,fxch")
497 (const_int 0)
498 (and (eq_attr "type" "call")
499 (match_operand 0 "constant_call_address_operand"))
500 (const_int 0)
501 (and (eq_attr "type" "callv")
502 (match_operand 1 "constant_call_address_operand"))
503 (const_int 0)
504 ]
505 (symbol_ref "ix86_attr_length_address_default (insn)")))
506
507 ;; Set when length prefix is used.
508 (define_attr "prefix_data16" ""
509 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
510 (const_int 0)
511 (eq_attr "mode" "HI")
512 (const_int 1)
513 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
514 (const_int 1)
515 ]
516 (const_int 0)))
517
518 ;; Set when string REP prefix is used.
519 (define_attr "prefix_rep" ""
520 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
521 (const_int 0)
522 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
523 (const_int 1)
524 (and (eq_attr "type" "ibr,call,callv")
525 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
526 (const_int 1)
527 ]
528 (const_int 0)))
529
530 ;; Set when 0f opcode prefix is used.
531 (define_attr "prefix_0f" ""
532 (if_then_else
533 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
534 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
535 (eq_attr "unit" "sse,mmx"))
536 (const_int 1)
537 (const_int 0)))
538
539 ;; Set when REX opcode prefix is used.
540 (define_attr "prefix_rex" ""
541 (cond [(not (match_test "TARGET_64BIT"))
542 (const_int 0)
543 (and (eq_attr "mode" "DI")
544 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
545 (eq_attr "unit" "!mmx")))
546 (const_int 1)
547 (and (eq_attr "mode" "QI")
548 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
549 (const_int 1)
550 (match_test "x86_extended_reg_mentioned_p (insn)")
551 (const_int 1)
552 (and (eq_attr "type" "imovx")
553 (match_operand:QI 1 "ext_QIreg_operand"))
554 (const_int 1)
555 ]
556 (const_int 0)))
557
558 ;; There are also additional prefixes in 3DNOW, SSSE3.
559 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
560 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
561 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
562 (define_attr "prefix_extra" ""
563 (cond [(eq_attr "type" "ssemuladd,sse4arg")
564 (const_int 2)
565 (eq_attr "type" "sseiadd1,ssecvt1")
566 (const_int 1)
567 ]
568 (const_int 0)))
569
570 ;; Set when BND opcode prefix may be used.
571 (define_attr "maybe_prefix_bnd" "" (const_int 0))
572
573 ;; Prefix used: original, VEX or maybe VEX.
574 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
575 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
576 (const_string "vex")
577 (eq_attr "mode" "XI,V16SF,V8DF")
578 (const_string "evex")
579 ]
580 (const_string "orig")))
581
582 ;; VEX W bit is used.
583 (define_attr "prefix_vex_w" "" (const_int 0))
584
585 ;; The length of VEX prefix
586 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
587 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
588 ;; still prefix_0f 1, with prefix_extra 1.
589 (define_attr "length_vex" ""
590 (if_then_else (and (eq_attr "prefix_0f" "1")
591 (eq_attr "prefix_extra" "0"))
592 (if_then_else (eq_attr "prefix_vex_w" "1")
593 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
594 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
595 (if_then_else (eq_attr "prefix_vex_w" "1")
596 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
597 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
598
599 ;; 4-bytes evex prefix and 1 byte opcode.
600 (define_attr "length_evex" "" (const_int 5))
601
602 ;; Set when modrm byte is used.
603 (define_attr "modrm" ""
604 (cond [(eq_attr "type" "str,leave")
605 (const_int 0)
606 (eq_attr "unit" "i387")
607 (const_int 0)
608 (and (eq_attr "type" "incdec")
609 (and (not (match_test "TARGET_64BIT"))
610 (ior (match_operand:SI 1 "register_operand")
611 (match_operand:HI 1 "register_operand"))))
612 (const_int 0)
613 (and (eq_attr "type" "push")
614 (not (match_operand 1 "memory_operand")))
615 (const_int 0)
616 (and (eq_attr "type" "pop")
617 (not (match_operand 0 "memory_operand")))
618 (const_int 0)
619 (and (eq_attr "type" "imov")
620 (and (not (eq_attr "mode" "DI"))
621 (ior (and (match_operand 0 "register_operand")
622 (match_operand 1 "immediate_operand"))
623 (ior (and (match_operand 0 "ax_reg_operand")
624 (match_operand 1 "memory_displacement_only_operand"))
625 (and (match_operand 0 "memory_displacement_only_operand")
626 (match_operand 1 "ax_reg_operand"))))))
627 (const_int 0)
628 (and (eq_attr "type" "call")
629 (match_operand 0 "constant_call_address_operand"))
630 (const_int 0)
631 (and (eq_attr "type" "callv")
632 (match_operand 1 "constant_call_address_operand"))
633 (const_int 0)
634 (and (eq_attr "type" "alu,alu1,icmp,test")
635 (match_operand 0 "ax_reg_operand"))
636 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
637 ]
638 (const_int 1)))
639
640 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
641 (cond [(eq_attr "modrm" "0")
642 (const_string "none")
643 (eq_attr "type" "alu,imul,ishift")
644 (const_string "op02")
645 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
646 (const_string "op01")
647 (eq_attr "type" "incdec")
648 (const_string "incdec")
649 (eq_attr "type" "push,pop")
650 (const_string "pushpop")]
651 (const_string "unknown")))
652
653 ;; The (bounding maximum) length of an instruction in bytes.
654 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
655 ;; Later we may want to split them and compute proper length as for
656 ;; other insns.
657 (define_attr "length" ""
658 (cond [(eq_attr "type" "other,multi,fistp,frndint")
659 (const_int 16)
660 (eq_attr "type" "fcmp")
661 (const_int 4)
662 (eq_attr "unit" "i387")
663 (plus (const_int 2)
664 (plus (attr "prefix_data16")
665 (attr "length_address")))
666 (ior (eq_attr "prefix" "evex")
667 (and (ior (eq_attr "prefix" "maybe_evex")
668 (eq_attr "prefix" "maybe_vex"))
669 (match_test "TARGET_AVX512F")))
670 (plus (attr "length_evex")
671 (plus (attr "length_immediate")
672 (plus (attr "modrm")
673 (attr "length_address"))))
674 (ior (eq_attr "prefix" "vex")
675 (and (ior (eq_attr "prefix" "maybe_vex")
676 (eq_attr "prefix" "maybe_evex"))
677 (match_test "TARGET_AVX")))
678 (plus (attr "length_vex")
679 (plus (attr "length_immediate")
680 (plus (attr "modrm")
681 (attr "length_address"))))]
682 (plus (plus (attr "modrm")
683 (plus (attr "prefix_0f")
684 (plus (attr "prefix_rex")
685 (plus (attr "prefix_extra")
686 (const_int 1)))))
687 (plus (attr "prefix_rep")
688 (plus (attr "prefix_data16")
689 (plus (attr "length_immediate")
690 (attr "length_address")))))))
691
692 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
693 ;; `store' if there is a simple memory reference therein, or `unknown'
694 ;; if the instruction is complex.
695
696 (define_attr "memory" "none,load,store,both,unknown"
697 (cond [(eq_attr "type" "other,multi,str,lwp")
698 (const_string "unknown")
699 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
700 (const_string "none")
701 (eq_attr "type" "fistp,leave")
702 (const_string "both")
703 (eq_attr "type" "frndint")
704 (const_string "load")
705 (eq_attr "type" "mpxld")
706 (const_string "load")
707 (eq_attr "type" "mpxst")
708 (const_string "store")
709 (eq_attr "type" "push")
710 (if_then_else (match_operand 1 "memory_operand")
711 (const_string "both")
712 (const_string "store"))
713 (eq_attr "type" "pop")
714 (if_then_else (match_operand 0 "memory_operand")
715 (const_string "both")
716 (const_string "load"))
717 (eq_attr "type" "setcc")
718 (if_then_else (match_operand 0 "memory_operand")
719 (const_string "store")
720 (const_string "none"))
721 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
722 (if_then_else (ior (match_operand 0 "memory_operand")
723 (match_operand 1 "memory_operand"))
724 (const_string "load")
725 (const_string "none"))
726 (eq_attr "type" "ibr")
727 (if_then_else (match_operand 0 "memory_operand")
728 (const_string "load")
729 (const_string "none"))
730 (eq_attr "type" "call")
731 (if_then_else (match_operand 0 "constant_call_address_operand")
732 (const_string "none")
733 (const_string "load"))
734 (eq_attr "type" "callv")
735 (if_then_else (match_operand 1 "constant_call_address_operand")
736 (const_string "none")
737 (const_string "load"))
738 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
739 (match_operand 1 "memory_operand"))
740 (const_string "both")
741 (and (match_operand 0 "memory_operand")
742 (match_operand 1 "memory_operand"))
743 (const_string "both")
744 (match_operand 0 "memory_operand")
745 (const_string "store")
746 (match_operand 1 "memory_operand")
747 (const_string "load")
748 (and (eq_attr "type"
749 "!alu1,negnot,ishift1,
750 imov,imovx,icmp,test,bitmanip,
751 fmov,fcmp,fsgn,
752 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
753 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
754 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
755 (match_operand 2 "memory_operand"))
756 (const_string "load")
757 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
758 (match_operand 3 "memory_operand"))
759 (const_string "load")
760 ]
761 (const_string "none")))
762
763 ;; Indicates if an instruction has both an immediate and a displacement.
764
765 (define_attr "imm_disp" "false,true,unknown"
766 (cond [(eq_attr "type" "other,multi")
767 (const_string "unknown")
768 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
769 (and (match_operand 0 "memory_displacement_operand")
770 (match_operand 1 "immediate_operand")))
771 (const_string "true")
772 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
773 (and (match_operand 0 "memory_displacement_operand")
774 (match_operand 2 "immediate_operand")))
775 (const_string "true")
776 ]
777 (const_string "false")))
778
779 ;; Indicates if an FP operation has an integer source.
780
781 (define_attr "fp_int_src" "false,true"
782 (const_string "false"))
783
784 ;; Defines rounding mode of an FP operation.
785
786 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
787 (const_string "any"))
788
789 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
790 (define_attr "use_carry" "0,1" (const_string "0"))
791
792 ;; Define attribute to indicate unaligned ssemov insns
793 (define_attr "movu" "0,1" (const_string "0"))
794
795 ;; Used to control the "enabled" attribute on a per-instruction basis.
796 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
797 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
798 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
799 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
800 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
801 (const_string "base"))
802
803 (define_attr "enabled" ""
804 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
805 (eq_attr "isa" "x64_sse4")
806 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
807 (eq_attr "isa" "x64_sse4_noavx")
808 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
809 (eq_attr "isa" "x64_avx")
810 (symbol_ref "TARGET_64BIT && TARGET_AVX")
811 (eq_attr "isa" "x64_avx512dq")
812 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
813 (eq_attr "isa" "x64_avx512bw")
814 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
815 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
816 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
817 (eq_attr "isa" "sse2_noavx")
818 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
819 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
820 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
821 (eq_attr "isa" "sse4_noavx")
822 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
823 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
824 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
825 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
826 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
827 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
828 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
829 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
830 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
831 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
832 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
833 (eq_attr "isa" "fma_avx512f")
834 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
835 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
836 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
837 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
838 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
839 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
840 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
841 ]
842 (const_int 1)))
843
844 (define_attr "preferred_for_size" "" (const_int 1))
845 (define_attr "preferred_for_speed" "" (const_int 1))
846
847 ;; Describe a user's asm statement.
848 (define_asm_attributes
849 [(set_attr "length" "128")
850 (set_attr "type" "multi")])
851
852 (define_code_iterator plusminus [plus minus])
853
854 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
855
856 (define_code_iterator multdiv [mult div])
857
858 ;; Base name for define_insn
859 (define_code_attr plusminus_insn
860 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
861 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
862
863 ;; Base name for insn mnemonic.
864 (define_code_attr plusminus_mnemonic
865 [(plus "add") (ss_plus "adds") (us_plus "addus")
866 (minus "sub") (ss_minus "subs") (us_minus "subus")])
867 (define_code_attr multdiv_mnemonic
868 [(mult "mul") (div "div")])
869
870 ;; Mark commutative operators as such in constraints.
871 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
872 (minus "") (ss_minus "") (us_minus "")])
873
874 ;; Mapping of max and min
875 (define_code_iterator maxmin [smax smin umax umin])
876
877 ;; Mapping of signed max and min
878 (define_code_iterator smaxmin [smax smin])
879
880 ;; Mapping of unsigned max and min
881 (define_code_iterator umaxmin [umax umin])
882
883 ;; Base name for integer and FP insn mnemonic
884 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
885 (umax "maxu") (umin "minu")])
886 (define_code_attr maxmin_float [(smax "max") (smin "min")])
887
888 (define_int_iterator IEEE_MAXMIN
889 [UNSPEC_IEEE_MAX
890 UNSPEC_IEEE_MIN])
891
892 (define_int_attr ieee_maxmin
893 [(UNSPEC_IEEE_MAX "max")
894 (UNSPEC_IEEE_MIN "min")])
895
896 ;; Mapping of logic operators
897 (define_code_iterator any_logic [and ior xor])
898 (define_code_iterator any_or [ior xor])
899 (define_code_iterator fpint_logic [and xor])
900
901 ;; Base name for insn mnemonic.
902 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
903
904 ;; Mapping of logic-shift operators
905 (define_code_iterator any_lshift [ashift lshiftrt])
906
907 ;; Mapping of shift-right operators
908 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
909
910 ;; Mapping of all shift operators
911 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
912
913 ;; Base name for define_insn
914 (define_code_attr shift_insn
915 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
916
917 ;; Base name for insn mnemonic.
918 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
919 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
920
921 ;; Mapping of rotate operators
922 (define_code_iterator any_rotate [rotate rotatert])
923
924 ;; Base name for define_insn
925 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
926
927 ;; Base name for insn mnemonic.
928 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
929
930 ;; Mapping of abs neg operators
931 (define_code_iterator absneg [abs neg])
932
933 ;; Base name for x87 insn mnemonic.
934 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
935
936 ;; Used in signed and unsigned widening multiplications.
937 (define_code_iterator any_extend [sign_extend zero_extend])
938
939 ;; Prefix for insn menmonic.
940 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
941
942 ;; Prefix for define_insn
943 (define_code_attr u [(sign_extend "") (zero_extend "u")])
944 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
945 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
946
947 ;; Used in signed and unsigned truncations.
948 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
949 ;; Instruction suffix for truncations.
950 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
951
952 ;; Used in signed and unsigned fix.
953 (define_code_iterator any_fix [fix unsigned_fix])
954 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
955
956 ;; Used in signed and unsigned float.
957 (define_code_iterator any_float [float unsigned_float])
958 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
959
960 ;; All integer modes.
961 (define_mode_iterator SWI1248x [QI HI SI DI])
962
963 ;; All integer modes without QImode.
964 (define_mode_iterator SWI248x [HI SI DI])
965
966 ;; All integer modes without QImode and HImode.
967 (define_mode_iterator SWI48x [SI DI])
968
969 ;; All integer modes without SImode and DImode.
970 (define_mode_iterator SWI12 [QI HI])
971
972 ;; All integer modes without DImode.
973 (define_mode_iterator SWI124 [QI HI SI])
974
975 ;; All integer modes without QImode and DImode.
976 (define_mode_iterator SWI24 [HI SI])
977
978 ;; Single word integer modes.
979 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
980
981 ;; Single word integer modes without QImode.
982 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
983
984 ;; Single word integer modes without QImode and HImode.
985 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
986
987 ;; All math-dependant single and double word integer modes.
988 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
989 (HI "TARGET_HIMODE_MATH")
990 SI DI (TI "TARGET_64BIT")])
991
992 ;; Math-dependant single word integer modes.
993 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
994 (HI "TARGET_HIMODE_MATH")
995 SI (DI "TARGET_64BIT")])
996
997 ;; Math-dependant integer modes without DImode.
998 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
999 (HI "TARGET_HIMODE_MATH")
1000 SI])
1001
1002 ;; Math-dependant integer modes with DImode.
1003 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1004 (HI "TARGET_HIMODE_MATH")
1005 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1006
1007 ;; Math-dependant single word integer modes without QImode.
1008 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1009 SI (DI "TARGET_64BIT")])
1010
1011 ;; Double word integer modes.
1012 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1013 (TI "TARGET_64BIT")])
1014
1015 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1016 ;; compile time constant, it is faster to use <MODE_SIZE> than
1017 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1018 ;; command line options just use GET_MODE_SIZE macro.
1019 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1020 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1021 (V16QI "16") (V32QI "32") (V64QI "64")
1022 (V8HI "16") (V16HI "32") (V32HI "64")
1023 (V4SI "16") (V8SI "32") (V16SI "64")
1024 (V2DI "16") (V4DI "32") (V8DI "64")
1025 (V1TI "16") (V2TI "32") (V4TI "64")
1026 (V2DF "16") (V4DF "32") (V8DF "64")
1027 (V4SF "16") (V8SF "32") (V16SF "64")])
1028
1029 ;; Double word integer modes as mode attribute.
1030 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1031 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1032
1033 ;; LEA mode corresponding to an integer mode
1034 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1035
1036 ;; Half mode for double word integer modes.
1037 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1038 (DI "TARGET_64BIT")])
1039
1040 ;; Bound modes.
1041 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1042 (BND64 "TARGET_LP64")])
1043
1044 ;; Pointer mode corresponding to bound mode.
1045 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1046
1047 ;; MPX check types
1048 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1049
1050 ;; Check name
1051 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1052 (UNSPEC_BNDCU "cu")
1053 (UNSPEC_BNDCN "cn")])
1054
1055 ;; Instruction suffix for integer modes.
1056 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1057
1058 ;; Instruction suffix for masks.
1059 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1060
1061 ;; Pointer size prefix for integer modes (Intel asm dialect)
1062 (define_mode_attr iptrsize [(QI "BYTE")
1063 (HI "WORD")
1064 (SI "DWORD")
1065 (DI "QWORD")])
1066
1067 ;; Register class for integer modes.
1068 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1069
1070 ;; Immediate operand constraint for integer modes.
1071 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1072
1073 ;; General operand constraint for word modes.
1074 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1075
1076 ;; Immediate operand constraint for double integer modes.
1077 (define_mode_attr di [(SI "nF") (DI "Wd")])
1078
1079 ;; Immediate operand constraint for shifts.
1080 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1081
1082 ;; General operand predicate for integer modes.
1083 (define_mode_attr general_operand
1084 [(QI "general_operand")
1085 (HI "general_operand")
1086 (SI "x86_64_general_operand")
1087 (DI "x86_64_general_operand")
1088 (TI "x86_64_general_operand")])
1089
1090 ;; General operand predicate for integer modes, where for TImode
1091 ;; we need both words of the operand to be general operands.
1092 (define_mode_attr general_hilo_operand
1093 [(QI "general_operand")
1094 (HI "general_operand")
1095 (SI "x86_64_general_operand")
1096 (DI "x86_64_general_operand")
1097 (TI "x86_64_hilo_general_operand")])
1098
1099 ;; General sign extend operand predicate for integer modes,
1100 ;; which disallows VOIDmode operands and thus it is suitable
1101 ;; for use inside sign_extend.
1102 (define_mode_attr general_sext_operand
1103 [(QI "sext_operand")
1104 (HI "sext_operand")
1105 (SI "x86_64_sext_operand")
1106 (DI "x86_64_sext_operand")])
1107
1108 ;; General sign/zero extend operand predicate for integer modes.
1109 (define_mode_attr general_szext_operand
1110 [(QI "general_operand")
1111 (HI "general_operand")
1112 (SI "x86_64_szext_general_operand")
1113 (DI "x86_64_szext_general_operand")])
1114
1115 ;; Immediate operand predicate for integer modes.
1116 (define_mode_attr immediate_operand
1117 [(QI "immediate_operand")
1118 (HI "immediate_operand")
1119 (SI "x86_64_immediate_operand")
1120 (DI "x86_64_immediate_operand")])
1121
1122 ;; Nonmemory operand predicate for integer modes.
1123 (define_mode_attr nonmemory_operand
1124 [(QI "nonmemory_operand")
1125 (HI "nonmemory_operand")
1126 (SI "x86_64_nonmemory_operand")
1127 (DI "x86_64_nonmemory_operand")])
1128
1129 ;; Operand predicate for shifts.
1130 (define_mode_attr shift_operand
1131 [(QI "nonimmediate_operand")
1132 (HI "nonimmediate_operand")
1133 (SI "nonimmediate_operand")
1134 (DI "shiftdi_operand")
1135 (TI "register_operand")])
1136
1137 ;; Operand predicate for shift argument.
1138 (define_mode_attr shift_immediate_operand
1139 [(QI "const_1_to_31_operand")
1140 (HI "const_1_to_31_operand")
1141 (SI "const_1_to_31_operand")
1142 (DI "const_1_to_63_operand")])
1143
1144 ;; Input operand predicate for arithmetic left shifts.
1145 (define_mode_attr ashl_input_operand
1146 [(QI "nonimmediate_operand")
1147 (HI "nonimmediate_operand")
1148 (SI "nonimmediate_operand")
1149 (DI "ashldi_input_operand")
1150 (TI "reg_or_pm1_operand")])
1151
1152 ;; SSE and x87 SFmode and DFmode floating point modes
1153 (define_mode_iterator MODEF [SF DF])
1154
1155 ;; All x87 floating point modes
1156 (define_mode_iterator X87MODEF [SF DF XF])
1157
1158 ;; SSE instruction suffix for various modes
1159 (define_mode_attr ssemodesuffix
1160 [(SF "ss") (DF "sd")
1161 (V16SF "ps") (V8DF "pd")
1162 (V8SF "ps") (V4DF "pd")
1163 (V4SF "ps") (V2DF "pd")
1164 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1165 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1166 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1167
1168 ;; SSE vector suffix for floating point modes
1169 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1170
1171 ;; SSE vector mode corresponding to a scalar mode
1172 (define_mode_attr ssevecmode
1173 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1174 (define_mode_attr ssevecmodelower
1175 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1176
1177 ;; AVX512F vector mode corresponding to a scalar mode
1178 (define_mode_attr avx512fvecmode
1179 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1180
1181 ;; Instruction suffix for REX 64bit operators.
1182 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1183
1184 ;; This mode iterator allows :P to be used for patterns that operate on
1185 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1186 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1187
1188 ;; This mode iterator allows :W to be used for patterns that operate on
1189 ;; word_mode sized quantities.
1190 (define_mode_iterator W
1191 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1192
1193 ;; This mode iterator allows :PTR to be used for patterns that operate on
1194 ;; ptr_mode sized quantities.
1195 (define_mode_iterator PTR
1196 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1197 \f
1198 ;; Scheduling descriptions
1199
1200 (include "pentium.md")
1201 (include "ppro.md")
1202 (include "k6.md")
1203 (include "athlon.md")
1204 (include "bdver1.md")
1205 (include "bdver3.md")
1206 (include "btver2.md")
1207 (include "znver1.md")
1208 (include "geode.md")
1209 (include "atom.md")
1210 (include "slm.md")
1211 (include "core2.md")
1212 (include "haswell.md")
1213
1214 \f
1215 ;; Operand and operator predicates and constraints
1216
1217 (include "predicates.md")
1218 (include "constraints.md")
1219
1220 \f
1221 ;; Compare and branch/compare and store instructions.
1222
1223 (define_expand "cbranch<mode>4"
1224 [(set (reg:CC FLAGS_REG)
1225 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1226 (match_operand:SDWIM 2 "<general_operand>")))
1227 (set (pc) (if_then_else
1228 (match_operator 0 "ordered_comparison_operator"
1229 [(reg:CC FLAGS_REG) (const_int 0)])
1230 (label_ref (match_operand 3))
1231 (pc)))]
1232 ""
1233 {
1234 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1235 operands[1] = force_reg (<MODE>mode, operands[1]);
1236 ix86_expand_branch (GET_CODE (operands[0]),
1237 operands[1], operands[2], operands[3]);
1238 DONE;
1239 })
1240
1241 (define_expand "cstore<mode>4"
1242 [(set (reg:CC FLAGS_REG)
1243 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1244 (match_operand:SWIM 3 "<general_operand>")))
1245 (set (match_operand:QI 0 "register_operand")
1246 (match_operator 1 "ordered_comparison_operator"
1247 [(reg:CC FLAGS_REG) (const_int 0)]))]
1248 ""
1249 {
1250 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1251 operands[2] = force_reg (<MODE>mode, operands[2]);
1252 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1253 operands[2], operands[3]);
1254 DONE;
1255 })
1256
1257 (define_expand "cmp<mode>_1"
1258 [(set (reg:CC FLAGS_REG)
1259 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1260 (match_operand:SWI48 1 "<general_operand>")))])
1261
1262 (define_insn "*cmp<mode>_ccno_1"
1263 [(set (reg FLAGS_REG)
1264 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1265 (match_operand:SWI 1 "const0_operand")))]
1266 "ix86_match_ccmode (insn, CCNOmode)"
1267 "@
1268 test{<imodesuffix>}\t%0, %0
1269 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1270 [(set_attr "type" "test,icmp")
1271 (set_attr "length_immediate" "0,1")
1272 (set_attr "modrm_class" "op0,unknown")
1273 (set_attr "mode" "<MODE>")])
1274
1275 (define_insn "*cmp<mode>_1"
1276 [(set (reg FLAGS_REG)
1277 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1278 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1279 "ix86_match_ccmode (insn, CCmode)"
1280 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1281 [(set_attr "type" "icmp")
1282 (set_attr "mode" "<MODE>")])
1283
1284 (define_insn "*cmp<mode>_minus_1"
1285 [(set (reg FLAGS_REG)
1286 (compare
1287 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1288 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1289 (const_int 0)))]
1290 "ix86_match_ccmode (insn, CCGOCmode)"
1291 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1292 [(set_attr "type" "icmp")
1293 (set_attr "mode" "<MODE>")])
1294
1295 (define_insn "*cmpqi_ext_1"
1296 [(set (reg FLAGS_REG)
1297 (compare
1298 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1299 (subreg:QI
1300 (zero_extract:SI
1301 (match_operand 1 "ext_register_operand" "Q,Q")
1302 (const_int 8)
1303 (const_int 8)) 0)))]
1304 "ix86_match_ccmode (insn, CCmode)"
1305 "cmp{b}\t{%h1, %0|%0, %h1}"
1306 [(set_attr "isa" "*,nox64")
1307 (set_attr "type" "icmp")
1308 (set_attr "mode" "QI")])
1309
1310 (define_insn "*cmpqi_ext_2"
1311 [(set (reg FLAGS_REG)
1312 (compare
1313 (subreg:QI
1314 (zero_extract:SI
1315 (match_operand 0 "ext_register_operand" "Q")
1316 (const_int 8)
1317 (const_int 8)) 0)
1318 (match_operand:QI 1 "const0_operand")))]
1319 "ix86_match_ccmode (insn, CCNOmode)"
1320 "test{b}\t%h0, %h0"
1321 [(set_attr "type" "test")
1322 (set_attr "length_immediate" "0")
1323 (set_attr "mode" "QI")])
1324
1325 (define_expand "cmpqi_ext_3"
1326 [(set (reg:CC FLAGS_REG)
1327 (compare:CC
1328 (subreg:QI
1329 (zero_extract:SI
1330 (match_operand 0 "ext_register_operand")
1331 (const_int 8)
1332 (const_int 8)) 0)
1333 (match_operand:QI 1 "const_int_operand")))])
1334
1335 (define_insn "*cmpqi_ext_3"
1336 [(set (reg FLAGS_REG)
1337 (compare
1338 (subreg:QI
1339 (zero_extract:SI
1340 (match_operand 0 "ext_register_operand" "Q,Q")
1341 (const_int 8)
1342 (const_int 8)) 0)
1343 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1344 "ix86_match_ccmode (insn, CCmode)"
1345 "cmp{b}\t{%1, %h0|%h0, %1}"
1346 [(set_attr "isa" "*,nox64")
1347 (set_attr "type" "icmp")
1348 (set_attr "mode" "QI")])
1349
1350 (define_insn "*cmpqi_ext_4"
1351 [(set (reg FLAGS_REG)
1352 (compare
1353 (subreg:QI
1354 (zero_extract:SI
1355 (match_operand 0 "ext_register_operand" "Q")
1356 (const_int 8)
1357 (const_int 8)) 0)
1358 (subreg:QI
1359 (zero_extract:SI
1360 (match_operand 1 "ext_register_operand" "Q")
1361 (const_int 8)
1362 (const_int 8)) 0)))]
1363 "ix86_match_ccmode (insn, CCmode)"
1364 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1365 [(set_attr "type" "icmp")
1366 (set_attr "mode" "QI")])
1367
1368 ;; These implement float point compares.
1369 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1370 ;; which would allow mix and match FP modes on the compares. Which is what
1371 ;; the old patterns did, but with many more of them.
1372
1373 (define_expand "cbranchxf4"
1374 [(set (reg:CC FLAGS_REG)
1375 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1376 (match_operand:XF 2 "nonmemory_operand")))
1377 (set (pc) (if_then_else
1378 (match_operator 0 "ix86_fp_comparison_operator"
1379 [(reg:CC FLAGS_REG)
1380 (const_int 0)])
1381 (label_ref (match_operand 3))
1382 (pc)))]
1383 "TARGET_80387"
1384 {
1385 ix86_expand_branch (GET_CODE (operands[0]),
1386 operands[1], operands[2], operands[3]);
1387 DONE;
1388 })
1389
1390 (define_expand "cstorexf4"
1391 [(set (reg:CC FLAGS_REG)
1392 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1393 (match_operand:XF 3 "nonmemory_operand")))
1394 (set (match_operand:QI 0 "register_operand")
1395 (match_operator 1 "ix86_fp_comparison_operator"
1396 [(reg:CC FLAGS_REG)
1397 (const_int 0)]))]
1398 "TARGET_80387"
1399 {
1400 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1401 operands[2], operands[3]);
1402 DONE;
1403 })
1404
1405 (define_expand "cbranch<mode>4"
1406 [(set (reg:CC FLAGS_REG)
1407 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1408 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1409 (set (pc) (if_then_else
1410 (match_operator 0 "ix86_fp_comparison_operator"
1411 [(reg:CC FLAGS_REG)
1412 (const_int 0)])
1413 (label_ref (match_operand 3))
1414 (pc)))]
1415 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1416 {
1417 ix86_expand_branch (GET_CODE (operands[0]),
1418 operands[1], operands[2], operands[3]);
1419 DONE;
1420 })
1421
1422 (define_expand "cstore<mode>4"
1423 [(set (reg:CC FLAGS_REG)
1424 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1425 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1426 (set (match_operand:QI 0 "register_operand")
1427 (match_operator 1 "ix86_fp_comparison_operator"
1428 [(reg:CC FLAGS_REG)
1429 (const_int 0)]))]
1430 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1431 {
1432 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1433 operands[2], operands[3]);
1434 DONE;
1435 })
1436
1437 (define_expand "cbranchcc4"
1438 [(set (pc) (if_then_else
1439 (match_operator 0 "comparison_operator"
1440 [(match_operand 1 "flags_reg_operand")
1441 (match_operand 2 "const0_operand")])
1442 (label_ref (match_operand 3))
1443 (pc)))]
1444 ""
1445 {
1446 ix86_expand_branch (GET_CODE (operands[0]),
1447 operands[1], operands[2], operands[3]);
1448 DONE;
1449 })
1450
1451 (define_expand "cstorecc4"
1452 [(set (match_operand:QI 0 "register_operand")
1453 (match_operator 1 "comparison_operator"
1454 [(match_operand 2 "flags_reg_operand")
1455 (match_operand 3 "const0_operand")]))]
1456 ""
1457 {
1458 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1459 operands[2], operands[3]);
1460 DONE;
1461 })
1462
1463
1464 ;; FP compares, step 1:
1465 ;; Set the FP condition codes.
1466 ;;
1467 ;; CCFPmode compare with exceptions
1468 ;; CCFPUmode compare with no exceptions
1469
1470 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1471 ;; used to manage the reg stack popping would not be preserved.
1472
1473 (define_insn "*cmp<mode>_0_i387"
1474 [(set (match_operand:HI 0 "register_operand" "=a")
1475 (unspec:HI
1476 [(compare:CCFP
1477 (match_operand:X87MODEF 1 "register_operand" "f")
1478 (match_operand:X87MODEF 2 "const0_operand"))]
1479 UNSPEC_FNSTSW))]
1480 "TARGET_80387"
1481 "* return output_fp_compare (insn, operands, false, false);"
1482 [(set_attr "type" "multi")
1483 (set_attr "unit" "i387")
1484 (set_attr "mode" "<MODE>")])
1485
1486 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1487 [(set (reg:CCFP FLAGS_REG)
1488 (compare:CCFP
1489 (match_operand:X87MODEF 1 "register_operand" "f")
1490 (match_operand:X87MODEF 2 "const0_operand")))
1491 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1492 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1493 "#"
1494 "&& reload_completed"
1495 [(set (match_dup 0)
1496 (unspec:HI
1497 [(compare:CCFP (match_dup 1)(match_dup 2))]
1498 UNSPEC_FNSTSW))
1499 (set (reg:CC FLAGS_REG)
1500 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1501 ""
1502 [(set_attr "type" "multi")
1503 (set_attr "unit" "i387")
1504 (set_attr "mode" "<MODE>")])
1505
1506 (define_insn "*cmpxf_i387"
1507 [(set (match_operand:HI 0 "register_operand" "=a")
1508 (unspec:HI
1509 [(compare:CCFP
1510 (match_operand:XF 1 "register_operand" "f")
1511 (match_operand:XF 2 "register_operand" "f"))]
1512 UNSPEC_FNSTSW))]
1513 "TARGET_80387"
1514 "* return output_fp_compare (insn, operands, false, false);"
1515 [(set_attr "type" "multi")
1516 (set_attr "unit" "i387")
1517 (set_attr "mode" "XF")])
1518
1519 (define_insn_and_split "*cmpxf_cc_i387"
1520 [(set (reg:CCFP FLAGS_REG)
1521 (compare:CCFP
1522 (match_operand:XF 1 "register_operand" "f")
1523 (match_operand:XF 2 "register_operand" "f")))
1524 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1525 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1526 "#"
1527 "&& reload_completed"
1528 [(set (match_dup 0)
1529 (unspec:HI
1530 [(compare:CCFP (match_dup 1)(match_dup 2))]
1531 UNSPEC_FNSTSW))
1532 (set (reg:CC FLAGS_REG)
1533 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1534 ""
1535 [(set_attr "type" "multi")
1536 (set_attr "unit" "i387")
1537 (set_attr "mode" "XF")])
1538
1539 (define_insn "*cmp<mode>_i387"
1540 [(set (match_operand:HI 0 "register_operand" "=a")
1541 (unspec:HI
1542 [(compare:CCFP
1543 (match_operand:MODEF 1 "register_operand" "f")
1544 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1545 UNSPEC_FNSTSW))]
1546 "TARGET_80387"
1547 "* return output_fp_compare (insn, operands, false, false);"
1548 [(set_attr "type" "multi")
1549 (set_attr "unit" "i387")
1550 (set_attr "mode" "<MODE>")])
1551
1552 (define_insn_and_split "*cmp<mode>_cc_i387"
1553 [(set (reg:CCFP FLAGS_REG)
1554 (compare:CCFP
1555 (match_operand:MODEF 1 "register_operand" "f")
1556 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1557 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1558 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1559 "#"
1560 "&& reload_completed"
1561 [(set (match_dup 0)
1562 (unspec:HI
1563 [(compare:CCFP (match_dup 1)(match_dup 2))]
1564 UNSPEC_FNSTSW))
1565 (set (reg:CC FLAGS_REG)
1566 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1567 ""
1568 [(set_attr "type" "multi")
1569 (set_attr "unit" "i387")
1570 (set_attr "mode" "<MODE>")])
1571
1572 (define_insn "*cmpu<mode>_i387"
1573 [(set (match_operand:HI 0 "register_operand" "=a")
1574 (unspec:HI
1575 [(compare:CCFPU
1576 (match_operand:X87MODEF 1 "register_operand" "f")
1577 (match_operand:X87MODEF 2 "register_operand" "f"))]
1578 UNSPEC_FNSTSW))]
1579 "TARGET_80387"
1580 "* return output_fp_compare (insn, operands, false, true);"
1581 [(set_attr "type" "multi")
1582 (set_attr "unit" "i387")
1583 (set_attr "mode" "<MODE>")])
1584
1585 (define_insn_and_split "*cmpu<mode>_cc_i387"
1586 [(set (reg:CCFPU FLAGS_REG)
1587 (compare:CCFPU
1588 (match_operand:X87MODEF 1 "register_operand" "f")
1589 (match_operand:X87MODEF 2 "register_operand" "f")))
1590 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1591 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1592 "#"
1593 "&& reload_completed"
1594 [(set (match_dup 0)
1595 (unspec:HI
1596 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1597 UNSPEC_FNSTSW))
1598 (set (reg:CC FLAGS_REG)
1599 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1600 ""
1601 [(set_attr "type" "multi")
1602 (set_attr "unit" "i387")
1603 (set_attr "mode" "<MODE>")])
1604
1605 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1606 [(set (match_operand:HI 0 "register_operand" "=a")
1607 (unspec:HI
1608 [(compare:CCFP
1609 (match_operand:X87MODEF 1 "register_operand" "f")
1610 (match_operator:X87MODEF 3 "float_operator"
1611 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1612 UNSPEC_FNSTSW))]
1613 "TARGET_80387
1614 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1615 || optimize_function_for_size_p (cfun))"
1616 "* return output_fp_compare (insn, operands, false, false);"
1617 [(set_attr "type" "multi")
1618 (set_attr "unit" "i387")
1619 (set_attr "fp_int_src" "true")
1620 (set_attr "mode" "<SWI24:MODE>")])
1621
1622 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1623 [(set (reg:CCFP FLAGS_REG)
1624 (compare:CCFP
1625 (match_operand:X87MODEF 1 "register_operand" "f")
1626 (match_operator:X87MODEF 3 "float_operator"
1627 [(match_operand:SWI24 2 "memory_operand" "m")])))
1628 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1629 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1630 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1631 || optimize_function_for_size_p (cfun))"
1632 "#"
1633 "&& reload_completed"
1634 [(set (match_dup 0)
1635 (unspec:HI
1636 [(compare:CCFP
1637 (match_dup 1)
1638 (match_op_dup 3 [(match_dup 2)]))]
1639 UNSPEC_FNSTSW))
1640 (set (reg:CC FLAGS_REG)
1641 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1642 ""
1643 [(set_attr "type" "multi")
1644 (set_attr "unit" "i387")
1645 (set_attr "fp_int_src" "true")
1646 (set_attr "mode" "<SWI24:MODE>")])
1647
1648 ;; FP compares, step 2
1649 ;; Move the fpsw to ax.
1650
1651 (define_insn "x86_fnstsw_1"
1652 [(set (match_operand:HI 0 "register_operand" "=a")
1653 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1654 "TARGET_80387"
1655 "fnstsw\t%0"
1656 [(set_attr "length" "2")
1657 (set_attr "mode" "SI")
1658 (set_attr "unit" "i387")])
1659
1660 ;; FP compares, step 3
1661 ;; Get ax into flags, general case.
1662
1663 (define_insn "x86_sahf_1"
1664 [(set (reg:CC FLAGS_REG)
1665 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1666 UNSPEC_SAHF))]
1667 "TARGET_SAHF"
1668 {
1669 #ifndef HAVE_AS_IX86_SAHF
1670 if (TARGET_64BIT)
1671 return ASM_BYTE "0x9e";
1672 else
1673 #endif
1674 return "sahf";
1675 }
1676 [(set_attr "length" "1")
1677 (set_attr "athlon_decode" "vector")
1678 (set_attr "amdfam10_decode" "direct")
1679 (set_attr "bdver1_decode" "direct")
1680 (set_attr "mode" "SI")])
1681
1682 ;; Pentium Pro can do steps 1 through 3 in one go.
1683 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1684 ;; (these i387 instructions set flags directly)
1685
1686 (define_mode_iterator FPCMP [CCFP CCFPU])
1687 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1688
1689 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>"
1690 [(set (reg:FPCMP FLAGS_REG)
1691 (compare:FPCMP
1692 (match_operand:MODEF 0 "register_operand" "f,v")
1693 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1694 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1695 || (TARGET_80387 && TARGET_CMOVE)"
1696 "* return output_fp_compare (insn, operands, true,
1697 <FPCMP:MODE>mode == CCFPUmode);"
1698 [(set_attr "type" "fcmp,ssecomi")
1699 (set_attr "prefix" "orig,maybe_vex")
1700 (set_attr "mode" "<MODEF:MODE>")
1701 (set_attr "prefix_rep" "*,0")
1702 (set (attr "prefix_data16")
1703 (cond [(eq_attr "alternative" "0")
1704 (const_string "*")
1705 (eq_attr "mode" "DF")
1706 (const_string "1")
1707 ]
1708 (const_string "0")))
1709 (set_attr "athlon_decode" "vector")
1710 (set_attr "amdfam10_decode" "direct")
1711 (set_attr "bdver1_decode" "double")
1712 (set_attr "znver1_decode" "double")
1713 (set (attr "enabled")
1714 (if_then_else
1715 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1716 (if_then_else
1717 (eq_attr "alternative" "0")
1718 (symbol_ref "TARGET_MIX_SSE_I387")
1719 (symbol_ref "true"))
1720 (if_then_else
1721 (eq_attr "alternative" "0")
1722 (symbol_ref "true")
1723 (symbol_ref "false"))))])
1724
1725 (define_insn "*cmpi<unord>xf_i387"
1726 [(set (reg:FPCMP FLAGS_REG)
1727 (compare:FPCMP
1728 (match_operand:XF 0 "register_operand" "f")
1729 (match_operand:XF 1 "register_operand" "f")))]
1730 "TARGET_80387 && TARGET_CMOVE"
1731 "* return output_fp_compare (insn, operands, true,
1732 <MODE>mode == CCFPUmode);"
1733 [(set_attr "type" "fcmp")
1734 (set_attr "mode" "XF")
1735 (set_attr "athlon_decode" "vector")
1736 (set_attr "amdfam10_decode" "direct")
1737 (set_attr "bdver1_decode" "double")
1738 (set_attr "znver1_decode" "double")])
1739 \f
1740 ;; Push/pop instructions.
1741
1742 (define_insn "*push<mode>2"
1743 [(set (match_operand:DWI 0 "push_operand" "=<")
1744 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1745 ""
1746 "#"
1747 [(set_attr "type" "multi")
1748 (set_attr "mode" "<MODE>")])
1749
1750 (define_split
1751 [(set (match_operand:DWI 0 "push_operand")
1752 (match_operand:DWI 1 "general_gr_operand"))]
1753 "reload_completed"
1754 [(const_int 0)]
1755 "ix86_split_long_move (operands); DONE;")
1756
1757 (define_insn "*pushdi2_rex64"
1758 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1759 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1760 "TARGET_64BIT"
1761 "@
1762 push{q}\t%1
1763 #"
1764 [(set_attr "type" "push,multi")
1765 (set_attr "mode" "DI")])
1766
1767 ;; Convert impossible pushes of immediate to existing instructions.
1768 ;; First try to get scratch register and go through it. In case this
1769 ;; fails, push sign extended lower part first and then overwrite
1770 ;; upper part by 32bit move.
1771 (define_peephole2
1772 [(match_scratch:DI 2 "r")
1773 (set (match_operand:DI 0 "push_operand")
1774 (match_operand:DI 1 "immediate_operand"))]
1775 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1776 && !x86_64_immediate_operand (operands[1], DImode)"
1777 [(set (match_dup 2) (match_dup 1))
1778 (set (match_dup 0) (match_dup 2))])
1779
1780 ;; We need to define this as both peepholer and splitter for case
1781 ;; peephole2 pass is not run.
1782 ;; "&& 1" is needed to keep it from matching the previous pattern.
1783 (define_peephole2
1784 [(set (match_operand:DI 0 "push_operand")
1785 (match_operand:DI 1 "immediate_operand"))]
1786 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1787 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1788 [(set (match_dup 0) (match_dup 1))
1789 (set (match_dup 2) (match_dup 3))]
1790 {
1791 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1792
1793 operands[1] = gen_lowpart (DImode, operands[2]);
1794 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1795 GEN_INT (4)));
1796 })
1797
1798 (define_split
1799 [(set (match_operand:DI 0 "push_operand")
1800 (match_operand:DI 1 "immediate_operand"))]
1801 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1802 ? epilogue_completed : reload_completed)
1803 && !symbolic_operand (operands[1], DImode)
1804 && !x86_64_immediate_operand (operands[1], DImode)"
1805 [(set (match_dup 0) (match_dup 1))
1806 (set (match_dup 2) (match_dup 3))]
1807 {
1808 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1809
1810 operands[1] = gen_lowpart (DImode, operands[2]);
1811 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1812 GEN_INT (4)));
1813 })
1814
1815 (define_insn "*pushsi2"
1816 [(set (match_operand:SI 0 "push_operand" "=<")
1817 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1818 "!TARGET_64BIT"
1819 "push{l}\t%1"
1820 [(set_attr "type" "push")
1821 (set_attr "mode" "SI")])
1822
1823 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1824 ;; "push a byte/word". But actually we use pushl, which has the effect
1825 ;; of rounding the amount pushed up to a word.
1826
1827 ;; For TARGET_64BIT we always round up to 8 bytes.
1828 (define_insn "*push<mode>2_rex64"
1829 [(set (match_operand:SWI124 0 "push_operand" "=X")
1830 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1831 "TARGET_64BIT"
1832 "push{q}\t%q1"
1833 [(set_attr "type" "push")
1834 (set_attr "mode" "DI")])
1835
1836 (define_insn "*push<mode>2"
1837 [(set (match_operand:SWI12 0 "push_operand" "=X")
1838 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1839 "!TARGET_64BIT"
1840 "push{l}\t%k1"
1841 [(set_attr "type" "push")
1842 (set_attr "mode" "SI")])
1843
1844 (define_insn "*push<mode>2_prologue"
1845 [(set (match_operand:W 0 "push_operand" "=<")
1846 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1847 (clobber (mem:BLK (scratch)))]
1848 ""
1849 "push{<imodesuffix>}\t%1"
1850 [(set_attr "type" "push")
1851 (set_attr "mode" "<MODE>")])
1852
1853 (define_insn "*pop<mode>1"
1854 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1855 (match_operand:W 1 "pop_operand" ">"))]
1856 ""
1857 "pop{<imodesuffix>}\t%0"
1858 [(set_attr "type" "pop")
1859 (set_attr "mode" "<MODE>")])
1860
1861 (define_insn "*pop<mode>1_epilogue"
1862 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1863 (match_operand:W 1 "pop_operand" ">"))
1864 (clobber (mem:BLK (scratch)))]
1865 ""
1866 "pop{<imodesuffix>}\t%0"
1867 [(set_attr "type" "pop")
1868 (set_attr "mode" "<MODE>")])
1869
1870 (define_insn "*pushfl<mode>2"
1871 [(set (match_operand:W 0 "push_operand" "=<")
1872 (match_operand:W 1 "flags_reg_operand"))]
1873 ""
1874 "pushf{<imodesuffix>}"
1875 [(set_attr "type" "push")
1876 (set_attr "mode" "<MODE>")])
1877
1878 (define_insn "*popfl<mode>1"
1879 [(set (match_operand:W 0 "flags_reg_operand")
1880 (match_operand:W 1 "pop_operand" ">"))]
1881 ""
1882 "popf{<imodesuffix>}"
1883 [(set_attr "type" "pop")
1884 (set_attr "mode" "<MODE>")])
1885
1886 \f
1887 ;; Reload patterns to support multi-word load/store
1888 ;; with non-offsetable address.
1889 (define_expand "reload_noff_store"
1890 [(parallel [(match_operand 0 "memory_operand" "=m")
1891 (match_operand 1 "register_operand" "r")
1892 (match_operand:DI 2 "register_operand" "=&r")])]
1893 "TARGET_64BIT"
1894 {
1895 rtx mem = operands[0];
1896 rtx addr = XEXP (mem, 0);
1897
1898 emit_move_insn (operands[2], addr);
1899 mem = replace_equiv_address_nv (mem, operands[2]);
1900
1901 emit_insn (gen_rtx_SET (mem, operands[1]));
1902 DONE;
1903 })
1904
1905 (define_expand "reload_noff_load"
1906 [(parallel [(match_operand 0 "register_operand" "=r")
1907 (match_operand 1 "memory_operand" "m")
1908 (match_operand:DI 2 "register_operand" "=r")])]
1909 "TARGET_64BIT"
1910 {
1911 rtx mem = operands[1];
1912 rtx addr = XEXP (mem, 0);
1913
1914 emit_move_insn (operands[2], addr);
1915 mem = replace_equiv_address_nv (mem, operands[2]);
1916
1917 emit_insn (gen_rtx_SET (operands[0], mem));
1918 DONE;
1919 })
1920
1921 ;; Move instructions.
1922
1923 (define_expand "movxi"
1924 [(set (match_operand:XI 0 "nonimmediate_operand")
1925 (match_operand:XI 1 "general_operand"))]
1926 "TARGET_AVX512F"
1927 "ix86_expand_vector_move (XImode, operands); DONE;")
1928
1929 (define_expand "movoi"
1930 [(set (match_operand:OI 0 "nonimmediate_operand")
1931 (match_operand:OI 1 "general_operand"))]
1932 "TARGET_AVX"
1933 "ix86_expand_vector_move (OImode, operands); DONE;")
1934
1935 (define_expand "movti"
1936 [(set (match_operand:TI 0 "nonimmediate_operand")
1937 (match_operand:TI 1 "general_operand"))]
1938 "TARGET_64BIT || TARGET_SSE"
1939 {
1940 if (TARGET_64BIT)
1941 ix86_expand_move (TImode, operands);
1942 else
1943 ix86_expand_vector_move (TImode, operands);
1944 DONE;
1945 })
1946
1947 ;; This expands to what emit_move_complex would generate if we didn't
1948 ;; have a movti pattern. Having this avoids problems with reload on
1949 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1950 ;; to have around all the time.
1951 (define_expand "movcdi"
1952 [(set (match_operand:CDI 0 "nonimmediate_operand")
1953 (match_operand:CDI 1 "general_operand"))]
1954 ""
1955 {
1956 if (push_operand (operands[0], CDImode))
1957 emit_move_complex_push (CDImode, operands[0], operands[1]);
1958 else
1959 emit_move_complex_parts (operands[0], operands[1]);
1960 DONE;
1961 })
1962
1963 (define_expand "mov<mode>"
1964 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1965 (match_operand:SWI1248x 1 "general_operand"))]
1966 ""
1967 "ix86_expand_move (<MODE>mode, operands); DONE;")
1968
1969 (define_insn "*mov<mode>_xor"
1970 [(set (match_operand:SWI48 0 "register_operand" "=r")
1971 (match_operand:SWI48 1 "const0_operand"))
1972 (clobber (reg:CC FLAGS_REG))]
1973 "reload_completed"
1974 "xor{l}\t%k0, %k0"
1975 [(set_attr "type" "alu1")
1976 (set_attr "modrm_class" "op0")
1977 (set_attr "mode" "SI")
1978 (set_attr "length_immediate" "0")])
1979
1980 (define_insn "*mov<mode>_or"
1981 [(set (match_operand:SWI48 0 "register_operand" "=r")
1982 (match_operand:SWI48 1 "constm1_operand"))
1983 (clobber (reg:CC FLAGS_REG))]
1984 "reload_completed"
1985 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1986 [(set_attr "type" "alu1")
1987 (set_attr "mode" "<MODE>")
1988 (set_attr "length_immediate" "1")])
1989
1990 (define_insn "*movxi_internal_avx512f"
1991 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
1992 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1993 "TARGET_AVX512F
1994 && (register_operand (operands[0], XImode)
1995 || register_operand (operands[1], XImode))"
1996 {
1997 switch (get_attr_type (insn))
1998 {
1999 case TYPE_SSELOG1:
2000 return standard_sse_constant_opcode (insn, operands[1]);
2001
2002 case TYPE_SSEMOV:
2003 if (misaligned_operand (operands[0], XImode)
2004 || misaligned_operand (operands[1], XImode))
2005 return "vmovdqu32\t{%1, %0|%0, %1}";
2006 else
2007 return "vmovdqa32\t{%1, %0|%0, %1}";
2008
2009 default:
2010 gcc_unreachable ();
2011 }
2012 }
2013 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2014 (set_attr "prefix" "evex")
2015 (set_attr "mode" "XI")])
2016
2017 (define_insn "*movoi_internal_avx"
2018 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2019 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2020 "TARGET_AVX
2021 && (register_operand (operands[0], OImode)
2022 || register_operand (operands[1], OImode))"
2023 {
2024 switch (get_attr_type (insn))
2025 {
2026 case TYPE_SSELOG1:
2027 return standard_sse_constant_opcode (insn, operands[1]);
2028
2029 case TYPE_SSEMOV:
2030 if (misaligned_operand (operands[0], OImode)
2031 || misaligned_operand (operands[1], OImode))
2032 {
2033 if (get_attr_mode (insn) == MODE_V8SF)
2034 return "vmovups\t{%1, %0|%0, %1}";
2035 else if (get_attr_mode (insn) == MODE_XI)
2036 return "vmovdqu32\t{%1, %0|%0, %1}";
2037 else
2038 return "vmovdqu\t{%1, %0|%0, %1}";
2039 }
2040 else
2041 {
2042 if (get_attr_mode (insn) == MODE_V8SF)
2043 return "vmovaps\t{%1, %0|%0, %1}";
2044 else if (get_attr_mode (insn) == MODE_XI)
2045 return "vmovdqa32\t{%1, %0|%0, %1}";
2046 else
2047 return "vmovdqa\t{%1, %0|%0, %1}";
2048 }
2049
2050 default:
2051 gcc_unreachable ();
2052 }
2053 }
2054 [(set_attr "isa" "*,avx2,*,*")
2055 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2056 (set_attr "prefix" "vex")
2057 (set (attr "mode")
2058 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2059 (match_operand 1 "ext_sse_reg_operand"))
2060 (const_string "XI")
2061 (and (eq_attr "alternative" "1")
2062 (match_test "TARGET_AVX512VL"))
2063 (const_string "XI")
2064 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2065 (and (eq_attr "alternative" "3")
2066 (match_test "TARGET_SSE_TYPELESS_STORES")))
2067 (const_string "V8SF")
2068 ]
2069 (const_string "OI")))])
2070
2071 (define_insn "*movti_internal"
2072 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m")
2073 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v"))]
2074 "(TARGET_64BIT
2075 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2076 || (TARGET_SSE
2077 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2078 && (register_operand (operands[0], TImode)
2079 || register_operand (operands[1], TImode)))"
2080 {
2081 switch (get_attr_type (insn))
2082 {
2083 case TYPE_MULTI:
2084 return "#";
2085
2086 case TYPE_SSELOG1:
2087 return standard_sse_constant_opcode (insn, operands[1]);
2088
2089 case TYPE_SSEMOV:
2090 /* TDmode values are passed as TImode on the stack. Moving them
2091 to stack may result in unaligned memory access. */
2092 if (misaligned_operand (operands[0], TImode)
2093 || misaligned_operand (operands[1], TImode))
2094 {
2095 if (get_attr_mode (insn) == MODE_V4SF)
2096 return "%vmovups\t{%1, %0|%0, %1}";
2097 else if (get_attr_mode (insn) == MODE_XI)
2098 return "vmovdqu32\t{%1, %0|%0, %1}";
2099 else
2100 return "%vmovdqu\t{%1, %0|%0, %1}";
2101 }
2102 else
2103 {
2104 if (get_attr_mode (insn) == MODE_V4SF)
2105 return "%vmovaps\t{%1, %0|%0, %1}";
2106 else if (get_attr_mode (insn) == MODE_XI)
2107 return "vmovdqa32\t{%1, %0|%0, %1}";
2108 else
2109 return "%vmovdqa\t{%1, %0|%0, %1}";
2110 }
2111
2112 default:
2113 gcc_unreachable ();
2114 }
2115 }
2116 [(set_attr "isa" "x64,x64,*,sse2,*,*")
2117 (set_attr "type" "multi,multi,sselog1,sselog1,ssemov,ssemov")
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 "mode")
2123 (cond [(eq_attr "alternative" "0,1")
2124 (const_string "DI")
2125 (ior (match_operand 0 "ext_sse_reg_operand")
2126 (match_operand 1 "ext_sse_reg_operand"))
2127 (const_string "XI")
2128 (and (eq_attr "alternative" "3")
2129 (match_test "TARGET_AVX512VL"))
2130 (const_string "XI")
2131 (ior (not (match_test "TARGET_SSE2"))
2132 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2133 (and (eq_attr "alternative" "5")
2134 (match_test "TARGET_SSE_TYPELESS_STORES"))))
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 (define_insn "*movdi_internal"
2144 [(set (match_operand:DI 0 "nonimmediate_operand"
2145 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r,*m")
2146 (match_operand:DI 1 "general_operand"
2147 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,v,*Yj,*v,r ,*Yj ,*Yn ,*r,*km,*k,*k"))]
2148 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2149 {
2150 switch (get_attr_type (insn))
2151 {
2152 case TYPE_MSKMOV:
2153 return "kmovq\t{%1, %0|%0, %1}";
2154
2155 case TYPE_MULTI:
2156 return "#";
2157
2158 case TYPE_MMX:
2159 return "pxor\t%0, %0";
2160
2161 case TYPE_MMXMOV:
2162 /* Handle broken assemblers that require movd instead of movq. */
2163 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2164 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2165 return "movd\t{%1, %0|%0, %1}";
2166 return "movq\t{%1, %0|%0, %1}";
2167
2168 case TYPE_SSELOG1:
2169 if (GENERAL_REG_P (operands[0]))
2170 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2171
2172 return standard_sse_constant_opcode (insn, operands[1]);
2173
2174 case TYPE_SSEMOV:
2175 switch (get_attr_mode (insn))
2176 {
2177 case MODE_DI:
2178 /* Handle broken assemblers that require movd instead of movq. */
2179 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2180 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2181 return "%vmovd\t{%1, %0|%0, %1}";
2182 return "%vmovq\t{%1, %0|%0, %1}";
2183 case MODE_TI:
2184 return "%vmovdqa\t{%1, %0|%0, %1}";
2185 case MODE_XI:
2186 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2187
2188 case MODE_V2SF:
2189 gcc_assert (!TARGET_AVX);
2190 return "movlps\t{%1, %0|%0, %1}";
2191 case MODE_V4SF:
2192 return "%vmovaps\t{%1, %0|%0, %1}";
2193
2194 default:
2195 gcc_unreachable ();
2196 }
2197
2198 case TYPE_SSECVT:
2199 if (SSE_REG_P (operands[0]))
2200 return "movq2dq\t{%1, %0|%0, %1}";
2201 else
2202 return "movdq2q\t{%1, %0|%0, %1}";
2203
2204 case TYPE_LEA:
2205 return "lea{q}\t{%E1, %0|%0, %E1}";
2206
2207 case TYPE_IMOV:
2208 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2209 if (get_attr_mode (insn) == MODE_SI)
2210 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2211 else if (which_alternative == 4)
2212 return "movabs{q}\t{%1, %0|%0, %1}";
2213 else if (ix86_use_lea_for_mov (insn, operands))
2214 return "lea{q}\t{%E1, %0|%0, %E1}";
2215 else
2216 return "mov{q}\t{%1, %0|%0, %1}";
2217
2218 default:
2219 gcc_unreachable ();
2220 }
2221 }
2222 [(set (attr "isa")
2223 (cond [(eq_attr "alternative" "0,1")
2224 (const_string "nox64")
2225 (eq_attr "alternative" "2,3,4,5,10,11,17,19,22,24")
2226 (const_string "x64")
2227 (eq_attr "alternative" "18")
2228 (const_string "x64_sse4")
2229 ]
2230 (const_string "*")))
2231 (set (attr "type")
2232 (cond [(eq_attr "alternative" "0,1")
2233 (const_string "multi")
2234 (eq_attr "alternative" "6")
2235 (const_string "mmx")
2236 (eq_attr "alternative" "7,8,9,10,11")
2237 (const_string "mmxmov")
2238 (eq_attr "alternative" "12,18")
2239 (const_string "sselog1")
2240 (eq_attr "alternative" "13,14,15,16,17,19")
2241 (const_string "ssemov")
2242 (eq_attr "alternative" "20,21")
2243 (const_string "ssecvt")
2244 (eq_attr "alternative" "22,23,24,25")
2245 (const_string "mskmov")
2246 (and (match_operand 0 "register_operand")
2247 (match_operand 1 "pic_32bit_operand"))
2248 (const_string "lea")
2249 ]
2250 (const_string "imov")))
2251 (set (attr "modrm")
2252 (if_then_else
2253 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2254 (const_string "0")
2255 (const_string "*")))
2256 (set (attr "length_immediate")
2257 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2258 (const_string "8")
2259 (eq_attr "alternative" "18")
2260 (const_string "1")
2261 ]
2262 (const_string "*")))
2263 (set (attr "prefix_rex")
2264 (if_then_else (eq_attr "alternative" "10,11,17,18,19")
2265 (const_string "1")
2266 (const_string "*")))
2267 (set (attr "prefix_extra")
2268 (if_then_else (eq_attr "alternative" "18")
2269 (const_string "1")
2270 (const_string "*")))
2271 (set (attr "prefix")
2272 (if_then_else (eq_attr "type" "sselog1,ssemov")
2273 (const_string "maybe_vex")
2274 (const_string "orig")))
2275 (set (attr "prefix_data16")
2276 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2277 (const_string "1")
2278 (const_string "*")))
2279 (set (attr "mode")
2280 (cond [(eq_attr "alternative" "2")
2281 (const_string "SI")
2282 (eq_attr "alternative" "12,13")
2283 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2284 (match_operand 1 "ext_sse_reg_operand"))
2285 (const_string "XI")
2286 (ior (not (match_test "TARGET_SSE2"))
2287 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2288 (const_string "V4SF")
2289 (match_test "TARGET_AVX")
2290 (const_string "TI")
2291 (match_test "optimize_function_for_size_p (cfun)")
2292 (const_string "V4SF")
2293 ]
2294 (const_string "TI"))
2295
2296 (and (eq_attr "alternative" "14,15,16")
2297 (not (match_test "TARGET_SSE2")))
2298 (const_string "V2SF")
2299 (eq_attr "alternative" "18")
2300 (const_string "TI")
2301 ]
2302 (const_string "DI")))
2303 (set (attr "enabled")
2304 (cond [(eq_attr "alternative" "15")
2305 (if_then_else
2306 (match_test "TARGET_STV && TARGET_SSE2")
2307 (symbol_ref "false")
2308 (const_string "*"))
2309 (eq_attr "alternative" "16")
2310 (if_then_else
2311 (match_test "TARGET_STV && TARGET_SSE2")
2312 (symbol_ref "true")
2313 (symbol_ref "false"))
2314 ]
2315 (const_string "*")))])
2316
2317 (define_split
2318 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2319 (match_operand:DWI 1 "general_gr_operand"))]
2320 "reload_completed"
2321 [(const_int 0)]
2322 "ix86_split_long_move (operands); DONE;")
2323
2324 (define_insn "*movsi_internal"
2325 [(set (match_operand:SI 0 "nonimmediate_operand"
2326 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2327 (match_operand:SI 1 "general_operand"
2328 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2329 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2330 {
2331 switch (get_attr_type (insn))
2332 {
2333 case TYPE_SSELOG1:
2334 if (GENERAL_REG_P (operands[0]))
2335 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2336
2337 return standard_sse_constant_opcode (insn, operands[1]);
2338
2339 case TYPE_MSKMOV:
2340 return "kmovd\t{%1, %0|%0, %1}";
2341
2342 case TYPE_SSEMOV:
2343 switch (get_attr_mode (insn))
2344 {
2345 case MODE_SI:
2346 return "%vmovd\t{%1, %0|%0, %1}";
2347 case MODE_TI:
2348 return "%vmovdqa\t{%1, %0|%0, %1}";
2349 case MODE_XI:
2350 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2351
2352 case MODE_V4SF:
2353 return "%vmovaps\t{%1, %0|%0, %1}";
2354
2355 case MODE_SF:
2356 gcc_assert (!TARGET_AVX);
2357 return "movss\t{%1, %0|%0, %1}";
2358
2359 default:
2360 gcc_unreachable ();
2361 }
2362
2363 case TYPE_MMX:
2364 return "pxor\t%0, %0";
2365
2366 case TYPE_MMXMOV:
2367 switch (get_attr_mode (insn))
2368 {
2369 case MODE_DI:
2370 return "movq\t{%1, %0|%0, %1}";
2371 case MODE_SI:
2372 return "movd\t{%1, %0|%0, %1}";
2373
2374 default:
2375 gcc_unreachable ();
2376 }
2377
2378 case TYPE_LEA:
2379 return "lea{l}\t{%E1, %0|%0, %E1}";
2380
2381 case TYPE_IMOV:
2382 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2383 if (ix86_use_lea_for_mov (insn, operands))
2384 return "lea{l}\t{%E1, %0|%0, %E1}";
2385 else
2386 return "mov{l}\t{%1, %0|%0, %1}";
2387
2388 default:
2389 gcc_unreachable ();
2390 }
2391 }
2392 [(set (attr "isa")
2393 (if_then_else (eq_attr "alternative" "11")
2394 (const_string "sse4")
2395 (const_string "*")))
2396 (set (attr "type")
2397 (cond [(eq_attr "alternative" "2")
2398 (const_string "mmx")
2399 (eq_attr "alternative" "3,4,5")
2400 (const_string "mmxmov")
2401 (eq_attr "alternative" "6,11")
2402 (const_string "sselog1")
2403 (eq_attr "alternative" "7,8,9,10,12")
2404 (const_string "ssemov")
2405 (eq_attr "alternative" "13,14")
2406 (const_string "mskmov")
2407 (and (match_operand 0 "register_operand")
2408 (match_operand 1 "pic_32bit_operand"))
2409 (const_string "lea")
2410 ]
2411 (const_string "imov")))
2412 (set (attr "length_immediate")
2413 (if_then_else (eq_attr "alternative" "11")
2414 (const_string "1")
2415 (const_string "*")))
2416 (set (attr "prefix_extra")
2417 (if_then_else (eq_attr "alternative" "11")
2418 (const_string "1")
2419 (const_string "*")))
2420 (set (attr "prefix")
2421 (if_then_else (eq_attr "type" "sselog1,ssemov")
2422 (const_string "maybe_vex")
2423 (const_string "orig")))
2424 (set (attr "prefix_data16")
2425 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2426 (const_string "1")
2427 (const_string "*")))
2428 (set (attr "mode")
2429 (cond [(eq_attr "alternative" "2,3")
2430 (const_string "DI")
2431 (eq_attr "alternative" "6,7")
2432 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2433 (match_operand 1 "ext_sse_reg_operand"))
2434 (const_string "XI")
2435 (ior (not (match_test "TARGET_SSE2"))
2436 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2437 (const_string "V4SF")
2438 (match_test "TARGET_AVX")
2439 (const_string "TI")
2440 (match_test "optimize_function_for_size_p (cfun)")
2441 (const_string "V4SF")
2442 ]
2443 (const_string "TI"))
2444
2445 (and (eq_attr "alternative" "8,9")
2446 (not (match_test "TARGET_SSE2")))
2447 (const_string "SF")
2448 (eq_attr "alternative" "11")
2449 (const_string "TI")
2450 ]
2451 (const_string "SI")))])
2452
2453 (define_insn "*movhi_internal"
2454 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2455 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2456 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2457 {
2458 switch (get_attr_type (insn))
2459 {
2460 case TYPE_IMOVX:
2461 /* movzwl is faster than movw on p2 due to partial word stalls,
2462 though not as fast as an aligned movl. */
2463 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2464
2465 case TYPE_MSKMOV:
2466 switch (which_alternative)
2467 {
2468 case 4:
2469 return "kmovw\t{%k1, %0|%0, %k1}";
2470 case 6:
2471 return "kmovw\t{%1, %k0|%k0, %1}";
2472 case 5:
2473 case 7:
2474 return "kmovw\t{%1, %0|%0, %1}";
2475 default:
2476 gcc_unreachable ();
2477 }
2478
2479 default:
2480 if (get_attr_mode (insn) == MODE_SI)
2481 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2482 else
2483 return "mov{w}\t{%1, %0|%0, %1}";
2484 }
2485 }
2486 [(set (attr "type")
2487 (cond [(eq_attr "alternative" "4,5,6,7")
2488 (const_string "mskmov")
2489 (match_test "optimize_function_for_size_p (cfun)")
2490 (const_string "imov")
2491 (and (eq_attr "alternative" "0")
2492 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2493 (not (match_test "TARGET_HIMODE_MATH"))))
2494 (const_string "imov")
2495 (and (eq_attr "alternative" "1,2")
2496 (match_operand:HI 1 "aligned_operand"))
2497 (const_string "imov")
2498 (and (match_test "TARGET_MOVX")
2499 (eq_attr "alternative" "0,2"))
2500 (const_string "imovx")
2501 ]
2502 (const_string "imov")))
2503 (set (attr "prefix")
2504 (if_then_else (eq_attr "alternative" "4,5,6,7")
2505 (const_string "vex")
2506 (const_string "orig")))
2507 (set (attr "mode")
2508 (cond [(eq_attr "type" "imovx")
2509 (const_string "SI")
2510 (and (eq_attr "alternative" "1,2")
2511 (match_operand:HI 1 "aligned_operand"))
2512 (const_string "SI")
2513 (and (eq_attr "alternative" "0")
2514 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2515 (not (match_test "TARGET_HIMODE_MATH"))))
2516 (const_string "SI")
2517 ]
2518 (const_string "HI")))])
2519
2520 ;; Situation is quite tricky about when to choose full sized (SImode) move
2521 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2522 ;; partial register dependency machines (such as AMD Athlon), where QImode
2523 ;; moves issue extra dependency and for partial register stalls machines
2524 ;; that don't use QImode patterns (and QImode move cause stall on the next
2525 ;; instruction).
2526 ;;
2527 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2528 ;; register stall machines with, where we use QImode instructions, since
2529 ;; partial register stall can be caused there. Then we use movzx.
2530
2531 (define_insn "*movqi_internal"
2532 [(set (match_operand:QI 0 "nonimmediate_operand"
2533 "=q,q ,q ,r,r ,?r,m ,k,k,r,m,k")
2534 (match_operand:QI 1 "general_operand"
2535 "q ,qn,qm,q,rn,qm,qn,r,k,k,k,m"))]
2536 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2537 {
2538 static char buf[128];
2539 const char *ops;
2540 const char *suffix;
2541
2542 switch (get_attr_type (insn))
2543 {
2544 case TYPE_IMOVX:
2545 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2546 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2547
2548 case TYPE_MSKMOV:
2549 switch (which_alternative)
2550 {
2551 case 7:
2552 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2553 break;
2554 case 9:
2555 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2556 break;
2557 case 10:
2558 case 11:
2559 gcc_assert (TARGET_AVX512DQ);
2560 /* FALLTHRU */
2561 case 8:
2562 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2563 break;
2564 default:
2565 gcc_unreachable ();
2566 }
2567
2568 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2569
2570 snprintf (buf, sizeof (buf), ops, suffix);
2571 return buf;
2572
2573 default:
2574 if (get_attr_mode (insn) == MODE_SI)
2575 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2576 else
2577 return "mov{b}\t{%1, %0|%0, %1}";
2578 }
2579 }
2580 [(set (attr "isa")
2581 (if_then_else (eq_attr "alternative" "10,11")
2582 (const_string "avx512dq")
2583 (const_string "*")))
2584 (set (attr "type")
2585 (cond [(eq_attr "alternative" "7,8,9,10,11")
2586 (const_string "mskmov")
2587 (and (eq_attr "alternative" "5")
2588 (not (match_operand:QI 1 "aligned_operand")))
2589 (const_string "imovx")
2590 (match_test "optimize_function_for_size_p (cfun)")
2591 (const_string "imov")
2592 (and (eq_attr "alternative" "3")
2593 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2594 (not (match_test "TARGET_QIMODE_MATH"))))
2595 (const_string "imov")
2596 (eq_attr "alternative" "3,5")
2597 (const_string "imovx")
2598 (and (match_test "TARGET_MOVX")
2599 (eq_attr "alternative" "2"))
2600 (const_string "imovx")
2601 ]
2602 (const_string "imov")))
2603 (set (attr "prefix")
2604 (if_then_else (eq_attr "alternative" "7,8,9")
2605 (const_string "vex")
2606 (const_string "orig")))
2607 (set (attr "mode")
2608 (cond [(eq_attr "alternative" "3,4,5")
2609 (const_string "SI")
2610 (eq_attr "alternative" "6")
2611 (const_string "QI")
2612 (and (eq_attr "alternative" "7,8,9")
2613 (not (match_test "TARGET_AVX512DQ")))
2614 (const_string "HI")
2615 (eq_attr "type" "imovx")
2616 (const_string "SI")
2617 (and (eq_attr "type" "imov")
2618 (and (eq_attr "alternative" "0,1")
2619 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2620 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2621 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2622 (const_string "SI")
2623 ;; Avoid partial register stalls when not using QImode arithmetic
2624 (and (eq_attr "type" "imov")
2625 (and (eq_attr "alternative" "0,1")
2626 (and (match_test "TARGET_PARTIAL_REG_STALL")
2627 (not (match_test "TARGET_QIMODE_MATH")))))
2628 (const_string "SI")
2629 ]
2630 (const_string "QI")))])
2631
2632 ;; Stores and loads of ax to arbitrary constant address.
2633 ;; We fake an second form of instruction to force reload to load address
2634 ;; into register when rax is not available
2635 (define_insn "*movabs<mode>_1"
2636 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2637 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2638 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2639 {
2640 /* Recover the full memory rtx. */
2641 operands[0] = SET_DEST (PATTERN (insn));
2642 switch (which_alternative)
2643 {
2644 case 0:
2645 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2646 case 1:
2647 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2648 default:
2649 gcc_unreachable ();
2650 }
2651 }
2652 [(set_attr "type" "imov")
2653 (set_attr "modrm" "0,*")
2654 (set_attr "length_address" "8,0")
2655 (set_attr "length_immediate" "0,*")
2656 (set_attr "memory" "store")
2657 (set_attr "mode" "<MODE>")])
2658
2659 (define_insn "*movabs<mode>_2"
2660 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2661 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2662 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2663 {
2664 /* Recover the full memory rtx. */
2665 operands[1] = SET_SRC (PATTERN (insn));
2666 switch (which_alternative)
2667 {
2668 case 0:
2669 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2670 case 1:
2671 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2672 default:
2673 gcc_unreachable ();
2674 }
2675 }
2676 [(set_attr "type" "imov")
2677 (set_attr "modrm" "0,*")
2678 (set_attr "length_address" "8,0")
2679 (set_attr "length_immediate" "0")
2680 (set_attr "memory" "load")
2681 (set_attr "mode" "<MODE>")])
2682
2683 (define_insn "*swap<mode>"
2684 [(set (match_operand:SWI48 0 "register_operand" "+r")
2685 (match_operand:SWI48 1 "register_operand" "+r"))
2686 (set (match_dup 1)
2687 (match_dup 0))]
2688 ""
2689 "xchg{<imodesuffix>}\t%1, %0"
2690 [(set_attr "type" "imov")
2691 (set_attr "mode" "<MODE>")
2692 (set_attr "pent_pair" "np")
2693 (set_attr "athlon_decode" "vector")
2694 (set_attr "amdfam10_decode" "double")
2695 (set_attr "bdver1_decode" "double")])
2696
2697 (define_insn "*swap<mode>"
2698 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2699 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2700 (set (match_dup 1)
2701 (match_dup 0))]
2702 ""
2703 "@
2704 xchg{<imodesuffix>}\t%1, %0
2705 xchg{l}\t%k1, %k0"
2706 [(set_attr "type" "imov")
2707 (set_attr "mode" "<MODE>,SI")
2708 (set (attr "preferred_for_size")
2709 (cond [(eq_attr "alternative" "0")
2710 (symbol_ref "false")]
2711 (symbol_ref "true")))
2712 ;; Potential partial reg stall on alternative 1.
2713 (set (attr "preferred_for_speed")
2714 (cond [(eq_attr "alternative" "1")
2715 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2716 (symbol_ref "true")))
2717 (set_attr "pent_pair" "np")
2718 (set_attr "athlon_decode" "vector")
2719 (set_attr "amdfam10_decode" "double")
2720 (set_attr "bdver1_decode" "double")])
2721
2722 (define_expand "movstrict<mode>"
2723 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2724 (match_operand:SWI12 1 "general_operand"))]
2725 ""
2726 {
2727 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2728 FAIL;
2729 if (SUBREG_P (operands[0])
2730 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2731 FAIL;
2732 /* Don't generate memory->memory moves, go through a register */
2733 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2734 operands[1] = force_reg (<MODE>mode, operands[1]);
2735 })
2736
2737 (define_insn "*movstrict<mode>_1"
2738 [(set (strict_low_part
2739 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2740 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2741 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2742 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2743 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2744 [(set_attr "type" "imov")
2745 (set_attr "mode" "<MODE>")])
2746
2747 (define_insn "*movstrict<mode>_xor"
2748 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2749 (match_operand:SWI12 1 "const0_operand"))
2750 (clobber (reg:CC FLAGS_REG))]
2751 "reload_completed"
2752 "xor{<imodesuffix>}\t%0, %0"
2753 [(set_attr "type" "alu1")
2754 (set_attr "modrm_class" "op0")
2755 (set_attr "mode" "<MODE>")
2756 (set_attr "length_immediate" "0")])
2757
2758 (define_expand "extv<mode>"
2759 [(set (match_operand:SWI24 0 "register_operand")
2760 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2761 (match_operand:SI 2 "const_int_operand")
2762 (match_operand:SI 3 "const_int_operand")))]
2763 ""
2764 {
2765 /* Handle extractions from %ah et al. */
2766 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2767 FAIL;
2768
2769 unsigned int regno = reg_or_subregno (operands[1]);
2770
2771 /* Be careful to expand only with registers having upper parts. */
2772 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2773 operands[1] = copy_to_reg (operands[1]);
2774 })
2775
2776 (define_insn "*extv<mode>"
2777 [(set (match_operand:SWI24 0 "register_operand" "=R")
2778 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2779 (const_int 8)
2780 (const_int 8)))]
2781 ""
2782 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2783 [(set_attr "type" "imovx")
2784 (set_attr "mode" "SI")])
2785
2786 (define_expand "extzv<mode>"
2787 [(set (match_operand:SWI248 0 "register_operand")
2788 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2789 (match_operand:SI 2 "const_int_operand")
2790 (match_operand:SI 3 "const_int_operand")))]
2791 ""
2792 {
2793 if (ix86_expand_pextr (operands))
2794 DONE;
2795
2796 /* Handle extractions from %ah et al. */
2797 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2798 FAIL;
2799
2800 unsigned int regno = reg_or_subregno (operands[1]);
2801
2802 /* Be careful to expand only with registers having upper parts. */
2803 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2804 operands[1] = copy_to_reg (operands[1]);
2805 })
2806
2807 (define_insn "*extzv<mode>"
2808 [(set (match_operand:SWI248 0 "register_operand" "=R")
2809 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2810 (const_int 8)
2811 (const_int 8)))]
2812 ""
2813 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2814 [(set_attr "type" "imovx")
2815 (set_attr "mode" "SI")])
2816
2817 (define_insn "*extzvqi_mem_rex64"
2818 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2819 (subreg:QI
2820 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2821 (const_int 8)
2822 (const_int 8)) 0))]
2823 "TARGET_64BIT && reload_completed"
2824 "mov{b}\t{%h1, %0|%0, %h1}"
2825 [(set_attr "type" "imov")
2826 (set_attr "mode" "QI")])
2827
2828 (define_insn "*extzvqi"
2829 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2830 (subreg:QI
2831 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2832 (const_int 8)
2833 (const_int 8)) 0))]
2834 ""
2835 {
2836 switch (get_attr_type (insn))
2837 {
2838 case TYPE_IMOVX:
2839 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2840 default:
2841 return "mov{b}\t{%h1, %0|%0, %h1}";
2842 }
2843 }
2844 [(set_attr "isa" "*,*,nox64")
2845 (set (attr "type")
2846 (if_then_else (and (match_operand:QI 0 "register_operand")
2847 (ior (not (match_operand:QI 0 "QIreg_operand"))
2848 (match_test "TARGET_MOVX")))
2849 (const_string "imovx")
2850 (const_string "imov")))
2851 (set (attr "mode")
2852 (if_then_else (eq_attr "type" "imovx")
2853 (const_string "SI")
2854 (const_string "QI")))])
2855
2856 (define_peephole2
2857 [(set (match_operand:QI 0 "register_operand")
2858 (subreg:QI
2859 (zero_extract:SI (match_operand 1 "ext_register_operand")
2860 (const_int 8)
2861 (const_int 8)) 0))
2862 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2863 "TARGET_64BIT
2864 && peep2_reg_dead_p (2, operands[0])"
2865 [(set (match_dup 2)
2866 (subreg:QI
2867 (zero_extract:SI (match_dup 1)
2868 (const_int 8)
2869 (const_int 8)) 0))])
2870
2871 (define_expand "insv<mode>"
2872 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2873 (match_operand:SI 1 "const_int_operand")
2874 (match_operand:SI 2 "const_int_operand"))
2875 (match_operand:SWI248 3 "register_operand"))]
2876 ""
2877 {
2878 rtx dst;
2879
2880 if (ix86_expand_pinsr (operands))
2881 DONE;
2882
2883 /* Handle insertions to %ah et al. */
2884 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2885 FAIL;
2886
2887 unsigned int regno = reg_or_subregno (operands[0]);
2888
2889 /* Be careful to expand only with registers having upper parts. */
2890 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2891 dst = copy_to_reg (operands[0]);
2892 else
2893 dst = operands[0];
2894
2895 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2896
2897 /* Fix up the destination if needed. */
2898 if (dst != operands[0])
2899 emit_move_insn (operands[0], dst);
2900
2901 DONE;
2902 })
2903
2904 (define_insn "insv<mode>_1"
2905 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2906 (const_int 8)
2907 (const_int 8))
2908 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2909 ""
2910 {
2911 if (CONST_INT_P (operands[1]))
2912 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2913 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2914 }
2915 [(set_attr "isa" "*,nox64")
2916 (set_attr "type" "imov")
2917 (set_attr "mode" "QI")])
2918
2919 (define_insn "*insvqi"
2920 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2921 (const_int 8)
2922 (const_int 8))
2923 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2924 (const_int 8)))]
2925 ""
2926 "mov{b}\t{%h1, %h0|%h0, %h1}"
2927 [(set_attr "type" "imov")
2928 (set_attr "mode" "QI")])
2929 \f
2930 ;; Floating point push instructions.
2931
2932 (define_insn "*pushtf"
2933 [(set (match_operand:TF 0 "push_operand" "=<,<")
2934 (match_operand:TF 1 "general_no_elim_operand" "v,*roF"))]
2935 "TARGET_64BIT || TARGET_SSE"
2936 {
2937 /* This insn should be already split before reg-stack. */
2938 gcc_unreachable ();
2939 }
2940 [(set_attr "isa" "*,x64")
2941 (set_attr "type" "multi")
2942 (set_attr "unit" "sse,*")
2943 (set_attr "mode" "TF,DI")])
2944
2945 ;; %%% Kill this when call knows how to work this out.
2946 (define_split
2947 [(set (match_operand:TF 0 "push_operand")
2948 (match_operand:TF 1 "sse_reg_operand"))]
2949 "TARGET_SSE && reload_completed"
2950 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2951 (set (match_dup 0) (match_dup 1))]
2952 {
2953 /* Preserve memory attributes. */
2954 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2955 })
2956
2957 (define_insn "*pushxf"
2958 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2959 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2960 ""
2961 {
2962 /* This insn should be already split before reg-stack. */
2963 gcc_unreachable ();
2964 }
2965 [(set_attr "type" "multi")
2966 (set_attr "unit" "i387,*,*,*")
2967 (set (attr "mode")
2968 (cond [(eq_attr "alternative" "1,2,3")
2969 (if_then_else (match_test "TARGET_64BIT")
2970 (const_string "DI")
2971 (const_string "SI"))
2972 ]
2973 (const_string "XF")))
2974 (set (attr "preferred_for_size")
2975 (cond [(eq_attr "alternative" "1")
2976 (symbol_ref "false")]
2977 (symbol_ref "true")))])
2978
2979 ;; %%% Kill this when call knows how to work this out.
2980 (define_split
2981 [(set (match_operand:XF 0 "push_operand")
2982 (match_operand:XF 1 "fp_register_operand"))]
2983 "reload_completed"
2984 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2985 (set (match_dup 0) (match_dup 1))]
2986 {
2987 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2988 /* Preserve memory attributes. */
2989 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2990 })
2991
2992 (define_insn "*pushdf"
2993 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2994 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2995 ""
2996 {
2997 /* This insn should be already split before reg-stack. */
2998 gcc_unreachable ();
2999 }
3000 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3001 (set_attr "type" "multi")
3002 (set_attr "unit" "i387,*,*,*,*,sse")
3003 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3004 (set (attr "preferred_for_size")
3005 (cond [(eq_attr "alternative" "1")
3006 (symbol_ref "false")]
3007 (symbol_ref "true")))
3008 (set (attr "preferred_for_speed")
3009 (cond [(eq_attr "alternative" "1")
3010 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3011 (symbol_ref "true")))])
3012
3013 ;; %%% Kill this when call knows how to work this out.
3014 (define_split
3015 [(set (match_operand:DF 0 "push_operand")
3016 (match_operand:DF 1 "any_fp_register_operand"))]
3017 "reload_completed"
3018 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3019 (set (match_dup 0) (match_dup 1))]
3020 {
3021 /* Preserve memory attributes. */
3022 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3023 })
3024
3025 (define_insn "*pushsf_rex64"
3026 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3027 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3028 "TARGET_64BIT"
3029 {
3030 /* Anything else should be already split before reg-stack. */
3031 gcc_assert (which_alternative == 1);
3032 return "push{q}\t%q1";
3033 }
3034 [(set_attr "type" "multi,push,multi")
3035 (set_attr "unit" "i387,*,*")
3036 (set_attr "mode" "SF,DI,SF")])
3037
3038 (define_insn "*pushsf"
3039 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3040 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3041 "!TARGET_64BIT"
3042 {
3043 /* Anything else should be already split before reg-stack. */
3044 gcc_assert (which_alternative == 1);
3045 return "push{l}\t%1";
3046 }
3047 [(set_attr "type" "multi,push,multi")
3048 (set_attr "unit" "i387,*,*")
3049 (set_attr "mode" "SF,SI,SF")])
3050
3051 ;; %%% Kill this when call knows how to work this out.
3052 (define_split
3053 [(set (match_operand:SF 0 "push_operand")
3054 (match_operand:SF 1 "any_fp_register_operand"))]
3055 "reload_completed"
3056 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3057 (set (match_dup 0) (match_dup 1))]
3058 {
3059 rtx op = XEXP (operands[0], 0);
3060 if (GET_CODE (op) == PRE_DEC)
3061 {
3062 gcc_assert (!TARGET_64BIT);
3063 op = GEN_INT (-4);
3064 }
3065 else
3066 {
3067 op = XEXP (XEXP (op, 1), 1);
3068 gcc_assert (CONST_INT_P (op));
3069 }
3070 operands[2] = op;
3071 /* Preserve memory attributes. */
3072 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3073 })
3074
3075 (define_split
3076 [(set (match_operand:SF 0 "push_operand")
3077 (match_operand:SF 1 "memory_operand"))]
3078 "reload_completed
3079 && find_constant_src (insn)"
3080 [(set (match_dup 0) (match_dup 2))]
3081 "operands[2] = find_constant_src (curr_insn);")
3082
3083 (define_split
3084 [(set (match_operand 0 "push_operand")
3085 (match_operand 1 "general_gr_operand"))]
3086 "reload_completed
3087 && (GET_MODE (operands[0]) == TFmode
3088 || GET_MODE (operands[0]) == XFmode
3089 || GET_MODE (operands[0]) == DFmode)"
3090 [(const_int 0)]
3091 "ix86_split_long_move (operands); DONE;")
3092 \f
3093 ;; Floating point move instructions.
3094
3095 (define_expand "movtf"
3096 [(set (match_operand:TF 0 "nonimmediate_operand")
3097 (match_operand:TF 1 "nonimmediate_operand"))]
3098 "TARGET_64BIT || TARGET_SSE"
3099 "ix86_expand_move (TFmode, operands); DONE;")
3100
3101 (define_expand "mov<mode>"
3102 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3103 (match_operand:X87MODEF 1 "general_operand"))]
3104 ""
3105 "ix86_expand_move (<MODE>mode, operands); DONE;")
3106
3107 (define_insn "*movtf_internal"
3108 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3109 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3110 "(TARGET_64BIT || TARGET_SSE)
3111 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3112 && (lra_in_progress || reload_completed
3113 || !CONST_DOUBLE_P (operands[1])
3114 || ((optimize_function_for_size_p (cfun)
3115 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3116 && standard_sse_constant_p (operands[1], TFmode) == 1
3117 && !memory_operand (operands[0], TFmode))
3118 || (!TARGET_MEMORY_MISMATCH_STALL
3119 && memory_operand (operands[0], TFmode)))"
3120 {
3121 switch (get_attr_type (insn))
3122 {
3123 case TYPE_SSELOG1:
3124 return standard_sse_constant_opcode (insn, operands[1]);
3125
3126 case TYPE_SSEMOV:
3127 /* Handle misaligned load/store since we
3128 don't have movmisaligntf pattern. */
3129 if (misaligned_operand (operands[0], TFmode)
3130 || misaligned_operand (operands[1], TFmode))
3131 {
3132 if (get_attr_mode (insn) == MODE_V4SF)
3133 return "%vmovups\t{%1, %0|%0, %1}";
3134 else if (TARGET_AVX512VL
3135 && (EXT_REX_SSE_REG_P (operands[0])
3136 || EXT_REX_SSE_REG_P (operands[1])))
3137 return "vmovdqu64\t{%1, %0|%0, %1}";
3138 else
3139 return "%vmovdqu\t{%1, %0|%0, %1}";
3140 }
3141 else
3142 {
3143 if (get_attr_mode (insn) == MODE_V4SF)
3144 return "%vmovaps\t{%1, %0|%0, %1}";
3145 else if (TARGET_AVX512VL
3146 && (EXT_REX_SSE_REG_P (operands[0])
3147 || EXT_REX_SSE_REG_P (operands[1])))
3148 return "vmovdqa64\t{%1, %0|%0, %1}";
3149 else
3150 return "%vmovdqa\t{%1, %0|%0, %1}";
3151 }
3152
3153 case TYPE_MULTI:
3154 return "#";
3155
3156 default:
3157 gcc_unreachable ();
3158 }
3159 }
3160 [(set_attr "isa" "*,*,*,x64,x64")
3161 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3162 (set (attr "prefix")
3163 (if_then_else (eq_attr "type" "sselog1,ssemov")
3164 (const_string "maybe_vex")
3165 (const_string "orig")))
3166 (set (attr "mode")
3167 (cond [(eq_attr "alternative" "3,4")
3168 (const_string "DI")
3169 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3170 (const_string "V4SF")
3171 (and (eq_attr "alternative" "2")
3172 (match_test "TARGET_SSE_TYPELESS_STORES"))
3173 (const_string "V4SF")
3174 (match_test "TARGET_AVX")
3175 (const_string "TI")
3176 (ior (not (match_test "TARGET_SSE2"))
3177 (match_test "optimize_function_for_size_p (cfun)"))
3178 (const_string "V4SF")
3179 ]
3180 (const_string "TI")))])
3181
3182 (define_split
3183 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3184 (match_operand:TF 1 "general_gr_operand"))]
3185 "reload_completed"
3186 [(const_int 0)]
3187 "ix86_split_long_move (operands); DONE;")
3188
3189 ;; Possible store forwarding (partial memory) stall
3190 ;; in alternatives 4, 6, 7 and 8.
3191 (define_insn "*movxf_internal"
3192 [(set (match_operand:XF 0 "nonimmediate_operand"
3193 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o")
3194 (match_operand:XF 1 "general_operand"
3195 "fm,f,G,roF,r , *roF,*r,F ,C,roF,rF"))]
3196 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3197 && (lra_in_progress || reload_completed
3198 || !CONST_DOUBLE_P (operands[1])
3199 || ((optimize_function_for_size_p (cfun)
3200 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3201 && standard_80387_constant_p (operands[1]) > 0
3202 && !memory_operand (operands[0], XFmode))
3203 || (!TARGET_MEMORY_MISMATCH_STALL
3204 && memory_operand (operands[0], XFmode))
3205 || !TARGET_HARD_XF_REGS)"
3206 {
3207 switch (get_attr_type (insn))
3208 {
3209 case TYPE_FMOV:
3210 if (which_alternative == 2)
3211 return standard_80387_constant_opcode (operands[1]);
3212 return output_387_reg_move (insn, operands);
3213
3214 case TYPE_MULTI:
3215 return "#";
3216
3217 default:
3218 gcc_unreachable ();
3219 }
3220 }
3221 [(set (attr "isa")
3222 (cond [(eq_attr "alternative" "7")
3223 (const_string "nox64")
3224 (eq_attr "alternative" "8")
3225 (const_string "x64")
3226 ]
3227 (const_string "*")))
3228 (set (attr "type")
3229 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3230 (const_string "multi")
3231 ]
3232 (const_string "fmov")))
3233 (set (attr "mode")
3234 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3235 (if_then_else (match_test "TARGET_64BIT")
3236 (const_string "DI")
3237 (const_string "SI"))
3238 ]
3239 (const_string "XF")))
3240 (set (attr "preferred_for_size")
3241 (cond [(eq_attr "alternative" "3,4")
3242 (symbol_ref "false")]
3243 (symbol_ref "true")))
3244 (set (attr "enabled")
3245 (cond [(eq_attr "alternative" "9,10")
3246 (if_then_else
3247 (match_test "TARGET_HARD_XF_REGS")
3248 (symbol_ref "false")
3249 (const_string "*"))
3250 (not (match_test "TARGET_HARD_XF_REGS"))
3251 (symbol_ref "false")
3252 ]
3253 (const_string "*")))])
3254
3255 (define_split
3256 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3257 (match_operand:XF 1 "general_gr_operand"))]
3258 "reload_completed"
3259 [(const_int 0)]
3260 "ix86_split_long_move (operands); DONE;")
3261
3262 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3263 (define_insn "*movdf_internal"
3264 [(set (match_operand:DF 0 "nonimmediate_operand"
3265 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi,r ,o ,r ,m")
3266 (match_operand:DF 1 "general_operand"
3267 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r ,roF,rF,rmF,rC"))]
3268 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3269 && (lra_in_progress || reload_completed
3270 || !CONST_DOUBLE_P (operands[1])
3271 || ((optimize_function_for_size_p (cfun)
3272 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3273 && ((IS_STACK_MODE (DFmode)
3274 && standard_80387_constant_p (operands[1]) > 0)
3275 || (TARGET_SSE2 && TARGET_SSE_MATH
3276 && standard_sse_constant_p (operands[1], DFmode) == 1))
3277 && !memory_operand (operands[0], DFmode))
3278 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3279 && memory_operand (operands[0], DFmode))
3280 || !TARGET_HARD_DF_REGS)"
3281 {
3282 switch (get_attr_type (insn))
3283 {
3284 case TYPE_FMOV:
3285 if (which_alternative == 2)
3286 return standard_80387_constant_opcode (operands[1]);
3287 return output_387_reg_move (insn, operands);
3288
3289 case TYPE_MULTI:
3290 return "#";
3291
3292 case TYPE_IMOV:
3293 if (get_attr_mode (insn) == MODE_SI)
3294 return "mov{l}\t{%1, %k0|%k0, %1}";
3295 else if (which_alternative == 11)
3296 return "movabs{q}\t{%1, %0|%0, %1}";
3297 else
3298 return "mov{q}\t{%1, %0|%0, %1}";
3299
3300 case TYPE_SSELOG1:
3301 return standard_sse_constant_opcode (insn, operands[1]);
3302
3303 case TYPE_SSEMOV:
3304 switch (get_attr_mode (insn))
3305 {
3306 case MODE_DF:
3307 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3308 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3309 return "%vmovsd\t{%1, %0|%0, %1}";
3310
3311 case MODE_V4SF:
3312 return "%vmovaps\t{%1, %0|%0, %1}";
3313 case MODE_V8DF:
3314 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3315 case MODE_V2DF:
3316 return "%vmovapd\t{%1, %0|%0, %1}";
3317
3318 case MODE_V2SF:
3319 gcc_assert (!TARGET_AVX);
3320 return "movlps\t{%1, %0|%0, %1}";
3321 case MODE_V1DF:
3322 gcc_assert (!TARGET_AVX);
3323 return "movlpd\t{%1, %0|%0, %1}";
3324
3325 case MODE_DI:
3326 /* Handle broken assemblers that require movd instead of movq. */
3327 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3328 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3329 return "%vmovd\t{%1, %0|%0, %1}";
3330 return "%vmovq\t{%1, %0|%0, %1}";
3331
3332 default:
3333 gcc_unreachable ();
3334 }
3335
3336 default:
3337 gcc_unreachable ();
3338 }
3339 }
3340 [(set (attr "isa")
3341 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3342 (const_string "nox64")
3343 (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3344 (const_string "x64")
3345 (eq_attr "alternative" "12,13,14,15")
3346 (const_string "sse2")
3347 ]
3348 (const_string "*")))
3349 (set (attr "type")
3350 (cond [(eq_attr "alternative" "0,1,2")
3351 (const_string "fmov")
3352 (eq_attr "alternative" "3,4,5,6,7,22,23")
3353 (const_string "multi")
3354 (eq_attr "alternative" "8,9,10,11,24,25")
3355 (const_string "imov")
3356 (eq_attr "alternative" "12,16")
3357 (const_string "sselog1")
3358 ]
3359 (const_string "ssemov")))
3360 (set (attr "modrm")
3361 (if_then_else (eq_attr "alternative" "11")
3362 (const_string "0")
3363 (const_string "*")))
3364 (set (attr "length_immediate")
3365 (if_then_else (eq_attr "alternative" "11")
3366 (const_string "8")
3367 (const_string "*")))
3368 (set (attr "prefix")
3369 (if_then_else (eq_attr "type" "sselog1,ssemov")
3370 (const_string "maybe_vex")
3371 (const_string "orig")))
3372 (set (attr "prefix_data16")
3373 (if_then_else
3374 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3375 (eq_attr "mode" "V1DF"))
3376 (const_string "1")
3377 (const_string "*")))
3378 (set (attr "mode")
3379 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3380 (const_string "SI")
3381 (eq_attr "alternative" "8,9,11,20,21,24,25")
3382 (const_string "DI")
3383
3384 /* xorps is one byte shorter for non-AVX targets. */
3385 (eq_attr "alternative" "12,16")
3386 (cond [(not (match_test "TARGET_SSE2"))
3387 (const_string "V4SF")
3388 (match_test "TARGET_AVX512F")
3389 (const_string "XI")
3390 (match_test "TARGET_AVX")
3391 (const_string "V2DF")
3392 (match_test "optimize_function_for_size_p (cfun)")
3393 (const_string "V4SF")
3394 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3395 (const_string "TI")
3396 ]
3397 (const_string "V2DF"))
3398
3399 /* For architectures resolving dependencies on
3400 whole SSE registers use movapd to break dependency
3401 chains, otherwise use short move to avoid extra work. */
3402
3403 /* movaps is one byte shorter for non-AVX targets. */
3404 (eq_attr "alternative" "13,17")
3405 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3406 (match_operand 1 "ext_sse_reg_operand"))
3407 (const_string "V8DF")
3408 (ior (not (match_test "TARGET_SSE2"))
3409 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3410 (const_string "V4SF")
3411 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3412 (const_string "V2DF")
3413 (match_test "TARGET_AVX")
3414 (const_string "DF")
3415 (match_test "optimize_function_for_size_p (cfun)")
3416 (const_string "V4SF")
3417 ]
3418 (const_string "DF"))
3419
3420 /* For architectures resolving dependencies on register
3421 parts we may avoid extra work to zero out upper part
3422 of register. */
3423 (eq_attr "alternative" "14,18")
3424 (cond [(not (match_test "TARGET_SSE2"))
3425 (const_string "V2SF")
3426 (match_test "TARGET_AVX")
3427 (const_string "DF")
3428 (match_test "TARGET_SSE_SPLIT_REGS")
3429 (const_string "V1DF")
3430 ]
3431 (const_string "DF"))
3432
3433 (and (eq_attr "alternative" "15,19")
3434 (not (match_test "TARGET_SSE2")))
3435 (const_string "V2SF")
3436 ]
3437 (const_string "DF")))
3438 (set (attr "preferred_for_size")
3439 (cond [(eq_attr "alternative" "3,4")
3440 (symbol_ref "false")]
3441 (symbol_ref "true")))
3442 (set (attr "preferred_for_speed")
3443 (cond [(eq_attr "alternative" "3,4")
3444 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3445 (symbol_ref "true")))
3446 (set (attr "enabled")
3447 (cond [(eq_attr "alternative" "22,23,24,25")
3448 (if_then_else
3449 (match_test "TARGET_HARD_DF_REGS")
3450 (symbol_ref "false")
3451 (const_string "*"))
3452 (not (match_test "TARGET_HARD_DF_REGS"))
3453 (symbol_ref "false")
3454 ]
3455 (const_string "*")))])
3456
3457 (define_split
3458 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3459 (match_operand:DF 1 "general_gr_operand"))]
3460 "!TARGET_64BIT && reload_completed"
3461 [(const_int 0)]
3462 "ix86_split_long_move (operands); DONE;")
3463
3464 (define_insn "*movsf_internal"
3465 [(set (match_operand:SF 0 "nonimmediate_operand"
3466 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r ,m")
3467 (match_operand:SF 1 "general_operand"
3468 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r ,rmF,rF"))]
3469 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3470 && (lra_in_progress || reload_completed
3471 || !CONST_DOUBLE_P (operands[1])
3472 || ((optimize_function_for_size_p (cfun)
3473 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3474 && ((IS_STACK_MODE (SFmode)
3475 && standard_80387_constant_p (operands[1]) > 0)
3476 || (TARGET_SSE && TARGET_SSE_MATH
3477 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3478 || memory_operand (operands[0], SFmode)
3479 || !TARGET_HARD_SF_REGS)"
3480 {
3481 switch (get_attr_type (insn))
3482 {
3483 case TYPE_FMOV:
3484 if (which_alternative == 2)
3485 return standard_80387_constant_opcode (operands[1]);
3486 return output_387_reg_move (insn, operands);
3487
3488 case TYPE_IMOV:
3489 return "mov{l}\t{%1, %0|%0, %1}";
3490
3491 case TYPE_SSELOG1:
3492 return standard_sse_constant_opcode (insn, operands[1]);
3493
3494 case TYPE_SSEMOV:
3495 switch (get_attr_mode (insn))
3496 {
3497 case MODE_SF:
3498 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3499 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3500 return "%vmovss\t{%1, %0|%0, %1}";
3501
3502 case MODE_V16SF:
3503 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3504 case MODE_V4SF:
3505 return "%vmovaps\t{%1, %0|%0, %1}";
3506
3507 case MODE_SI:
3508 return "%vmovd\t{%1, %0|%0, %1}";
3509
3510 default:
3511 gcc_unreachable ();
3512 }
3513
3514 case TYPE_MMXMOV:
3515 switch (get_attr_mode (insn))
3516 {
3517 case MODE_DI:
3518 return "movq\t{%1, %0|%0, %1}";
3519 case MODE_SI:
3520 return "movd\t{%1, %0|%0, %1}";
3521
3522 default:
3523 gcc_unreachable ();
3524 }
3525
3526 default:
3527 gcc_unreachable ();
3528 }
3529 }
3530 [(set (attr "type")
3531 (cond [(eq_attr "alternative" "0,1,2")
3532 (const_string "fmov")
3533 (eq_attr "alternative" "3,4,16,17")
3534 (const_string "imov")
3535 (eq_attr "alternative" "5")
3536 (const_string "sselog1")
3537 (eq_attr "alternative" "11,12,13,14,15")
3538 (const_string "mmxmov")
3539 ]
3540 (const_string "ssemov")))
3541 (set (attr "prefix")
3542 (if_then_else (eq_attr "type" "sselog1,ssemov")
3543 (const_string "maybe_vex")
3544 (const_string "orig")))
3545 (set (attr "prefix_data16")
3546 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3547 (const_string "1")
3548 (const_string "*")))
3549 (set (attr "mode")
3550 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3551 (const_string "SI")
3552 (eq_attr "alternative" "11")
3553 (const_string "DI")
3554 (eq_attr "alternative" "5")
3555 (cond [(not (match_test "TARGET_SSE2"))
3556 (const_string "V4SF")
3557 (match_test "TARGET_AVX512F")
3558 (const_string "V16SF")
3559 (match_test "TARGET_AVX")
3560 (const_string "V4SF")
3561 (match_test "optimize_function_for_size_p (cfun)")
3562 (const_string "V4SF")
3563 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3564 (const_string "TI")
3565 ]
3566 (const_string "V4SF"))
3567
3568 /* For architectures resolving dependencies on
3569 whole SSE registers use APS move to break dependency
3570 chains, otherwise use short move to avoid extra work.
3571
3572 Do the same for architectures resolving dependencies on
3573 the parts. While in DF mode it is better to always handle
3574 just register parts, the SF mode is different due to lack
3575 of instructions to load just part of the register. It is
3576 better to maintain the whole registers in single format
3577 to avoid problems on using packed logical operations. */
3578 (eq_attr "alternative" "6")
3579 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3580 (match_operand 1 "ext_sse_reg_operand"))
3581 (const_string "V16SF")
3582 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3583 (match_test "TARGET_SSE_SPLIT_REGS"))
3584 (const_string "V4SF")
3585 ]
3586 (const_string "SF"))
3587 ]
3588 (const_string "SF")))
3589 (set (attr "enabled")
3590 (cond [(eq_attr "alternative" "16,17")
3591 (if_then_else
3592 (match_test "TARGET_HARD_SF_REGS")
3593 (symbol_ref "false")
3594 (const_string "*"))
3595 (not (match_test "TARGET_HARD_SF_REGS"))
3596 (symbol_ref "false")
3597 ]
3598 (const_string "*")))])
3599
3600 (define_split
3601 [(set (match_operand 0 "any_fp_register_operand")
3602 (match_operand 1 "memory_operand"))]
3603 "reload_completed
3604 && (GET_MODE (operands[0]) == TFmode
3605 || GET_MODE (operands[0]) == XFmode
3606 || GET_MODE (operands[0]) == DFmode
3607 || GET_MODE (operands[0]) == SFmode)
3608 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3609 [(set (match_dup 0) (match_dup 2))]
3610 "operands[2] = find_constant_src (curr_insn);")
3611
3612 (define_split
3613 [(set (match_operand 0 "any_fp_register_operand")
3614 (float_extend (match_operand 1 "memory_operand")))]
3615 "reload_completed
3616 && (GET_MODE (operands[0]) == TFmode
3617 || GET_MODE (operands[0]) == XFmode
3618 || GET_MODE (operands[0]) == DFmode)
3619 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3620 [(set (match_dup 0) (match_dup 2))]
3621 "operands[2] = find_constant_src (curr_insn);")
3622
3623 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3624 (define_split
3625 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3626 (match_operand:X87MODEF 1 "immediate_operand"))]
3627 "reload_completed
3628 && (standard_80387_constant_p (operands[1]) == 8
3629 || standard_80387_constant_p (operands[1]) == 9)"
3630 [(set (match_dup 0)(match_dup 1))
3631 (set (match_dup 0)
3632 (neg:X87MODEF (match_dup 0)))]
3633 {
3634 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3635 operands[1] = CONST0_RTX (<MODE>mode);
3636 else
3637 operands[1] = CONST1_RTX (<MODE>mode);
3638 })
3639
3640 (define_insn "swapxf"
3641 [(set (match_operand:XF 0 "register_operand" "+f")
3642 (match_operand:XF 1 "register_operand" "+f"))
3643 (set (match_dup 1)
3644 (match_dup 0))]
3645 "TARGET_80387"
3646 {
3647 if (STACK_TOP_P (operands[0]))
3648 return "fxch\t%1";
3649 else
3650 return "fxch\t%0";
3651 }
3652 [(set_attr "type" "fxch")
3653 (set_attr "mode" "XF")])
3654
3655 (define_insn "*swap<mode>"
3656 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3657 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3658 (set (match_dup 1)
3659 (match_dup 0))]
3660 "TARGET_80387 || reload_completed"
3661 {
3662 if (STACK_TOP_P (operands[0]))
3663 return "fxch\t%1";
3664 else
3665 return "fxch\t%0";
3666 }
3667 [(set_attr "type" "fxch")
3668 (set_attr "mode" "<MODE>")])
3669 \f
3670 ;; Zero extension instructions
3671
3672 (define_expand "zero_extendsidi2"
3673 [(set (match_operand:DI 0 "nonimmediate_operand")
3674 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3675
3676 (define_insn "*zero_extendsidi2"
3677 [(set (match_operand:DI 0 "nonimmediate_operand"
3678 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x,*r")
3679 (zero_extend:DI
3680 (match_operand:SI 1 "x86_64_zext_operand"
3681 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m ,*k")))]
3682 ""
3683 {
3684 switch (get_attr_type (insn))
3685 {
3686 case TYPE_IMOVX:
3687 if (ix86_use_lea_for_mov (insn, operands))
3688 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3689 else
3690 return "mov{l}\t{%1, %k0|%k0, %1}";
3691
3692 case TYPE_MULTI:
3693 return "#";
3694
3695 case TYPE_MMXMOV:
3696 return "movd\t{%1, %0|%0, %1}";
3697
3698 case TYPE_SSELOG1:
3699 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3700
3701 case TYPE_SSEMOV:
3702 if (GENERAL_REG_P (operands[0]))
3703 return "%vmovd\t{%1, %k0|%k0, %1}";
3704
3705 return "%vmovd\t{%1, %0|%0, %1}";
3706
3707 case TYPE_MSKMOV:
3708 return "kmovd\t{%1, %k0|%k0, %1}";
3709
3710 default:
3711 gcc_unreachable ();
3712 }
3713 }
3714 [(set (attr "isa")
3715 (cond [(eq_attr "alternative" "0,1,2")
3716 (const_string "nox64")
3717 (eq_attr "alternative" "3,7")
3718 (const_string "x64")
3719 (eq_attr "alternative" "8")
3720 (const_string "x64_sse4")
3721 (eq_attr "alternative" "10")
3722 (const_string "sse2")
3723 (eq_attr "alternative" "11")
3724 (const_string "x64_avx512bw")
3725 ]
3726 (const_string "*")))
3727 (set (attr "type")
3728 (cond [(eq_attr "alternative" "0,1,2,4")
3729 (const_string "multi")
3730 (eq_attr "alternative" "5,6")
3731 (const_string "mmxmov")
3732 (eq_attr "alternative" "7,9,10")
3733 (const_string "ssemov")
3734 (eq_attr "alternative" "8")
3735 (const_string "sselog1")
3736 (eq_attr "alternative" "11")
3737 (const_string "mskmov")
3738 ]
3739 (const_string "imovx")))
3740 (set (attr "prefix_extra")
3741 (if_then_else (eq_attr "alternative" "8")
3742 (const_string "1")
3743 (const_string "*")))
3744 (set (attr "length_immediate")
3745 (if_then_else (eq_attr "alternative" "8")
3746 (const_string "1")
3747 (const_string "*")))
3748 (set (attr "prefix")
3749 (if_then_else (eq_attr "type" "ssemov,sselog1")
3750 (const_string "maybe_vex")
3751 (const_string "orig")))
3752 (set (attr "prefix_0f")
3753 (if_then_else (eq_attr "type" "imovx")
3754 (const_string "0")
3755 (const_string "*")))
3756 (set (attr "mode")
3757 (cond [(eq_attr "alternative" "5,6")
3758 (const_string "DI")
3759 (eq_attr "alternative" "7,8,9")
3760 (const_string "TI")
3761 ]
3762 (const_string "SI")))])
3763
3764 (define_split
3765 [(set (match_operand:DI 0 "memory_operand")
3766 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3767 "reload_completed"
3768 [(set (match_dup 4) (const_int 0))]
3769 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3770
3771 (define_split
3772 [(set (match_operand:DI 0 "general_reg_operand")
3773 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3774 "!TARGET_64BIT && reload_completed
3775 && REGNO (operands[0]) == REGNO (operands[1])"
3776 [(set (match_dup 4) (const_int 0))]
3777 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3778
3779 (define_split
3780 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3781 (zero_extend:DI (match_operand:SI 1 "nonimmediate_gr_operand")))]
3782 "!TARGET_64BIT && reload_completed
3783 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3784 [(set (match_dup 3) (match_dup 1))
3785 (set (match_dup 4) (const_int 0))]
3786 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3787
3788 (define_mode_attr kmov_isa
3789 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3790
3791 (define_insn "zero_extend<mode>di2"
3792 [(set (match_operand:DI 0 "register_operand" "=r,*r")
3793 (zero_extend:DI
3794 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3795 "TARGET_64BIT"
3796 "@
3797 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3798 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3799 [(set_attr "isa" "*,<kmov_isa>")
3800 (set_attr "type" "imovx,mskmov")
3801 (set_attr "mode" "SI,<MODE>")])
3802
3803 (define_expand "zero_extend<mode>si2"
3804 [(set (match_operand:SI 0 "register_operand")
3805 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3806 ""
3807 {
3808 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3809 {
3810 operands[1] = force_reg (<MODE>mode, operands[1]);
3811 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3812 DONE;
3813 }
3814 })
3815
3816 (define_insn_and_split "zero_extend<mode>si2_and"
3817 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3818 (zero_extend:SI
3819 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3820 (clobber (reg:CC FLAGS_REG))]
3821 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3822 "#"
3823 "&& reload_completed"
3824 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3825 (clobber (reg:CC FLAGS_REG))])]
3826 {
3827 if (!REG_P (operands[1])
3828 || REGNO (operands[0]) != REGNO (operands[1]))
3829 {
3830 ix86_expand_clear (operands[0]);
3831
3832 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3833 emit_insn (gen_movstrict<mode>
3834 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3835 DONE;
3836 }
3837
3838 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3839 }
3840 [(set_attr "type" "alu1")
3841 (set_attr "mode" "SI")])
3842
3843 (define_insn "*zero_extend<mode>si2"
3844 [(set (match_operand:SI 0 "register_operand" "=r,*r")
3845 (zero_extend:SI
3846 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3847 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3848 "@
3849 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
3850 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
3851 [(set_attr "isa" "*,<kmov_isa>")
3852 (set_attr "type" "imovx,mskmov")
3853 (set_attr "mode" "SI,<MODE>")])
3854
3855 (define_expand "zero_extendqihi2"
3856 [(set (match_operand:HI 0 "register_operand")
3857 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3858 ""
3859 {
3860 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3861 {
3862 operands[1] = force_reg (QImode, operands[1]);
3863 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3864 DONE;
3865 }
3866 })
3867
3868 (define_insn_and_split "zero_extendqihi2_and"
3869 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3870 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3871 (clobber (reg:CC FLAGS_REG))]
3872 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3873 "#"
3874 "&& reload_completed"
3875 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3876 (clobber (reg:CC FLAGS_REG))])]
3877 {
3878 if (!REG_P (operands[1])
3879 || REGNO (operands[0]) != REGNO (operands[1]))
3880 {
3881 ix86_expand_clear (operands[0]);
3882
3883 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3884 emit_insn (gen_movstrictqi
3885 (gen_lowpart (QImode, operands[0]), operands[1]));
3886 DONE;
3887 }
3888
3889 operands[0] = gen_lowpart (SImode, operands[0]);
3890 }
3891 [(set_attr "type" "alu1")
3892 (set_attr "mode" "SI")])
3893
3894 ; zero extend to SImode to avoid partial register stalls
3895 (define_insn "*zero_extendqihi2"
3896 [(set (match_operand:HI 0 "register_operand" "=r,*r")
3897 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
3898 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3899 "@
3900 movz{bl|x}\t{%1, %k0|%k0, %1}
3901 kmovb\t{%1, %k0|%k0, %1}"
3902 [(set_attr "isa" "*,avx512dq")
3903 (set_attr "type" "imovx,mskmov")
3904 (set_attr "mode" "SI,QI")])
3905
3906 (define_insn_and_split "*zext<mode>_doubleword_and"
3907 [(set (match_operand:DI 0 "register_operand" "=&<r>")
3908 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3909 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3910 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3911 "#"
3912 "&& reload_completed && GENERAL_REG_P (operands[0])"
3913 [(set (match_dup 2) (const_int 0))]
3914 {
3915 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
3916
3917 emit_move_insn (operands[0], const0_rtx);
3918
3919 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3920 emit_insn (gen_movstrict<mode>
3921 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3922 })
3923
3924 (define_insn_and_split "*zext<mode>_doubleword"
3925 [(set (match_operand:DI 0 "register_operand" "=r")
3926 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3927 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3928 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3929 "#"
3930 "&& reload_completed && GENERAL_REG_P (operands[0])"
3931 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
3932 (set (match_dup 2) (const_int 0))]
3933 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3934
3935 (define_insn_and_split "*zextsi_doubleword"
3936 [(set (match_operand:DI 0 "register_operand" "=r")
3937 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3938 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
3939 "#"
3940 "&& reload_completed && GENERAL_REG_P (operands[0])"
3941 [(set (match_dup 0) (match_dup 1))
3942 (set (match_dup 2) (const_int 0))]
3943 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3944 \f
3945 ;; Sign extension instructions
3946
3947 (define_expand "extendsidi2"
3948 [(set (match_operand:DI 0 "register_operand")
3949 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3950 ""
3951 {
3952 if (!TARGET_64BIT)
3953 {
3954 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3955 DONE;
3956 }
3957 })
3958
3959 (define_insn "*extendsidi2_rex64"
3960 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3961 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3962 "TARGET_64BIT"
3963 "@
3964 {cltq|cdqe}
3965 movs{lq|x}\t{%1, %0|%0, %1}"
3966 [(set_attr "type" "imovx")
3967 (set_attr "mode" "DI")
3968 (set_attr "prefix_0f" "0")
3969 (set_attr "modrm" "0,1")])
3970
3971 (define_insn "extendsidi2_1"
3972 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3973 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3974 (clobber (reg:CC FLAGS_REG))
3975 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3976 "!TARGET_64BIT"
3977 "#")
3978
3979 ;; Split the memory case. If the source register doesn't die, it will stay
3980 ;; this way, if it does die, following peephole2s take care of it.
3981 (define_split
3982 [(set (match_operand:DI 0 "memory_operand")
3983 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3984 (clobber (reg:CC FLAGS_REG))
3985 (clobber (match_operand:SI 2 "register_operand"))]
3986 "reload_completed"
3987 [(const_int 0)]
3988 {
3989 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3990
3991 emit_move_insn (operands[3], operands[1]);
3992
3993 /* Generate a cltd if possible and doing so it profitable. */
3994 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3995 && REGNO (operands[1]) == AX_REG
3996 && REGNO (operands[2]) == DX_REG)
3997 {
3998 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3999 }
4000 else
4001 {
4002 emit_move_insn (operands[2], operands[1]);
4003 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4004 }
4005 emit_move_insn (operands[4], operands[2]);
4006 DONE;
4007 })
4008
4009 ;; Peepholes for the case where the source register does die, after
4010 ;; being split with the above splitter.
4011 (define_peephole2
4012 [(set (match_operand:SI 0 "memory_operand")
4013 (match_operand:SI 1 "general_reg_operand"))
4014 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4015 (parallel [(set (match_dup 2)
4016 (ashiftrt:SI (match_dup 2) (const_int 31)))
4017 (clobber (reg:CC FLAGS_REG))])
4018 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4019 "REGNO (operands[1]) != REGNO (operands[2])
4020 && peep2_reg_dead_p (2, operands[1])
4021 && peep2_reg_dead_p (4, operands[2])
4022 && !reg_mentioned_p (operands[2], operands[3])"
4023 [(set (match_dup 0) (match_dup 1))
4024 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4025 (clobber (reg:CC FLAGS_REG))])
4026 (set (match_dup 3) (match_dup 1))])
4027
4028 (define_peephole2
4029 [(set (match_operand:SI 0 "memory_operand")
4030 (match_operand:SI 1 "general_reg_operand"))
4031 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4032 (ashiftrt:SI (match_dup 1) (const_int 31)))
4033 (clobber (reg:CC FLAGS_REG))])
4034 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4035 "/* cltd is shorter than sarl $31, %eax */
4036 !optimize_function_for_size_p (cfun)
4037 && REGNO (operands[1]) == AX_REG
4038 && REGNO (operands[2]) == DX_REG
4039 && peep2_reg_dead_p (2, operands[1])
4040 && peep2_reg_dead_p (3, operands[2])
4041 && !reg_mentioned_p (operands[2], operands[3])"
4042 [(set (match_dup 0) (match_dup 1))
4043 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4044 (clobber (reg:CC FLAGS_REG))])
4045 (set (match_dup 3) (match_dup 1))])
4046
4047 ;; Extend to register case. Optimize case where source and destination
4048 ;; registers match and cases where we can use cltd.
4049 (define_split
4050 [(set (match_operand:DI 0 "register_operand")
4051 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4052 (clobber (reg:CC FLAGS_REG))
4053 (clobber (match_scratch:SI 2))]
4054 "reload_completed"
4055 [(const_int 0)]
4056 {
4057 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4058
4059 if (REGNO (operands[3]) != REGNO (operands[1]))
4060 emit_move_insn (operands[3], operands[1]);
4061
4062 /* Generate a cltd if possible and doing so it profitable. */
4063 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4064 && REGNO (operands[3]) == AX_REG
4065 && REGNO (operands[4]) == DX_REG)
4066 {
4067 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4068 DONE;
4069 }
4070
4071 if (REGNO (operands[4]) != REGNO (operands[1]))
4072 emit_move_insn (operands[4], operands[1]);
4073
4074 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4075 DONE;
4076 })
4077
4078 (define_insn "extend<mode>di2"
4079 [(set (match_operand:DI 0 "register_operand" "=r")
4080 (sign_extend:DI
4081 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4082 "TARGET_64BIT"
4083 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4084 [(set_attr "type" "imovx")
4085 (set_attr "mode" "DI")])
4086
4087 (define_insn "extendhisi2"
4088 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4089 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4090 ""
4091 {
4092 switch (get_attr_prefix_0f (insn))
4093 {
4094 case 0:
4095 return "{cwtl|cwde}";
4096 default:
4097 return "movs{wl|x}\t{%1, %0|%0, %1}";
4098 }
4099 }
4100 [(set_attr "type" "imovx")
4101 (set_attr "mode" "SI")
4102 (set (attr "prefix_0f")
4103 ;; movsx is short decodable while cwtl is vector decoded.
4104 (if_then_else (and (eq_attr "cpu" "!k6")
4105 (eq_attr "alternative" "0"))
4106 (const_string "0")
4107 (const_string "1")))
4108 (set (attr "znver1_decode")
4109 (if_then_else (eq_attr "prefix_0f" "0")
4110 (const_string "double")
4111 (const_string "direct")))
4112 (set (attr "modrm")
4113 (if_then_else (eq_attr "prefix_0f" "0")
4114 (const_string "0")
4115 (const_string "1")))])
4116
4117 (define_insn "*extendhisi2_zext"
4118 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4119 (zero_extend:DI
4120 (sign_extend:SI
4121 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4122 "TARGET_64BIT"
4123 {
4124 switch (get_attr_prefix_0f (insn))
4125 {
4126 case 0:
4127 return "{cwtl|cwde}";
4128 default:
4129 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4130 }
4131 }
4132 [(set_attr "type" "imovx")
4133 (set_attr "mode" "SI")
4134 (set (attr "prefix_0f")
4135 ;; movsx is short decodable while cwtl is vector decoded.
4136 (if_then_else (and (eq_attr "cpu" "!k6")
4137 (eq_attr "alternative" "0"))
4138 (const_string "0")
4139 (const_string "1")))
4140 (set (attr "modrm")
4141 (if_then_else (eq_attr "prefix_0f" "0")
4142 (const_string "0")
4143 (const_string "1")))])
4144
4145 (define_insn "extendqisi2"
4146 [(set (match_operand:SI 0 "register_operand" "=r")
4147 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4148 ""
4149 "movs{bl|x}\t{%1, %0|%0, %1}"
4150 [(set_attr "type" "imovx")
4151 (set_attr "mode" "SI")])
4152
4153 (define_insn "*extendqisi2_zext"
4154 [(set (match_operand:DI 0 "register_operand" "=r")
4155 (zero_extend:DI
4156 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4157 "TARGET_64BIT"
4158 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4159 [(set_attr "type" "imovx")
4160 (set_attr "mode" "SI")])
4161
4162 (define_insn "extendqihi2"
4163 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4164 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4165 ""
4166 {
4167 switch (get_attr_prefix_0f (insn))
4168 {
4169 case 0:
4170 return "{cbtw|cbw}";
4171 default:
4172 return "movs{bw|x}\t{%1, %0|%0, %1}";
4173 }
4174 }
4175 [(set_attr "type" "imovx")
4176 (set_attr "mode" "HI")
4177 (set (attr "prefix_0f")
4178 ;; movsx is short decodable while cwtl is vector decoded.
4179 (if_then_else (and (eq_attr "cpu" "!k6")
4180 (eq_attr "alternative" "0"))
4181 (const_string "0")
4182 (const_string "1")))
4183 (set (attr "modrm")
4184 (if_then_else (eq_attr "prefix_0f" "0")
4185 (const_string "0")
4186 (const_string "1")))])
4187 \f
4188 ;; Conversions between float and double.
4189
4190 ;; These are all no-ops in the model used for the 80387.
4191 ;; So just emit moves.
4192
4193 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4194 (define_split
4195 [(set (match_operand:DF 0 "push_operand")
4196 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4197 "reload_completed"
4198 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4199 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4200
4201 (define_split
4202 [(set (match_operand:XF 0 "push_operand")
4203 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4204 "reload_completed"
4205 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4206 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4207 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4208
4209 (define_expand "extendsfdf2"
4210 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4211 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4212 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4213 {
4214 /* ??? Needed for compress_float_constant since all fp constants
4215 are TARGET_LEGITIMATE_CONSTANT_P. */
4216 if (CONST_DOUBLE_P (operands[1]))
4217 {
4218 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4219 && standard_80387_constant_p (operands[1]) > 0)
4220 {
4221 operands[1] = simplify_const_unary_operation
4222 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4223 emit_move_insn_1 (operands[0], operands[1]);
4224 DONE;
4225 }
4226 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4227 }
4228 })
4229
4230 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4231 cvtss2sd:
4232 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4233 cvtps2pd xmm2,xmm1
4234 We do the conversion post reload to avoid producing of 128bit spills
4235 that might lead to ICE on 32bit target. The sequence unlikely combine
4236 anyway. */
4237 (define_split
4238 [(set (match_operand:DF 0 "sse_reg_operand")
4239 (float_extend:DF
4240 (match_operand:SF 1 "nonimmediate_operand")))]
4241 "TARGET_USE_VECTOR_FP_CONVERTS
4242 && optimize_insn_for_speed_p ()
4243 && reload_completed
4244 && (!EXT_REX_SSE_REG_P (operands[0])
4245 || TARGET_AVX512VL)"
4246 [(set (match_dup 2)
4247 (float_extend:V2DF
4248 (vec_select:V2SF
4249 (match_dup 3)
4250 (parallel [(const_int 0) (const_int 1)]))))]
4251 {
4252 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4253 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4254 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4255 Try to avoid move when unpacking can be done in source. */
4256 if (REG_P (operands[1]))
4257 {
4258 /* If it is unsafe to overwrite upper half of source, we need
4259 to move to destination and unpack there. */
4260 if (REGNO (operands[0]) != REGNO (operands[1])
4261 || (EXT_REX_SSE_REG_P (operands[1])
4262 && !TARGET_AVX512VL))
4263 {
4264 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4265 emit_move_insn (tmp, operands[1]);
4266 }
4267 else
4268 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4269 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4270 =v, v, then vbroadcastss will be only needed for AVX512F without
4271 AVX512VL. */
4272 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4273 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4274 operands[3]));
4275 else
4276 {
4277 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4278 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4279 }
4280 }
4281 else
4282 emit_insn (gen_vec_setv4sf_0 (operands[3],
4283 CONST0_RTX (V4SFmode), operands[1]));
4284 })
4285
4286 ;; It's more profitable to split and then extend in the same register.
4287 (define_peephole2
4288 [(set (match_operand:DF 0 "sse_reg_operand")
4289 (float_extend:DF
4290 (match_operand:SF 1 "memory_operand")))]
4291 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4292 && optimize_insn_for_speed_p ()"
4293 [(set (match_dup 2) (match_dup 1))
4294 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4295 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4296
4297 (define_insn "*extendsfdf2"
4298 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4299 (float_extend:DF
4300 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4301 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4302 {
4303 switch (which_alternative)
4304 {
4305 case 0:
4306 case 1:
4307 return output_387_reg_move (insn, operands);
4308
4309 case 2:
4310 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4311
4312 default:
4313 gcc_unreachable ();
4314 }
4315 }
4316 [(set_attr "type" "fmov,fmov,ssecvt")
4317 (set_attr "prefix" "orig,orig,maybe_vex")
4318 (set_attr "mode" "SF,XF,DF")
4319 (set (attr "enabled")
4320 (if_then_else
4321 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4322 (if_then_else
4323 (eq_attr "alternative" "0,1")
4324 (symbol_ref "TARGET_MIX_SSE_I387")
4325 (symbol_ref "true"))
4326 (if_then_else
4327 (eq_attr "alternative" "0,1")
4328 (symbol_ref "true")
4329 (symbol_ref "false"))))])
4330
4331 (define_expand "extend<mode>xf2"
4332 [(set (match_operand:XF 0 "nonimmediate_operand")
4333 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4334 "TARGET_80387"
4335 {
4336 /* ??? Needed for compress_float_constant since all fp constants
4337 are TARGET_LEGITIMATE_CONSTANT_P. */
4338 if (CONST_DOUBLE_P (operands[1]))
4339 {
4340 if (standard_80387_constant_p (operands[1]) > 0)
4341 {
4342 operands[1] = simplify_const_unary_operation
4343 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4344 emit_move_insn_1 (operands[0], operands[1]);
4345 DONE;
4346 }
4347 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4348 }
4349 })
4350
4351 (define_insn "*extend<mode>xf2_i387"
4352 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4353 (float_extend:XF
4354 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4355 "TARGET_80387"
4356 "* return output_387_reg_move (insn, operands);"
4357 [(set_attr "type" "fmov")
4358 (set_attr "mode" "<MODE>,XF")])
4359
4360 ;; %%% This seems like bad news.
4361 ;; This cannot output into an f-reg because there is no way to be sure
4362 ;; of truncating in that case. Otherwise this is just like a simple move
4363 ;; insn. So we pretend we can output to a reg in order to get better
4364 ;; register preferencing, but we really use a stack slot.
4365
4366 ;; Conversion from DFmode to SFmode.
4367
4368 (define_expand "truncdfsf2"
4369 [(set (match_operand:SF 0 "nonimmediate_operand")
4370 (float_truncate:SF
4371 (match_operand:DF 1 "nonimmediate_operand")))]
4372 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4373 {
4374 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4375 ;
4376 else if (flag_unsafe_math_optimizations)
4377 ;
4378 else
4379 {
4380 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4381 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4382 DONE;
4383 }
4384 })
4385
4386 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4387 cvtsd2ss:
4388 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4389 cvtpd2ps xmm2,xmm1
4390 We do the conversion post reload to avoid producing of 128bit spills
4391 that might lead to ICE on 32bit target. The sequence unlikely combine
4392 anyway. */
4393 (define_split
4394 [(set (match_operand:SF 0 "sse_reg_operand")
4395 (float_truncate:SF
4396 (match_operand:DF 1 "nonimmediate_operand")))]
4397 "TARGET_USE_VECTOR_FP_CONVERTS
4398 && optimize_insn_for_speed_p ()
4399 && reload_completed
4400 && (!EXT_REX_SSE_REG_P (operands[0])
4401 || TARGET_AVX512VL)"
4402 [(set (match_dup 2)
4403 (vec_concat:V4SF
4404 (float_truncate:V2SF
4405 (match_dup 4))
4406 (match_dup 3)))]
4407 {
4408 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4409 operands[3] = CONST0_RTX (V2SFmode);
4410 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4411 /* Use movsd for loading from memory, unpcklpd for registers.
4412 Try to avoid move when unpacking can be done in source, or SSE3
4413 movddup is available. */
4414 if (REG_P (operands[1]))
4415 {
4416 if (!TARGET_SSE3
4417 && REGNO (operands[0]) != REGNO (operands[1]))
4418 {
4419 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4420 emit_move_insn (tmp, operands[1]);
4421 operands[1] = tmp;
4422 }
4423 else if (!TARGET_SSE3)
4424 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4425 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4426 }
4427 else
4428 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4429 CONST0_RTX (DFmode)));
4430 })
4431
4432 ;; It's more profitable to split and then extend in the same register.
4433 (define_peephole2
4434 [(set (match_operand:SF 0 "sse_reg_operand")
4435 (float_truncate:SF
4436 (match_operand:DF 1 "memory_operand")))]
4437 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4438 && optimize_insn_for_speed_p ()"
4439 [(set (match_dup 2) (match_dup 1))
4440 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4441 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4442
4443 (define_expand "truncdfsf2_with_temp"
4444 [(parallel [(set (match_operand:SF 0)
4445 (float_truncate:SF (match_operand:DF 1)))
4446 (clobber (match_operand:SF 2))])])
4447
4448 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4449 ;; because nothing we do there is unsafe.
4450 (define_insn "*truncdfsf_fast_mixed"
4451 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4452 (float_truncate:SF
4453 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4454 "TARGET_SSE2 && TARGET_SSE_MATH"
4455 {
4456 switch (which_alternative)
4457 {
4458 case 0:
4459 return output_387_reg_move (insn, operands);
4460 case 1:
4461 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4462 default:
4463 gcc_unreachable ();
4464 }
4465 }
4466 [(set_attr "type" "fmov,ssecvt")
4467 (set_attr "prefix" "orig,maybe_vex")
4468 (set_attr "mode" "SF")
4469 (set (attr "enabled")
4470 (cond [(eq_attr "alternative" "0")
4471 (symbol_ref "TARGET_MIX_SSE_I387
4472 && flag_unsafe_math_optimizations")
4473 ]
4474 (symbol_ref "true")))])
4475
4476 (define_insn "*truncdfsf_fast_i387"
4477 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4478 (float_truncate:SF
4479 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4480 "TARGET_80387 && flag_unsafe_math_optimizations"
4481 "* return output_387_reg_move (insn, operands);"
4482 [(set_attr "type" "fmov")
4483 (set_attr "mode" "SF")])
4484
4485 (define_insn "*truncdfsf_mixed"
4486 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
4487 (float_truncate:SF
4488 (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4489 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4490 "TARGET_MIX_SSE_I387"
4491 {
4492 switch (which_alternative)
4493 {
4494 case 0:
4495 return output_387_reg_move (insn, operands);
4496 case 1:
4497 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4498
4499 default:
4500 return "#";
4501 }
4502 }
4503 [(set_attr "isa" "*,sse2,*,*,*")
4504 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4505 (set_attr "unit" "*,*,i387,i387,i387")
4506 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4507 (set_attr "mode" "SF")])
4508
4509 (define_insn "*truncdfsf_i387"
4510 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4511 (float_truncate:SF
4512 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4513 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4514 "TARGET_80387"
4515 {
4516 switch (which_alternative)
4517 {
4518 case 0:
4519 return output_387_reg_move (insn, operands);
4520
4521 default:
4522 return "#";
4523 }
4524 }
4525 [(set_attr "type" "fmov,multi,multi,multi")
4526 (set_attr "unit" "*,i387,i387,i387")
4527 (set_attr "mode" "SF")])
4528
4529 (define_insn "*truncdfsf2_i387_1"
4530 [(set (match_operand:SF 0 "memory_operand" "=m")
4531 (float_truncate:SF
4532 (match_operand:DF 1 "register_operand" "f")))]
4533 "TARGET_80387
4534 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4535 && !TARGET_MIX_SSE_I387"
4536 "* return output_387_reg_move (insn, operands);"
4537 [(set_attr "type" "fmov")
4538 (set_attr "mode" "SF")])
4539
4540 (define_split
4541 [(set (match_operand:SF 0 "register_operand")
4542 (float_truncate:SF
4543 (match_operand:DF 1 "fp_register_operand")))
4544 (clobber (match_operand 2))]
4545 "reload_completed"
4546 [(set (match_dup 2) (match_dup 1))
4547 (set (match_dup 0) (match_dup 2))]
4548 "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4549
4550 ;; Conversion from XFmode to {SF,DF}mode
4551
4552 (define_expand "truncxf<mode>2"
4553 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4554 (float_truncate:MODEF
4555 (match_operand:XF 1 "register_operand")))
4556 (clobber (match_dup 2))])]
4557 "TARGET_80387"
4558 {
4559 if (flag_unsafe_math_optimizations)
4560 {
4561 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4562 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4563 if (reg != operands[0])
4564 emit_move_insn (operands[0], reg);
4565 DONE;
4566 }
4567 else
4568 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4569 })
4570
4571 (define_insn "*truncxfsf2_mixed"
4572 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4573 (float_truncate:SF
4574 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4575 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4576 "TARGET_80387"
4577 {
4578 gcc_assert (!which_alternative);
4579 return output_387_reg_move (insn, operands);
4580 }
4581 [(set_attr "type" "fmov,multi,multi,multi")
4582 (set_attr "unit" "*,i387,i387,i387")
4583 (set_attr "mode" "SF")])
4584
4585 (define_insn "*truncxfdf2_mixed"
4586 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4587 (float_truncate:DF
4588 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4589 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4590 "TARGET_80387"
4591 {
4592 gcc_assert (!which_alternative);
4593 return output_387_reg_move (insn, operands);
4594 }
4595 [(set_attr "isa" "*,*,sse2,*")
4596 (set_attr "type" "fmov,multi,multi,multi")
4597 (set_attr "unit" "*,i387,i387,i387")
4598 (set_attr "mode" "DF")])
4599
4600 (define_insn "truncxf<mode>2_i387_noop"
4601 [(set (match_operand:MODEF 0 "register_operand" "=f")
4602 (float_truncate:MODEF
4603 (match_operand:XF 1 "register_operand" "f")))]
4604 "TARGET_80387 && flag_unsafe_math_optimizations"
4605 "* return output_387_reg_move (insn, operands);"
4606 [(set_attr "type" "fmov")
4607 (set_attr "mode" "<MODE>")])
4608
4609 (define_insn "*truncxf<mode>2_i387"
4610 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4611 (float_truncate:MODEF
4612 (match_operand:XF 1 "register_operand" "f")))]
4613 "TARGET_80387"
4614 "* return output_387_reg_move (insn, operands);"
4615 [(set_attr "type" "fmov")
4616 (set_attr "mode" "<MODE>")])
4617
4618 (define_split
4619 [(set (match_operand:MODEF 0 "register_operand")
4620 (float_truncate:MODEF
4621 (match_operand:XF 1 "register_operand")))
4622 (clobber (match_operand:MODEF 2 "memory_operand"))]
4623 "TARGET_80387 && reload_completed"
4624 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4625 (set (match_dup 0) (match_dup 2))])
4626
4627 (define_split
4628 [(set (match_operand:MODEF 0 "memory_operand")
4629 (float_truncate:MODEF
4630 (match_operand:XF 1 "register_operand")))
4631 (clobber (match_operand:MODEF 2 "memory_operand"))]
4632 "TARGET_80387"
4633 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4634 \f
4635 ;; Signed conversion to DImode.
4636
4637 (define_expand "fix_truncxfdi2"
4638 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4639 (fix:DI (match_operand:XF 1 "register_operand")))
4640 (clobber (reg:CC FLAGS_REG))])]
4641 "TARGET_80387"
4642 {
4643 if (TARGET_FISTTP)
4644 {
4645 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4646 DONE;
4647 }
4648 })
4649
4650 (define_expand "fix_trunc<mode>di2"
4651 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4652 (fix:DI (match_operand:MODEF 1 "register_operand")))
4653 (clobber (reg:CC FLAGS_REG))])]
4654 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4655 {
4656 if (TARGET_FISTTP
4657 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4658 {
4659 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4660 DONE;
4661 }
4662 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4663 {
4664 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4665 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4666 if (out != operands[0])
4667 emit_move_insn (operands[0], out);
4668 DONE;
4669 }
4670 })
4671
4672 ;; Signed conversion to SImode.
4673
4674 (define_expand "fix_truncxfsi2"
4675 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4676 (fix:SI (match_operand:XF 1 "register_operand")))
4677 (clobber (reg:CC FLAGS_REG))])]
4678 "TARGET_80387"
4679 {
4680 if (TARGET_FISTTP)
4681 {
4682 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4683 DONE;
4684 }
4685 })
4686
4687 (define_expand "fix_trunc<mode>si2"
4688 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4689 (fix:SI (match_operand:MODEF 1 "register_operand")))
4690 (clobber (reg:CC FLAGS_REG))])]
4691 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4692 {
4693 if (TARGET_FISTTP
4694 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4695 {
4696 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4697 DONE;
4698 }
4699 if (SSE_FLOAT_MODE_P (<MODE>mode))
4700 {
4701 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4702 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4703 if (out != operands[0])
4704 emit_move_insn (operands[0], out);
4705 DONE;
4706 }
4707 })
4708
4709 ;; Signed conversion to HImode.
4710
4711 (define_expand "fix_trunc<mode>hi2"
4712 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4713 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4714 (clobber (reg:CC FLAGS_REG))])]
4715 "TARGET_80387
4716 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4717 {
4718 if (TARGET_FISTTP)
4719 {
4720 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4721 DONE;
4722 }
4723 })
4724
4725 ;; Unsigned conversion to SImode.
4726
4727 (define_expand "fixuns_trunc<mode>si2"
4728 [(parallel
4729 [(set (match_operand:SI 0 "register_operand")
4730 (unsigned_fix:SI
4731 (match_operand:MODEF 1 "nonimmediate_operand")))
4732 (use (match_dup 2))
4733 (clobber (match_scratch:<ssevecmode> 3))
4734 (clobber (match_scratch:<ssevecmode> 4))])]
4735 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4736 {
4737 machine_mode mode = <MODE>mode;
4738 machine_mode vecmode = <ssevecmode>mode;
4739 REAL_VALUE_TYPE TWO31r;
4740 rtx two31;
4741
4742 if (optimize_insn_for_size_p ())
4743 FAIL;
4744
4745 real_ldexp (&TWO31r, &dconst1, 31);
4746 two31 = const_double_from_real_value (TWO31r, mode);
4747 two31 = ix86_build_const_vector (vecmode, true, two31);
4748 operands[2] = force_reg (vecmode, two31);
4749 })
4750
4751 (define_insn_and_split "*fixuns_trunc<mode>_1"
4752 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4753 (unsigned_fix:SI
4754 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4755 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4756 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4757 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4758 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4759 && optimize_function_for_speed_p (cfun)"
4760 "#"
4761 "&& reload_completed"
4762 [(const_int 0)]
4763 {
4764 ix86_split_convert_uns_si_sse (operands);
4765 DONE;
4766 })
4767
4768 ;; Unsigned conversion to HImode.
4769 ;; Without these patterns, we'll try the unsigned SI conversion which
4770 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4771
4772 (define_expand "fixuns_trunc<mode>hi2"
4773 [(set (match_dup 2)
4774 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4775 (set (match_operand:HI 0 "nonimmediate_operand")
4776 (subreg:HI (match_dup 2) 0))]
4777 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4778 "operands[2] = gen_reg_rtx (SImode);")
4779
4780 ;; When SSE is available, it is always faster to use it!
4781 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4782 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4783 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4784 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4785 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4786 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4787 [(set_attr "type" "sseicvt")
4788 (set_attr "prefix" "maybe_vex")
4789 (set (attr "prefix_rex")
4790 (if_then_else
4791 (match_test "<SWI48:MODE>mode == DImode")
4792 (const_string "1")
4793 (const_string "*")))
4794 (set_attr "mode" "<MODEF:MODE>")
4795 (set_attr "athlon_decode" "double,vector")
4796 (set_attr "amdfam10_decode" "double,double")
4797 (set_attr "bdver1_decode" "double,double")])
4798
4799 ;; Avoid vector decoded forms of the instruction.
4800 (define_peephole2
4801 [(match_scratch:MODEF 2 "x")
4802 (set (match_operand:SWI48 0 "register_operand")
4803 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4804 "TARGET_AVOID_VECTOR_DECODE
4805 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4806 && optimize_insn_for_speed_p ()"
4807 [(set (match_dup 2) (match_dup 1))
4808 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4809
4810 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4811 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4812 (fix:SWI248x (match_operand 1 "register_operand")))]
4813 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4814 && TARGET_FISTTP
4815 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4816 && (TARGET_64BIT || <MODE>mode != DImode))
4817 && TARGET_SSE_MATH)
4818 && can_create_pseudo_p ()"
4819 "#"
4820 "&& 1"
4821 [(const_int 0)]
4822 {
4823 if (memory_operand (operands[0], VOIDmode))
4824 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4825 else
4826 {
4827 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4828 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4829 operands[1],
4830 operands[2]));
4831 }
4832 DONE;
4833 }
4834 [(set_attr "type" "fisttp")
4835 (set_attr "mode" "<MODE>")])
4836
4837 (define_insn "fix_trunc<mode>_i387_fisttp"
4838 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4839 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4840 (clobber (match_scratch:XF 2 "=&1f"))]
4841 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4842 && TARGET_FISTTP
4843 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4844 && (TARGET_64BIT || <MODE>mode != DImode))
4845 && TARGET_SSE_MATH)"
4846 "* return output_fix_trunc (insn, operands, true);"
4847 [(set_attr "type" "fisttp")
4848 (set_attr "mode" "<MODE>")])
4849
4850 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4851 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4852 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4853 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4854 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4855 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4856 && TARGET_FISTTP
4857 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4858 && (TARGET_64BIT || <MODE>mode != DImode))
4859 && TARGET_SSE_MATH)"
4860 "#"
4861 [(set_attr "type" "fisttp")
4862 (set_attr "mode" "<MODE>")])
4863
4864 (define_split
4865 [(set (match_operand:SWI248x 0 "register_operand")
4866 (fix:SWI248x (match_operand 1 "register_operand")))
4867 (clobber (match_operand:SWI248x 2 "memory_operand"))
4868 (clobber (match_scratch 3))]
4869 "reload_completed"
4870 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4871 (clobber (match_dup 3))])
4872 (set (match_dup 0) (match_dup 2))])
4873
4874 (define_split
4875 [(set (match_operand:SWI248x 0 "memory_operand")
4876 (fix:SWI248x (match_operand 1 "register_operand")))
4877 (clobber (match_operand:SWI248x 2 "memory_operand"))
4878 (clobber (match_scratch 3))]
4879 "reload_completed"
4880 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4881 (clobber (match_dup 3))])])
4882
4883 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4884 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4885 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4886 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4887 ;; function in i386.c.
4888 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4889 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4890 (fix:SWI248x (match_operand 1 "register_operand")))
4891 (clobber (reg:CC FLAGS_REG))]
4892 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4893 && !TARGET_FISTTP
4894 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4895 && (TARGET_64BIT || <MODE>mode != DImode))
4896 && can_create_pseudo_p ()"
4897 "#"
4898 "&& 1"
4899 [(const_int 0)]
4900 {
4901 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4902
4903 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4904 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4905 if (memory_operand (operands[0], VOIDmode))
4906 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4907 operands[2], operands[3]));
4908 else
4909 {
4910 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4911 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4912 operands[2], operands[3],
4913 operands[4]));
4914 }
4915 DONE;
4916 }
4917 [(set_attr "type" "fistp")
4918 (set_attr "i387_cw" "trunc")
4919 (set_attr "mode" "<MODE>")])
4920
4921 (define_insn "fix_truncdi_i387"
4922 [(set (match_operand:DI 0 "memory_operand" "=m")
4923 (fix:DI (match_operand 1 "register_operand" "f")))
4924 (use (match_operand:HI 2 "memory_operand" "m"))
4925 (use (match_operand:HI 3 "memory_operand" "m"))
4926 (clobber (match_scratch:XF 4 "=&1f"))]
4927 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4928 && !TARGET_FISTTP
4929 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4930 "* return output_fix_trunc (insn, operands, false);"
4931 [(set_attr "type" "fistp")
4932 (set_attr "i387_cw" "trunc")
4933 (set_attr "mode" "DI")])
4934
4935 (define_insn "fix_truncdi_i387_with_temp"
4936 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4937 (fix:DI (match_operand 1 "register_operand" "f,f")))
4938 (use (match_operand:HI 2 "memory_operand" "m,m"))
4939 (use (match_operand:HI 3 "memory_operand" "m,m"))
4940 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4941 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4942 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4943 && !TARGET_FISTTP
4944 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4945 "#"
4946 [(set_attr "type" "fistp")
4947 (set_attr "i387_cw" "trunc")
4948 (set_attr "mode" "DI")])
4949
4950 (define_split
4951 [(set (match_operand:DI 0 "register_operand")
4952 (fix:DI (match_operand 1 "register_operand")))
4953 (use (match_operand:HI 2 "memory_operand"))
4954 (use (match_operand:HI 3 "memory_operand"))
4955 (clobber (match_operand:DI 4 "memory_operand"))
4956 (clobber (match_scratch 5))]
4957 "reload_completed"
4958 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4959 (use (match_dup 2))
4960 (use (match_dup 3))
4961 (clobber (match_dup 5))])
4962 (set (match_dup 0) (match_dup 4))])
4963
4964 (define_split
4965 [(set (match_operand:DI 0 "memory_operand")
4966 (fix:DI (match_operand 1 "register_operand")))
4967 (use (match_operand:HI 2 "memory_operand"))
4968 (use (match_operand:HI 3 "memory_operand"))
4969 (clobber (match_operand:DI 4 "memory_operand"))
4970 (clobber (match_scratch 5))]
4971 "reload_completed"
4972 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4973 (use (match_dup 2))
4974 (use (match_dup 3))
4975 (clobber (match_dup 5))])])
4976
4977 (define_insn "fix_trunc<mode>_i387"
4978 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4979 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4980 (use (match_operand:HI 2 "memory_operand" "m"))
4981 (use (match_operand:HI 3 "memory_operand" "m"))]
4982 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4983 && !TARGET_FISTTP
4984 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4985 "* return output_fix_trunc (insn, operands, false);"
4986 [(set_attr "type" "fistp")
4987 (set_attr "i387_cw" "trunc")
4988 (set_attr "mode" "<MODE>")])
4989
4990 (define_insn "fix_trunc<mode>_i387_with_temp"
4991 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4992 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4993 (use (match_operand:HI 2 "memory_operand" "m,m"))
4994 (use (match_operand:HI 3 "memory_operand" "m,m"))
4995 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4996 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4997 && !TARGET_FISTTP
4998 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4999 "#"
5000 [(set_attr "type" "fistp")
5001 (set_attr "i387_cw" "trunc")
5002 (set_attr "mode" "<MODE>")])
5003
5004 (define_split
5005 [(set (match_operand:SWI24 0 "register_operand")
5006 (fix:SWI24 (match_operand 1 "register_operand")))
5007 (use (match_operand:HI 2 "memory_operand"))
5008 (use (match_operand:HI 3 "memory_operand"))
5009 (clobber (match_operand:SWI24 4 "memory_operand"))]
5010 "reload_completed"
5011 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5012 (use (match_dup 2))
5013 (use (match_dup 3))])
5014 (set (match_dup 0) (match_dup 4))])
5015
5016 (define_split
5017 [(set (match_operand:SWI24 0 "memory_operand")
5018 (fix:SWI24 (match_operand 1 "register_operand")))
5019 (use (match_operand:HI 2 "memory_operand"))
5020 (use (match_operand:HI 3 "memory_operand"))
5021 (clobber (match_operand:SWI24 4 "memory_operand"))]
5022 "reload_completed"
5023 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5024 (use (match_dup 2))
5025 (use (match_dup 3))])])
5026
5027 (define_insn "x86_fnstcw_1"
5028 [(set (match_operand:HI 0 "memory_operand" "=m")
5029 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5030 "TARGET_80387"
5031 "fnstcw\t%0"
5032 [(set (attr "length")
5033 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5034 (set_attr "mode" "HI")
5035 (set_attr "unit" "i387")
5036 (set_attr "bdver1_decode" "vector")])
5037
5038 (define_insn "x86_fldcw_1"
5039 [(set (reg:HI FPCR_REG)
5040 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5041 "TARGET_80387"
5042 "fldcw\t%0"
5043 [(set (attr "length")
5044 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5045 (set_attr "mode" "HI")
5046 (set_attr "unit" "i387")
5047 (set_attr "athlon_decode" "vector")
5048 (set_attr "amdfam10_decode" "vector")
5049 (set_attr "bdver1_decode" "vector")])
5050 \f
5051 ;; Conversion between fixed point and floating point.
5052
5053 ;; Even though we only accept memory inputs, the backend _really_
5054 ;; wants to be able to do this between registers. Thankfully, LRA
5055 ;; will fix this up for us during register allocation.
5056
5057 (define_insn "floathi<mode>2"
5058 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5059 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5060 "TARGET_80387
5061 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5062 || TARGET_MIX_SSE_I387)"
5063 "fild%Z1\t%1"
5064 [(set_attr "type" "fmov")
5065 (set_attr "mode" "<MODE>")
5066 (set_attr "znver1_decode" "double")
5067 (set_attr "fp_int_src" "true")])
5068
5069 (define_insn "float<SWI48x:mode>xf2"
5070 [(set (match_operand:XF 0 "register_operand" "=f")
5071 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5072 "TARGET_80387"
5073 "fild%Z1\t%1"
5074 [(set_attr "type" "fmov")
5075 (set_attr "mode" "XF")
5076 (set_attr "znver1_decode" "double")
5077 (set_attr "fp_int_src" "true")])
5078
5079 (define_expand "float<SWI48:mode><MODEF:mode>2"
5080 [(set (match_operand:MODEF 0 "register_operand")
5081 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5082 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5083 {
5084 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5085 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5086 {
5087 rtx reg = gen_reg_rtx (XFmode);
5088 rtx (*insn)(rtx, rtx);
5089
5090 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5091
5092 if (<MODEF:MODE>mode == SFmode)
5093 insn = gen_truncxfsf2;
5094 else if (<MODEF:MODE>mode == DFmode)
5095 insn = gen_truncxfdf2;
5096 else
5097 gcc_unreachable ();
5098
5099 emit_insn (insn (operands[0], reg));
5100 DONE;
5101 }
5102 })
5103
5104 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5105 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5106 (float:MODEF
5107 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5108 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5109 "@
5110 fild%Z1\t%1
5111 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5112 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5113 [(set_attr "type" "fmov,sseicvt,sseicvt")
5114 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5115 (set_attr "mode" "<MODEF:MODE>")
5116 (set (attr "prefix_rex")
5117 (if_then_else
5118 (and (eq_attr "prefix" "maybe_vex")
5119 (match_test "<SWI48:MODE>mode == DImode"))
5120 (const_string "1")
5121 (const_string "*")))
5122 (set_attr "unit" "i387,*,*")
5123 (set_attr "athlon_decode" "*,double,direct")
5124 (set_attr "amdfam10_decode" "*,vector,double")
5125 (set_attr "bdver1_decode" "*,double,direct")
5126 (set_attr "znver1_decode" "double,*,*")
5127 (set_attr "fp_int_src" "true")
5128 (set (attr "enabled")
5129 (cond [(eq_attr "alternative" "0")
5130 (symbol_ref "TARGET_MIX_SSE_I387
5131 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5132 <SWI48:MODE>mode)")
5133 ]
5134 (symbol_ref "true")))
5135 (set (attr "preferred_for_speed")
5136 (cond [(eq_attr "alternative" "1")
5137 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5138 (symbol_ref "true")))])
5139
5140 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5141 [(set (match_operand:MODEF 0 "register_operand" "=f")
5142 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5143 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5144 "fild%Z1\t%1"
5145 [(set_attr "type" "fmov")
5146 (set_attr "mode" "<MODEF:MODE>")
5147 (set_attr "znver1_decode" "double")
5148 (set_attr "fp_int_src" "true")])
5149
5150 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5151 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5152 ;; alternative in sse2_loadld.
5153 (define_split
5154 [(set (match_operand:MODEF 0 "sse_reg_operand")
5155 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5156 "TARGET_USE_VECTOR_CONVERTS
5157 && optimize_function_for_speed_p (cfun)
5158 && reload_completed
5159 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5160 && (!EXT_REX_SSE_REG_P (operands[0])
5161 || TARGET_AVX512VL)"
5162 [(const_int 0)]
5163 {
5164 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5165 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5166
5167 emit_insn (gen_sse2_loadld (operands[4],
5168 CONST0_RTX (V4SImode), operands[1]));
5169
5170 if (<ssevecmode>mode == V4SFmode)
5171 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5172 else
5173 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5174 DONE;
5175 })
5176
5177 ;; Avoid partial SSE register dependency stalls. This splitter should split
5178 ;; late in the pass sequence (after register rename pass), so allocated
5179 ;; registers won't change anymore
5180
5181 (define_split
5182 [(set (match_operand:MODEF 0 "sse_reg_operand")
5183 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5184 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5185 && optimize_function_for_speed_p (cfun)
5186 && (!EXT_REX_SSE_REG_P (operands[0])
5187 || TARGET_AVX512VL)"
5188 [(set (match_dup 0)
5189 (vec_merge:<MODEF:ssevecmode>
5190 (vec_duplicate:<MODEF:ssevecmode>
5191 (float:MODEF
5192 (match_dup 1)))
5193 (match_dup 0)
5194 (const_int 1)))]
5195 {
5196 const machine_mode vmode = <MODEF:ssevecmode>mode;
5197
5198 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5199 emit_move_insn (operands[0], CONST0_RTX (vmode));
5200 })
5201
5202 ;; Break partial reg stall for cvtsd2ss. This splitter should split
5203 ;; late in the pass sequence (after register rename pass),
5204 ;; so allocated registers won't change anymore.
5205
5206 (define_split
5207 [(set (match_operand:SF 0 "sse_reg_operand")
5208 (float_truncate:SF
5209 (match_operand:DF 1 "nonimmediate_operand")))]
5210 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5211 && optimize_function_for_speed_p (cfun)
5212 && (!REG_P (operands[1])
5213 || REGNO (operands[0]) != REGNO (operands[1]))
5214 && (!EXT_REX_SSE_REG_P (operands[0])
5215 || TARGET_AVX512VL)"
5216 [(set (match_dup 0)
5217 (vec_merge:V4SF
5218 (vec_duplicate:V4SF
5219 (float_truncate:SF
5220 (match_dup 1)))
5221 (match_dup 0)
5222 (const_int 1)))]
5223 {
5224 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5225 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5226 })
5227
5228 ;; Break partial reg stall for cvtss2sd. This splitter should split
5229 ;; late in the pass sequence (after register rename pass),
5230 ;; so allocated registers won't change anymore.
5231
5232 (define_split
5233 [(set (match_operand:DF 0 "sse_reg_operand")
5234 (float_extend:DF
5235 (match_operand:SF 1 "nonimmediate_operand")))]
5236 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5237 && optimize_function_for_speed_p (cfun)
5238 && (!REG_P (operands[1])
5239 || REGNO (operands[0]) != REGNO (operands[1]))
5240 && (!EXT_REX_SSE_REG_P (operands[0])
5241 || TARGET_AVX512VL)"
5242 [(set (match_dup 0)
5243 (vec_merge:V2DF
5244 (vec_duplicate:V2DF
5245 (float_extend:DF
5246 (match_dup 1)))
5247 (match_dup 0)
5248 (const_int 1)))]
5249 {
5250 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5251 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5252 })
5253
5254 ;; Avoid store forwarding (partial memory) stall penalty
5255 ;; by passing DImode value through XMM registers. */
5256
5257 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5258 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5259 (float:X87MODEF
5260 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5261 (clobber (match_scratch:V4SI 3 "=X,x"))
5262 (clobber (match_scratch:V4SI 4 "=X,x"))
5263 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5264 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5265 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5266 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5267 "#"
5268 [(set_attr "type" "multi")
5269 (set_attr "mode" "<X87MODEF:MODE>")
5270 (set_attr "unit" "i387")
5271 (set_attr "fp_int_src" "true")])
5272
5273 (define_split
5274 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5275 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5276 (clobber (match_scratch:V4SI 3))
5277 (clobber (match_scratch:V4SI 4))
5278 (clobber (match_operand:DI 2 "memory_operand"))]
5279 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5280 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5281 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5282 && reload_completed"
5283 [(set (match_dup 2) (match_dup 3))
5284 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5285 {
5286 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5287 Assemble the 64-bit DImode value in an xmm register. */
5288 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5289 gen_lowpart (SImode, operands[1])));
5290 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5291 gen_highpart (SImode, operands[1])));
5292 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5293 operands[4]));
5294
5295 operands[3] = gen_lowpart (DImode, operands[3]);
5296 })
5297
5298 (define_split
5299 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5300 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5301 (clobber (match_scratch:V4SI 3))
5302 (clobber (match_scratch:V4SI 4))
5303 (clobber (match_operand:DI 2 "memory_operand"))]
5304 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5305 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5306 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5307 && reload_completed"
5308 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5309
5310 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5311 [(set (match_operand:MODEF 0 "register_operand")
5312 (unsigned_float:MODEF
5313 (match_operand:SWI12 1 "nonimmediate_operand")))]
5314 "!TARGET_64BIT
5315 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5316 {
5317 operands[1] = convert_to_mode (SImode, operands[1], 1);
5318 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5319 DONE;
5320 })
5321
5322 ;; Avoid store forwarding (partial memory) stall penalty by extending
5323 ;; SImode value to DImode through XMM register instead of pushing two
5324 ;; SImode values to stack. Also note that fild loads from memory only.
5325
5326 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5327 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5328 (unsigned_float:X87MODEF
5329 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5330 (clobber (match_scratch:DI 3 "=x"))
5331 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5332 "!TARGET_64BIT
5333 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5334 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5335 "#"
5336 "&& reload_completed"
5337 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5338 (set (match_dup 2) (match_dup 3))
5339 (set (match_dup 0)
5340 (float:X87MODEF (match_dup 2)))]
5341 ""
5342 [(set_attr "type" "multi")
5343 (set_attr "mode" "<MODE>")])
5344
5345 (define_expand "floatunssi<mode>2"
5346 [(parallel
5347 [(set (match_operand:X87MODEF 0 "register_operand")
5348 (unsigned_float:X87MODEF
5349 (match_operand:SI 1 "nonimmediate_operand")))
5350 (clobber (match_scratch:DI 3))
5351 (clobber (match_dup 2))])]
5352 "!TARGET_64BIT
5353 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5354 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5355 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5356 {
5357 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5358 {
5359 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5360 DONE;
5361 }
5362 else
5363 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5364 })
5365
5366 (define_expand "floatunsdisf2"
5367 [(use (match_operand:SF 0 "register_operand"))
5368 (use (match_operand:DI 1 "nonimmediate_operand"))]
5369 "TARGET_64BIT && TARGET_SSE_MATH"
5370 "x86_emit_floatuns (operands); DONE;")
5371
5372 (define_expand "floatunsdidf2"
5373 [(use (match_operand:DF 0 "register_operand"))
5374 (use (match_operand:DI 1 "nonimmediate_operand"))]
5375 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5376 && TARGET_SSE2 && TARGET_SSE_MATH"
5377 {
5378 if (TARGET_64BIT)
5379 x86_emit_floatuns (operands);
5380 else
5381 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5382 DONE;
5383 })
5384 \f
5385 ;; Load effective address instructions
5386
5387 (define_insn_and_split "*lea<mode>"
5388 [(set (match_operand:SWI48 0 "register_operand" "=r")
5389 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5390 ""
5391 {
5392 if (SImode_address_operand (operands[1], VOIDmode))
5393 {
5394 gcc_assert (TARGET_64BIT);
5395 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5396 }
5397 else
5398 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5399 }
5400 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5401 [(const_int 0)]
5402 {
5403 machine_mode mode = <MODE>mode;
5404 rtx pat;
5405
5406 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5407 change operands[] array behind our back. */
5408 pat = PATTERN (curr_insn);
5409
5410 operands[0] = SET_DEST (pat);
5411 operands[1] = SET_SRC (pat);
5412
5413 /* Emit all operations in SImode for zero-extended addresses. */
5414 if (SImode_address_operand (operands[1], VOIDmode))
5415 mode = SImode;
5416
5417 ix86_split_lea_for_addr (curr_insn, operands, mode);
5418
5419 /* Zero-extend return register to DImode for zero-extended addresses. */
5420 if (mode != <MODE>mode)
5421 emit_insn (gen_zero_extendsidi2
5422 (operands[0], gen_lowpart (mode, operands[0])));
5423
5424 DONE;
5425 }
5426 [(set_attr "type" "lea")
5427 (set (attr "mode")
5428 (if_then_else
5429 (match_operand 1 "SImode_address_operand")
5430 (const_string "SI")
5431 (const_string "<MODE>")))])
5432 \f
5433 ;; Add instructions
5434
5435 (define_expand "add<mode>3"
5436 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5437 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5438 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5439 ""
5440 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5441
5442 (define_insn_and_split "*add<dwi>3_doubleword"
5443 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5444 (plus:<DWI>
5445 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5446 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5447 "ro<di>,r<di>")))
5448 (clobber (reg:CC FLAGS_REG))]
5449 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5450 "#"
5451 "reload_completed"
5452 [(parallel [(set (reg:CCC FLAGS_REG)
5453 (compare:CCC
5454 (plus:DWIH (match_dup 1) (match_dup 2))
5455 (match_dup 1)))
5456 (set (match_dup 0)
5457 (plus:DWIH (match_dup 1) (match_dup 2)))])
5458 (parallel [(set (match_dup 3)
5459 (plus:DWIH
5460 (plus:DWIH
5461 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5462 (match_dup 4))
5463 (match_dup 5)))
5464 (clobber (reg:CC FLAGS_REG))])]
5465 {
5466 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5467 if (operands[2] == const0_rtx)
5468 {
5469 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5470 DONE;
5471 }
5472 })
5473
5474 (define_insn "*add<mode>_1"
5475 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5476 (plus:SWI48
5477 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5478 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5479 (clobber (reg:CC FLAGS_REG))]
5480 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5481 {
5482 switch (get_attr_type (insn))
5483 {
5484 case TYPE_LEA:
5485 return "#";
5486
5487 case TYPE_INCDEC:
5488 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5489 if (operands[2] == const1_rtx)
5490 return "inc{<imodesuffix>}\t%0";
5491 else
5492 {
5493 gcc_assert (operands[2] == constm1_rtx);
5494 return "dec{<imodesuffix>}\t%0";
5495 }
5496
5497 default:
5498 /* For most processors, ADD is faster than LEA. This alternative
5499 was added to use ADD as much as possible. */
5500 if (which_alternative == 2)
5501 std::swap (operands[1], operands[2]);
5502
5503 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5504 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5505 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5506
5507 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5508 }
5509 }
5510 [(set (attr "type")
5511 (cond [(eq_attr "alternative" "3")
5512 (const_string "lea")
5513 (match_operand:SWI48 2 "incdec_operand")
5514 (const_string "incdec")
5515 ]
5516 (const_string "alu")))
5517 (set (attr "length_immediate")
5518 (if_then_else
5519 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5520 (const_string "1")
5521 (const_string "*")))
5522 (set_attr "mode" "<MODE>")])
5523
5524 ;; It may seem that nonimmediate operand is proper one for operand 1.
5525 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5526 ;; we take care in ix86_binary_operator_ok to not allow two memory
5527 ;; operands so proper swapping will be done in reload. This allow
5528 ;; patterns constructed from addsi_1 to match.
5529
5530 (define_insn "addsi_1_zext"
5531 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5532 (zero_extend:DI
5533 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5534 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5535 (clobber (reg:CC FLAGS_REG))]
5536 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5537 {
5538 switch (get_attr_type (insn))
5539 {
5540 case TYPE_LEA:
5541 return "#";
5542
5543 case TYPE_INCDEC:
5544 if (operands[2] == const1_rtx)
5545 return "inc{l}\t%k0";
5546 else
5547 {
5548 gcc_assert (operands[2] == constm1_rtx);
5549 return "dec{l}\t%k0";
5550 }
5551
5552 default:
5553 /* For most processors, ADD is faster than LEA. This alternative
5554 was added to use ADD as much as possible. */
5555 if (which_alternative == 1)
5556 std::swap (operands[1], operands[2]);
5557
5558 if (x86_maybe_negate_const_int (&operands[2], SImode))
5559 return "sub{l}\t{%2, %k0|%k0, %2}";
5560
5561 return "add{l}\t{%2, %k0|%k0, %2}";
5562 }
5563 }
5564 [(set (attr "type")
5565 (cond [(eq_attr "alternative" "2")
5566 (const_string "lea")
5567 (match_operand:SI 2 "incdec_operand")
5568 (const_string "incdec")
5569 ]
5570 (const_string "alu")))
5571 (set (attr "length_immediate")
5572 (if_then_else
5573 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5574 (const_string "1")
5575 (const_string "*")))
5576 (set_attr "mode" "SI")])
5577
5578 (define_insn "*addhi_1"
5579 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5580 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5581 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5582 (clobber (reg:CC FLAGS_REG))]
5583 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5584 {
5585 switch (get_attr_type (insn))
5586 {
5587 case TYPE_LEA:
5588 return "#";
5589
5590 case TYPE_INCDEC:
5591 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5592 if (operands[2] == const1_rtx)
5593 return "inc{w}\t%0";
5594 else
5595 {
5596 gcc_assert (operands[2] == constm1_rtx);
5597 return "dec{w}\t%0";
5598 }
5599
5600 default:
5601 /* For most processors, ADD is faster than LEA. This alternative
5602 was added to use ADD as much as possible. */
5603 if (which_alternative == 2)
5604 std::swap (operands[1], operands[2]);
5605
5606 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5607 if (x86_maybe_negate_const_int (&operands[2], HImode))
5608 return "sub{w}\t{%2, %0|%0, %2}";
5609
5610 return "add{w}\t{%2, %0|%0, %2}";
5611 }
5612 }
5613 [(set (attr "type")
5614 (cond [(eq_attr "alternative" "3")
5615 (const_string "lea")
5616 (match_operand:HI 2 "incdec_operand")
5617 (const_string "incdec")
5618 ]
5619 (const_string "alu")))
5620 (set (attr "length_immediate")
5621 (if_then_else
5622 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5623 (const_string "1")
5624 (const_string "*")))
5625 (set_attr "mode" "HI,HI,HI,SI")])
5626
5627 (define_insn "*addqi_1"
5628 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5629 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5630 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5631 (clobber (reg:CC FLAGS_REG))]
5632 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5633 {
5634 bool widen = (get_attr_mode (insn) != MODE_QI);
5635
5636 switch (get_attr_type (insn))
5637 {
5638 case TYPE_LEA:
5639 return "#";
5640
5641 case TYPE_INCDEC:
5642 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5643 if (operands[2] == const1_rtx)
5644 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5645 else
5646 {
5647 gcc_assert (operands[2] == constm1_rtx);
5648 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5649 }
5650
5651 default:
5652 /* For most processors, ADD is faster than LEA. These alternatives
5653 were added to use ADD as much as possible. */
5654 if (which_alternative == 2 || which_alternative == 4)
5655 std::swap (operands[1], operands[2]);
5656
5657 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5658 if (x86_maybe_negate_const_int (&operands[2], QImode))
5659 {
5660 if (widen)
5661 return "sub{l}\t{%2, %k0|%k0, %2}";
5662 else
5663 return "sub{b}\t{%2, %0|%0, %2}";
5664 }
5665 if (widen)
5666 return "add{l}\t{%k2, %k0|%k0, %k2}";
5667 else
5668 return "add{b}\t{%2, %0|%0, %2}";
5669 }
5670 }
5671 [(set (attr "type")
5672 (cond [(eq_attr "alternative" "5")
5673 (const_string "lea")
5674 (match_operand:QI 2 "incdec_operand")
5675 (const_string "incdec")
5676 ]
5677 (const_string "alu")))
5678 (set (attr "length_immediate")
5679 (if_then_else
5680 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5681 (const_string "1")
5682 (const_string "*")))
5683 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5684 ;; Potential partial reg stall on alternatives 3 and 4.
5685 (set (attr "preferred_for_speed")
5686 (cond [(eq_attr "alternative" "3,4")
5687 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5688 (symbol_ref "true")))])
5689
5690 (define_insn "*addqi_1_slp"
5691 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5692 (plus:QI (match_dup 0)
5693 (match_operand:QI 1 "general_operand" "qn,qm")))
5694 (clobber (reg:CC FLAGS_REG))]
5695 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5696 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5697 {
5698 switch (get_attr_type (insn))
5699 {
5700 case TYPE_INCDEC:
5701 if (operands[1] == const1_rtx)
5702 return "inc{b}\t%0";
5703 else
5704 {
5705 gcc_assert (operands[1] == constm1_rtx);
5706 return "dec{b}\t%0";
5707 }
5708
5709 default:
5710 if (x86_maybe_negate_const_int (&operands[1], QImode))
5711 return "sub{b}\t{%1, %0|%0, %1}";
5712
5713 return "add{b}\t{%1, %0|%0, %1}";
5714 }
5715 }
5716 [(set (attr "type")
5717 (if_then_else (match_operand:QI 1 "incdec_operand")
5718 (const_string "incdec")
5719 (const_string "alu1")))
5720 (set (attr "memory")
5721 (if_then_else (match_operand 1 "memory_operand")
5722 (const_string "load")
5723 (const_string "none")))
5724 (set_attr "mode" "QI")])
5725
5726 ;; Split non destructive adds if we cannot use lea.
5727 (define_split
5728 [(set (match_operand:SWI48 0 "register_operand")
5729 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5730 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5731 (clobber (reg:CC FLAGS_REG))]
5732 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5733 [(set (match_dup 0) (match_dup 1))
5734 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5735 (clobber (reg:CC FLAGS_REG))])])
5736
5737 ;; Split non destructive adds if we cannot use lea.
5738 (define_split
5739 [(set (match_operand:DI 0 "register_operand")
5740 (zero_extend:DI
5741 (plus:SI (match_operand:SI 1 "register_operand")
5742 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5743 (clobber (reg:CC FLAGS_REG))]
5744 "TARGET_64BIT
5745 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5746 [(set (match_dup 3) (match_dup 1))
5747 (parallel [(set (match_dup 0)
5748 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5749 (clobber (reg:CC FLAGS_REG))])]
5750 "operands[3] = gen_lowpart (SImode, operands[0]);")
5751
5752 ;; Convert add to the lea pattern to avoid flags dependency.
5753 (define_split
5754 [(set (match_operand:SWI 0 "register_operand")
5755 (plus:SWI (match_operand:SWI 1 "register_operand")
5756 (match_operand:SWI 2 "<nonmemory_operand>")))
5757 (clobber (reg:CC FLAGS_REG))]
5758 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5759 [(set (match_dup 0)
5760 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5761 {
5762 if (<MODE>mode != <LEAMODE>mode)
5763 {
5764 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5765 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5766 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5767 }
5768 })
5769
5770 ;; Convert add to the lea pattern to avoid flags dependency.
5771 (define_split
5772 [(set (match_operand:DI 0 "register_operand")
5773 (zero_extend:DI
5774 (plus:SI (match_operand:SI 1 "register_operand")
5775 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5776 (clobber (reg:CC FLAGS_REG))]
5777 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5778 [(set (match_dup 0)
5779 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5780
5781 (define_insn "*add<mode>_2"
5782 [(set (reg FLAGS_REG)
5783 (compare
5784 (plus:SWI
5785 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5786 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5787 (const_int 0)))
5788 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5789 (plus:SWI (match_dup 1) (match_dup 2)))]
5790 "ix86_match_ccmode (insn, CCGOCmode)
5791 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5792 {
5793 switch (get_attr_type (insn))
5794 {
5795 case TYPE_INCDEC:
5796 if (operands[2] == const1_rtx)
5797 return "inc{<imodesuffix>}\t%0";
5798 else
5799 {
5800 gcc_assert (operands[2] == constm1_rtx);
5801 return "dec{<imodesuffix>}\t%0";
5802 }
5803
5804 default:
5805 if (which_alternative == 2)
5806 std::swap (operands[1], operands[2]);
5807
5808 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5810 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5811
5812 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5813 }
5814 }
5815 [(set (attr "type")
5816 (if_then_else (match_operand:SWI 2 "incdec_operand")
5817 (const_string "incdec")
5818 (const_string "alu")))
5819 (set (attr "length_immediate")
5820 (if_then_else
5821 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5822 (const_string "1")
5823 (const_string "*")))
5824 (set_attr "mode" "<MODE>")])
5825
5826 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5827 (define_insn "*addsi_2_zext"
5828 [(set (reg FLAGS_REG)
5829 (compare
5830 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5831 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5832 (const_int 0)))
5833 (set (match_operand:DI 0 "register_operand" "=r,r")
5834 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5835 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5836 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5837 {
5838 switch (get_attr_type (insn))
5839 {
5840 case TYPE_INCDEC:
5841 if (operands[2] == const1_rtx)
5842 return "inc{l}\t%k0";
5843 else
5844 {
5845 gcc_assert (operands[2] == constm1_rtx);
5846 return "dec{l}\t%k0";
5847 }
5848
5849 default:
5850 if (which_alternative == 1)
5851 std::swap (operands[1], operands[2]);
5852
5853 if (x86_maybe_negate_const_int (&operands[2], SImode))
5854 return "sub{l}\t{%2, %k0|%k0, %2}";
5855
5856 return "add{l}\t{%2, %k0|%k0, %2}";
5857 }
5858 }
5859 [(set (attr "type")
5860 (if_then_else (match_operand:SI 2 "incdec_operand")
5861 (const_string "incdec")
5862 (const_string "alu")))
5863 (set (attr "length_immediate")
5864 (if_then_else
5865 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5866 (const_string "1")
5867 (const_string "*")))
5868 (set_attr "mode" "SI")])
5869
5870 (define_insn "*add<mode>_3"
5871 [(set (reg FLAGS_REG)
5872 (compare
5873 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5874 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5875 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5876 "ix86_match_ccmode (insn, CCZmode)
5877 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5878 {
5879 switch (get_attr_type (insn))
5880 {
5881 case TYPE_INCDEC:
5882 if (operands[2] == const1_rtx)
5883 return "inc{<imodesuffix>}\t%0";
5884 else
5885 {
5886 gcc_assert (operands[2] == constm1_rtx);
5887 return "dec{<imodesuffix>}\t%0";
5888 }
5889
5890 default:
5891 if (which_alternative == 1)
5892 std::swap (operands[1], operands[2]);
5893
5894 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5895 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5896 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5897
5898 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5899 }
5900 }
5901 [(set (attr "type")
5902 (if_then_else (match_operand:SWI 2 "incdec_operand")
5903 (const_string "incdec")
5904 (const_string "alu")))
5905 (set (attr "length_immediate")
5906 (if_then_else
5907 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5908 (const_string "1")
5909 (const_string "*")))
5910 (set_attr "mode" "<MODE>")])
5911
5912 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5913 (define_insn "*addsi_3_zext"
5914 [(set (reg FLAGS_REG)
5915 (compare
5916 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5917 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5918 (set (match_operand:DI 0 "register_operand" "=r,r")
5919 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5920 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5921 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5922 {
5923 switch (get_attr_type (insn))
5924 {
5925 case TYPE_INCDEC:
5926 if (operands[2] == const1_rtx)
5927 return "inc{l}\t%k0";
5928 else
5929 {
5930 gcc_assert (operands[2] == constm1_rtx);
5931 return "dec{l}\t%k0";
5932 }
5933
5934 default:
5935 if (which_alternative == 1)
5936 std::swap (operands[1], operands[2]);
5937
5938 if (x86_maybe_negate_const_int (&operands[2], SImode))
5939 return "sub{l}\t{%2, %k0|%k0, %2}";
5940
5941 return "add{l}\t{%2, %k0|%k0, %2}";
5942 }
5943 }
5944 [(set (attr "type")
5945 (if_then_else (match_operand:SI 2 "incdec_operand")
5946 (const_string "incdec")
5947 (const_string "alu")))
5948 (set (attr "length_immediate")
5949 (if_then_else
5950 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5951 (const_string "1")
5952 (const_string "*")))
5953 (set_attr "mode" "SI")])
5954
5955 ; For comparisons against 1, -1 and 128, we may generate better code
5956 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5957 ; is matched then. We can't accept general immediate, because for
5958 ; case of overflows, the result is messed up.
5959 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5960 ; only for comparisons not depending on it.
5961
5962 (define_insn "*adddi_4"
5963 [(set (reg FLAGS_REG)
5964 (compare
5965 (match_operand:DI 1 "nonimmediate_operand" "0")
5966 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5967 (clobber (match_scratch:DI 0 "=rm"))]
5968 "TARGET_64BIT
5969 && ix86_match_ccmode (insn, CCGCmode)"
5970 {
5971 switch (get_attr_type (insn))
5972 {
5973 case TYPE_INCDEC:
5974 if (operands[2] == constm1_rtx)
5975 return "inc{q}\t%0";
5976 else
5977 {
5978 gcc_assert (operands[2] == const1_rtx);
5979 return "dec{q}\t%0";
5980 }
5981
5982 default:
5983 if (x86_maybe_negate_const_int (&operands[2], DImode))
5984 return "add{q}\t{%2, %0|%0, %2}";
5985
5986 return "sub{q}\t{%2, %0|%0, %2}";
5987 }
5988 }
5989 [(set (attr "type")
5990 (if_then_else (match_operand:DI 2 "incdec_operand")
5991 (const_string "incdec")
5992 (const_string "alu")))
5993 (set (attr "length_immediate")
5994 (if_then_else
5995 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5996 (const_string "1")
5997 (const_string "*")))
5998 (set_attr "mode" "DI")])
5999
6000 ; For comparisons against 1, -1 and 128, we may generate better code
6001 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6002 ; is matched then. We can't accept general immediate, because for
6003 ; case of overflows, the result is messed up.
6004 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6005 ; only for comparisons not depending on it.
6006
6007 (define_insn "*add<mode>_4"
6008 [(set (reg FLAGS_REG)
6009 (compare
6010 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6011 (match_operand:SWI124 2 "const_int_operand" "n")))
6012 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6013 "ix86_match_ccmode (insn, CCGCmode)"
6014 {
6015 switch (get_attr_type (insn))
6016 {
6017 case TYPE_INCDEC:
6018 if (operands[2] == constm1_rtx)
6019 return "inc{<imodesuffix>}\t%0";
6020 else
6021 {
6022 gcc_assert (operands[2] == const1_rtx);
6023 return "dec{<imodesuffix>}\t%0";
6024 }
6025
6026 default:
6027 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6028 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6029
6030 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6031 }
6032 }
6033 [(set (attr "type")
6034 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6035 (const_string "incdec")
6036 (const_string "alu")))
6037 (set (attr "length_immediate")
6038 (if_then_else
6039 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6040 (const_string "1")
6041 (const_string "*")))
6042 (set_attr "mode" "<MODE>")])
6043
6044 (define_insn "*add<mode>_5"
6045 [(set (reg FLAGS_REG)
6046 (compare
6047 (plus:SWI
6048 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6049 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6050 (const_int 0)))
6051 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6052 "ix86_match_ccmode (insn, CCGOCmode)
6053 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6054 {
6055 switch (get_attr_type (insn))
6056 {
6057 case TYPE_INCDEC:
6058 if (operands[2] == const1_rtx)
6059 return "inc{<imodesuffix>}\t%0";
6060 else
6061 {
6062 gcc_assert (operands[2] == constm1_rtx);
6063 return "dec{<imodesuffix>}\t%0";
6064 }
6065
6066 default:
6067 if (which_alternative == 1)
6068 std::swap (operands[1], operands[2]);
6069
6070 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6071 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6072 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6073
6074 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6075 }
6076 }
6077 [(set (attr "type")
6078 (if_then_else (match_operand:SWI 2 "incdec_operand")
6079 (const_string "incdec")
6080 (const_string "alu")))
6081 (set (attr "length_immediate")
6082 (if_then_else
6083 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6084 (const_string "1")
6085 (const_string "*")))
6086 (set_attr "mode" "<MODE>")])
6087
6088 (define_insn "addqi_ext_1"
6089 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6090 (const_int 8)
6091 (const_int 8))
6092 (subreg:SI
6093 (plus:QI
6094 (subreg:QI
6095 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6096 (const_int 8)
6097 (const_int 8)) 0)
6098 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6099 (clobber (reg:CC FLAGS_REG))]
6100 ""
6101 {
6102 switch (get_attr_type (insn))
6103 {
6104 case TYPE_INCDEC:
6105 if (operands[2] == const1_rtx)
6106 return "inc{b}\t%h0";
6107 else
6108 {
6109 gcc_assert (operands[2] == constm1_rtx);
6110 return "dec{b}\t%h0";
6111 }
6112
6113 default:
6114 return "add{b}\t{%2, %h0|%h0, %2}";
6115 }
6116 }
6117 [(set_attr "isa" "*,nox64")
6118 (set (attr "type")
6119 (if_then_else (match_operand:QI 2 "incdec_operand")
6120 (const_string "incdec")
6121 (const_string "alu")))
6122 (set_attr "mode" "QI")])
6123
6124 (define_insn "*addqi_ext_2"
6125 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6126 (const_int 8)
6127 (const_int 8))
6128 (subreg:SI
6129 (plus:QI
6130 (subreg:QI
6131 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6132 (const_int 8)
6133 (const_int 8)) 0)
6134 (subreg:QI
6135 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6136 (const_int 8)
6137 (const_int 8)) 0)) 0))
6138 (clobber (reg:CC FLAGS_REG))]
6139 ""
6140 "add{b}\t{%h2, %h0|%h0, %h2}"
6141 [(set_attr "type" "alu")
6142 (set_attr "mode" "QI")])
6143
6144 ;; Add with jump on overflow.
6145 (define_expand "addv<mode>4"
6146 [(parallel [(set (reg:CCO FLAGS_REG)
6147 (eq:CCO (plus:<DWI>
6148 (sign_extend:<DWI>
6149 (match_operand:SWI 1 "nonimmediate_operand"))
6150 (match_dup 4))
6151 (sign_extend:<DWI>
6152 (plus:SWI (match_dup 1)
6153 (match_operand:SWI 2
6154 "<general_operand>")))))
6155 (set (match_operand:SWI 0 "register_operand")
6156 (plus:SWI (match_dup 1) (match_dup 2)))])
6157 (set (pc) (if_then_else
6158 (eq (reg:CCO FLAGS_REG) (const_int 0))
6159 (label_ref (match_operand 3))
6160 (pc)))]
6161 ""
6162 {
6163 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6164 if (CONST_INT_P (operands[2]))
6165 operands[4] = operands[2];
6166 else
6167 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6168 })
6169
6170 (define_insn "*addv<mode>4"
6171 [(set (reg:CCO FLAGS_REG)
6172 (eq:CCO (plus:<DWI>
6173 (sign_extend:<DWI>
6174 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6175 (sign_extend:<DWI>
6176 (match_operand:SWI 2 "<general_sext_operand>"
6177 "<r>mWe,<r>We")))
6178 (sign_extend:<DWI>
6179 (plus:SWI (match_dup 1) (match_dup 2)))))
6180 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6181 (plus:SWI (match_dup 1) (match_dup 2)))]
6182 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6183 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6184 [(set_attr "type" "alu")
6185 (set_attr "mode" "<MODE>")])
6186
6187 (define_insn "*addv<mode>4_1"
6188 [(set (reg:CCO FLAGS_REG)
6189 (eq:CCO (plus:<DWI>
6190 (sign_extend:<DWI>
6191 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6192 (match_operand:<DWI> 3 "const_int_operand" "i"))
6193 (sign_extend:<DWI>
6194 (plus:SWI (match_dup 1)
6195 (match_operand:SWI 2 "x86_64_immediate_operand"
6196 "<i>")))))
6197 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6198 (plus:SWI (match_dup 1) (match_dup 2)))]
6199 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6200 && CONST_INT_P (operands[2])
6201 && INTVAL (operands[2]) == INTVAL (operands[3])"
6202 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6203 [(set_attr "type" "alu")
6204 (set_attr "mode" "<MODE>")
6205 (set (attr "length_immediate")
6206 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6207 (const_string "1")
6208 (match_test "<MODE_SIZE> == 8")
6209 (const_string "4")]
6210 (const_string "<MODE_SIZE>")))])
6211
6212 (define_expand "uaddv<mode>4"
6213 [(parallel [(set (reg:CCC FLAGS_REG)
6214 (compare:CCC
6215 (plus:SWI
6216 (match_operand:SWI 1 "nonimmediate_operand")
6217 (match_operand:SWI 2 "<general_operand>"))
6218 (match_dup 1)))
6219 (set (match_operand:SWI 0 "register_operand")
6220 (plus:SWI (match_dup 1) (match_dup 2)))])
6221 (set (pc) (if_then_else
6222 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6223 (label_ref (match_operand 3))
6224 (pc)))]
6225 ""
6226 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6227
6228 ;; The lea patterns for modes less than 32 bits need to be matched by
6229 ;; several insns converted to real lea by splitters.
6230
6231 (define_insn_and_split "*lea<mode>_general_1"
6232 [(set (match_operand:SWI12 0 "register_operand" "=r")
6233 (plus:SWI12
6234 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6235 (match_operand:SWI12 2 "register_operand" "r"))
6236 (match_operand:SWI12 3 "immediate_operand" "i")))]
6237 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6238 "#"
6239 "&& reload_completed"
6240 [(set (match_dup 0)
6241 (plus:SI
6242 (plus:SI (match_dup 1) (match_dup 2))
6243 (match_dup 3)))]
6244 {
6245 operands[0] = gen_lowpart (SImode, operands[0]);
6246 operands[1] = gen_lowpart (SImode, operands[1]);
6247 operands[2] = gen_lowpart (SImode, operands[2]);
6248 operands[3] = gen_lowpart (SImode, operands[3]);
6249 }
6250 [(set_attr "type" "lea")
6251 (set_attr "mode" "SI")])
6252
6253 (define_insn_and_split "*lea<mode>_general_2"
6254 [(set (match_operand:SWI12 0 "register_operand" "=r")
6255 (plus:SWI12
6256 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6257 (match_operand 2 "const248_operand" "n"))
6258 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6259 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6260 "#"
6261 "&& reload_completed"
6262 [(set (match_dup 0)
6263 (plus:SI
6264 (mult:SI (match_dup 1) (match_dup 2))
6265 (match_dup 3)))]
6266 {
6267 operands[0] = gen_lowpart (SImode, operands[0]);
6268 operands[1] = gen_lowpart (SImode, operands[1]);
6269 operands[3] = gen_lowpart (SImode, operands[3]);
6270 }
6271 [(set_attr "type" "lea")
6272 (set_attr "mode" "SI")])
6273
6274 (define_insn_and_split "*lea<mode>_general_2b"
6275 [(set (match_operand:SWI12 0 "register_operand" "=r")
6276 (plus:SWI12
6277 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6278 (match_operand 2 "const123_operand" "n"))
6279 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6280 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6281 "#"
6282 "&& reload_completed"
6283 [(set (match_dup 0)
6284 (plus:SI
6285 (ashift:SI (match_dup 1) (match_dup 2))
6286 (match_dup 3)))]
6287 {
6288 operands[0] = gen_lowpart (SImode, operands[0]);
6289 operands[1] = gen_lowpart (SImode, operands[1]);
6290 operands[3] = gen_lowpart (SImode, operands[3]);
6291 }
6292 [(set_attr "type" "lea")
6293 (set_attr "mode" "SI")])
6294
6295 (define_insn_and_split "*lea<mode>_general_3"
6296 [(set (match_operand:SWI12 0 "register_operand" "=r")
6297 (plus:SWI12
6298 (plus:SWI12
6299 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6300 (match_operand 2 "const248_operand" "n"))
6301 (match_operand:SWI12 3 "register_operand" "r"))
6302 (match_operand:SWI12 4 "immediate_operand" "i")))]
6303 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6304 "#"
6305 "&& reload_completed"
6306 [(set (match_dup 0)
6307 (plus:SI
6308 (plus:SI
6309 (mult:SI (match_dup 1) (match_dup 2))
6310 (match_dup 3))
6311 (match_dup 4)))]
6312 {
6313 operands[0] = gen_lowpart (SImode, operands[0]);
6314 operands[1] = gen_lowpart (SImode, operands[1]);
6315 operands[3] = gen_lowpart (SImode, operands[3]);
6316 operands[4] = gen_lowpart (SImode, operands[4]);
6317 }
6318 [(set_attr "type" "lea")
6319 (set_attr "mode" "SI")])
6320
6321 (define_insn_and_split "*lea<mode>_general_3b"
6322 [(set (match_operand:SWI12 0 "register_operand" "=r")
6323 (plus:SWI12
6324 (plus:SWI12
6325 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6326 (match_operand 2 "const123_operand" "n"))
6327 (match_operand:SWI12 3 "register_operand" "r"))
6328 (match_operand:SWI12 4 "immediate_operand" "i")))]
6329 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6330 "#"
6331 "&& reload_completed"
6332 [(set (match_dup 0)
6333 (plus:SI
6334 (plus:SI
6335 (ashift:SI (match_dup 1) (match_dup 2))
6336 (match_dup 3))
6337 (match_dup 4)))]
6338 {
6339 operands[0] = gen_lowpart (SImode, operands[0]);
6340 operands[1] = gen_lowpart (SImode, operands[1]);
6341 operands[3] = gen_lowpart (SImode, operands[3]);
6342 operands[4] = gen_lowpart (SImode, operands[4]);
6343 }
6344 [(set_attr "type" "lea")
6345 (set_attr "mode" "SI")])
6346
6347 (define_insn_and_split "*lea<mode>_general_4"
6348 [(set (match_operand:SWI12 0 "register_operand" "=r")
6349 (any_or:SWI12
6350 (ashift:SWI12
6351 (match_operand:SWI12 1 "index_register_operand" "l")
6352 (match_operand 2 "const_0_to_3_operand" "n"))
6353 (match_operand 3 "const_int_operand" "n")))]
6354 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6355 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6356 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6357 "#"
6358 "&& reload_completed"
6359 [(set (match_dup 0)
6360 (plus:SI
6361 (mult:SI (match_dup 1) (match_dup 2))
6362 (match_dup 3)))]
6363 {
6364 operands[0] = gen_lowpart (SImode, operands[0]);
6365 operands[1] = gen_lowpart (SImode, operands[1]);
6366 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6367 }
6368 [(set_attr "type" "lea")
6369 (set_attr "mode" "SI")])
6370
6371 (define_insn_and_split "*lea<mode>_general_4"
6372 [(set (match_operand:SWI48 0 "register_operand" "=r")
6373 (any_or:SWI48
6374 (ashift:SWI48
6375 (match_operand:SWI48 1 "index_register_operand" "l")
6376 (match_operand 2 "const_0_to_3_operand" "n"))
6377 (match_operand 3 "const_int_operand" "n")))]
6378 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6379 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6380 "#"
6381 "&& reload_completed"
6382 [(set (match_dup 0)
6383 (plus:SWI48
6384 (mult:SWI48 (match_dup 1) (match_dup 2))
6385 (match_dup 3)))]
6386 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6387 [(set_attr "type" "lea")
6388 (set_attr "mode" "<MODE>")])
6389 \f
6390 ;; Subtract instructions
6391
6392 (define_expand "sub<mode>3"
6393 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6394 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6395 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6396 ""
6397 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6398
6399 (define_insn_and_split "*sub<dwi>3_doubleword"
6400 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6401 (minus:<DWI>
6402 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6403 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6404 "ro<di>,r<di>")))
6405 (clobber (reg:CC FLAGS_REG))]
6406 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6407 "#"
6408 "reload_completed"
6409 [(parallel [(set (reg:CC FLAGS_REG)
6410 (compare:CC (match_dup 1) (match_dup 2)))
6411 (set (match_dup 0)
6412 (minus:DWIH (match_dup 1) (match_dup 2)))])
6413 (parallel [(set (match_dup 3)
6414 (minus:DWIH
6415 (minus:DWIH
6416 (match_dup 4)
6417 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6418 (match_dup 5)))
6419 (clobber (reg:CC FLAGS_REG))])]
6420 {
6421 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6422 if (operands[2] == const0_rtx)
6423 {
6424 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6425 DONE;
6426 }
6427 })
6428
6429 (define_insn "*sub<mode>_1"
6430 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6431 (minus:SWI
6432 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6433 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6434 (clobber (reg:CC FLAGS_REG))]
6435 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6436 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6437 [(set_attr "type" "alu")
6438 (set_attr "mode" "<MODE>")])
6439
6440 (define_insn "*subsi_1_zext"
6441 [(set (match_operand:DI 0 "register_operand" "=r")
6442 (zero_extend:DI
6443 (minus:SI (match_operand:SI 1 "register_operand" "0")
6444 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6445 (clobber (reg:CC FLAGS_REG))]
6446 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6447 "sub{l}\t{%2, %k0|%k0, %2}"
6448 [(set_attr "type" "alu")
6449 (set_attr "mode" "SI")])
6450
6451 (define_insn "*subqi_1_slp"
6452 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6453 (minus:QI (match_dup 0)
6454 (match_operand:QI 1 "general_operand" "qn,qm")))
6455 (clobber (reg:CC FLAGS_REG))]
6456 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6457 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6458 "sub{b}\t{%1, %0|%0, %1}"
6459 [(set_attr "type" "alu1")
6460 (set_attr "mode" "QI")])
6461
6462 (define_insn "*sub<mode>_2"
6463 [(set (reg FLAGS_REG)
6464 (compare
6465 (minus:SWI
6466 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6467 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6468 (const_int 0)))
6469 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6470 (minus:SWI (match_dup 1) (match_dup 2)))]
6471 "ix86_match_ccmode (insn, CCGOCmode)
6472 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6473 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6474 [(set_attr "type" "alu")
6475 (set_attr "mode" "<MODE>")])
6476
6477 (define_insn "*subsi_2_zext"
6478 [(set (reg FLAGS_REG)
6479 (compare
6480 (minus:SI (match_operand:SI 1 "register_operand" "0")
6481 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6482 (const_int 0)))
6483 (set (match_operand:DI 0 "register_operand" "=r")
6484 (zero_extend:DI
6485 (minus:SI (match_dup 1)
6486 (match_dup 2))))]
6487 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6488 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6489 "sub{l}\t{%2, %k0|%k0, %2}"
6490 [(set_attr "type" "alu")
6491 (set_attr "mode" "SI")])
6492
6493 ;; Subtract with jump on overflow.
6494 (define_expand "subv<mode>4"
6495 [(parallel [(set (reg:CCO FLAGS_REG)
6496 (eq:CCO (minus:<DWI>
6497 (sign_extend:<DWI>
6498 (match_operand:SWI 1 "nonimmediate_operand"))
6499 (match_dup 4))
6500 (sign_extend:<DWI>
6501 (minus:SWI (match_dup 1)
6502 (match_operand:SWI 2
6503 "<general_operand>")))))
6504 (set (match_operand:SWI 0 "register_operand")
6505 (minus:SWI (match_dup 1) (match_dup 2)))])
6506 (set (pc) (if_then_else
6507 (eq (reg:CCO FLAGS_REG) (const_int 0))
6508 (label_ref (match_operand 3))
6509 (pc)))]
6510 ""
6511 {
6512 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6513 if (CONST_INT_P (operands[2]))
6514 operands[4] = operands[2];
6515 else
6516 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6517 })
6518
6519 (define_insn "*subv<mode>4"
6520 [(set (reg:CCO FLAGS_REG)
6521 (eq:CCO (minus:<DWI>
6522 (sign_extend:<DWI>
6523 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6524 (sign_extend:<DWI>
6525 (match_operand:SWI 2 "<general_sext_operand>"
6526 "<r>We,<r>m")))
6527 (sign_extend:<DWI>
6528 (minus:SWI (match_dup 1) (match_dup 2)))))
6529 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6530 (minus:SWI (match_dup 1) (match_dup 2)))]
6531 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6532 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6533 [(set_attr "type" "alu")
6534 (set_attr "mode" "<MODE>")])
6535
6536 (define_insn "*subv<mode>4_1"
6537 [(set (reg:CCO FLAGS_REG)
6538 (eq:CCO (minus:<DWI>
6539 (sign_extend:<DWI>
6540 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6541 (match_operand:<DWI> 3 "const_int_operand" "i"))
6542 (sign_extend:<DWI>
6543 (minus:SWI (match_dup 1)
6544 (match_operand:SWI 2 "x86_64_immediate_operand"
6545 "<i>")))))
6546 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6547 (minus:SWI (match_dup 1) (match_dup 2)))]
6548 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6549 && CONST_INT_P (operands[2])
6550 && INTVAL (operands[2]) == INTVAL (operands[3])"
6551 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6552 [(set_attr "type" "alu")
6553 (set_attr "mode" "<MODE>")
6554 (set (attr "length_immediate")
6555 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6556 (const_string "1")
6557 (match_test "<MODE_SIZE> == 8")
6558 (const_string "4")]
6559 (const_string "<MODE_SIZE>")))])
6560
6561 (define_expand "usubv<mode>4"
6562 [(parallel [(set (reg:CC FLAGS_REG)
6563 (compare:CC
6564 (match_operand:SWI 1 "nonimmediate_operand")
6565 (match_operand:SWI 2 "<general_operand>")))
6566 (set (match_operand:SWI 0 "register_operand")
6567 (minus:SWI (match_dup 1) (match_dup 2)))])
6568 (set (pc) (if_then_else
6569 (ltu (reg:CC FLAGS_REG) (const_int 0))
6570 (label_ref (match_operand 3))
6571 (pc)))]
6572 ""
6573 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6574
6575 (define_insn "*sub<mode>_3"
6576 [(set (reg FLAGS_REG)
6577 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6578 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6579 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6580 (minus:SWI (match_dup 1) (match_dup 2)))]
6581 "ix86_match_ccmode (insn, CCmode)
6582 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6583 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6584 [(set_attr "type" "alu")
6585 (set_attr "mode" "<MODE>")])
6586
6587 (define_insn "*subsi_3_zext"
6588 [(set (reg FLAGS_REG)
6589 (compare (match_operand:SI 1 "register_operand" "0")
6590 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6591 (set (match_operand:DI 0 "register_operand" "=r")
6592 (zero_extend:DI
6593 (minus:SI (match_dup 1)
6594 (match_dup 2))))]
6595 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6596 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6597 "sub{l}\t{%2, %1|%1, %2}"
6598 [(set_attr "type" "alu")
6599 (set_attr "mode" "SI")])
6600 \f
6601 ;; Add with carry and subtract with borrow
6602
6603 (define_insn "add<mode>3_carry"
6604 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6605 (plus:SWI
6606 (plus:SWI
6607 (match_operator:SWI 4 "ix86_carry_flag_operator"
6608 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6609 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6610 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6613 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "use_carry" "1")
6616 (set_attr "pent_pair" "pu")
6617 (set_attr "mode" "<MODE>")])
6618
6619 (define_insn "*addsi3_carry_zext"
6620 [(set (match_operand:DI 0 "register_operand" "=r")
6621 (zero_extend:DI
6622 (plus:SI
6623 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6624 [(reg FLAGS_REG) (const_int 0)])
6625 (match_operand:SI 1 "register_operand" "%0"))
6626 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6627 (clobber (reg:CC FLAGS_REG))]
6628 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6629 "adc{l}\t{%2, %k0|%k0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "use_carry" "1")
6632 (set_attr "pent_pair" "pu")
6633 (set_attr "mode" "SI")])
6634
6635 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6636
6637 (define_insn "addcarry<mode>"
6638 [(set (reg:CCC FLAGS_REG)
6639 (compare:CCC
6640 (plus:SWI48
6641 (plus:SWI48
6642 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6643 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6644 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6645 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6646 (match_dup 1)))
6647 (set (match_operand:SWI48 0 "register_operand" "=r")
6648 (plus:SWI48 (plus:SWI48 (match_op_dup 4
6649 [(match_dup 3) (const_int 0)])
6650 (match_dup 1))
6651 (match_dup 2)))]
6652 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6653 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6654 [(set_attr "type" "alu")
6655 (set_attr "use_carry" "1")
6656 (set_attr "pent_pair" "pu")
6657 (set_attr "mode" "<MODE>")])
6658
6659 (define_insn "sub<mode>3_carry"
6660 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6661 (minus:SWI
6662 (minus:SWI
6663 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6664 (match_operator:SWI 4 "ix86_carry_flag_operator"
6665 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6666 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6667 (clobber (reg:CC FLAGS_REG))]
6668 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6669 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "use_carry" "1")
6672 (set_attr "pent_pair" "pu")
6673 (set_attr "mode" "<MODE>")])
6674
6675 (define_insn "*subsi3_carry_zext"
6676 [(set (match_operand:DI 0 "register_operand" "=r")
6677 (zero_extend:DI
6678 (minus:SI
6679 (minus:SI
6680 (match_operand:SI 1 "register_operand" "0")
6681 (match_operator:SI 3 "ix86_carry_flag_operator"
6682 [(reg FLAGS_REG) (const_int 0)]))
6683 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6684 (clobber (reg:CC FLAGS_REG))]
6685 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6686 "sbb{l}\t{%2, %k0|%k0, %2}"
6687 [(set_attr "type" "alu")
6688 (set_attr "use_carry" "1")
6689 (set_attr "pent_pair" "pu")
6690 (set_attr "mode" "SI")])
6691
6692 (define_insn "subborrow<mode>"
6693 [(set (reg:CCC FLAGS_REG)
6694 (compare:CCC
6695 (match_operand:SWI48 1 "nonimmediate_operand" "0")
6696 (plus:SWI48
6697 (match_operator:SWI48 4 "ix86_carry_flag_operator"
6698 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6699 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6700 (set (match_operand:SWI48 0 "register_operand" "=r")
6701 (minus:SWI48 (minus:SWI48 (match_dup 1)
6702 (match_op_dup 4
6703 [(match_dup 3) (const_int 0)]))
6704 (match_dup 2)))]
6705 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6706 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6707 [(set_attr "type" "alu")
6708 (set_attr "use_carry" "1")
6709 (set_attr "pent_pair" "pu")
6710 (set_attr "mode" "<MODE>")])
6711 \f
6712 ;; Overflow setting add instructions
6713
6714 (define_expand "addqi3_cconly_overflow"
6715 [(parallel
6716 [(set (reg:CCC FLAGS_REG)
6717 (compare:CCC
6718 (plus:QI
6719 (match_operand:QI 0 "nonimmediate_operand")
6720 (match_operand:QI 1 "general_operand"))
6721 (match_dup 0)))
6722 (clobber (match_scratch:QI 2))])]
6723 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6724
6725 (define_insn "*add<mode>3_cconly_overflow_1"
6726 [(set (reg:CCC FLAGS_REG)
6727 (compare:CCC
6728 (plus:SWI
6729 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6730 (match_operand:SWI 2 "<general_operand>" "<g>"))
6731 (match_dup 1)))
6732 (clobber (match_scratch:SWI 0 "=<r>"))]
6733 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6734 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6735 [(set_attr "type" "alu")
6736 (set_attr "mode" "<MODE>")])
6737
6738 (define_insn "*add<mode>3_cc_overflow_1"
6739 [(set (reg:CCC FLAGS_REG)
6740 (compare:CCC
6741 (plus:SWI
6742 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6743 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6744 (match_dup 1)))
6745 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6746 (plus:SWI (match_dup 1) (match_dup 2)))]
6747 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6748 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6749 [(set_attr "type" "alu")
6750 (set_attr "mode" "<MODE>")])
6751
6752 (define_insn "*addsi3_zext_cc_overflow_1"
6753 [(set (reg:CCC FLAGS_REG)
6754 (compare:CCC
6755 (plus:SI
6756 (match_operand:SI 1 "nonimmediate_operand" "%0")
6757 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6758 (match_dup 1)))
6759 (set (match_operand:DI 0 "register_operand" "=r")
6760 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6761 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6762 "add{l}\t{%2, %k0|%k0, %2}"
6763 [(set_attr "type" "alu")
6764 (set_attr "mode" "SI")])
6765
6766 (define_insn "*add<mode>3_cconly_overflow_2"
6767 [(set (reg:CCC FLAGS_REG)
6768 (compare:CCC
6769 (plus:SWI
6770 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6771 (match_operand:SWI 2 "<general_operand>" "<g>"))
6772 (match_dup 2)))
6773 (clobber (match_scratch:SWI 0 "=<r>"))]
6774 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6775 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6776 [(set_attr "type" "alu")
6777 (set_attr "mode" "<MODE>")])
6778
6779 (define_insn "*add<mode>3_cc_overflow_2"
6780 [(set (reg:CCC FLAGS_REG)
6781 (compare:CCC
6782 (plus:SWI
6783 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6784 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6785 (match_dup 2)))
6786 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6787 (plus:SWI (match_dup 1) (match_dup 2)))]
6788 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6789 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6790 [(set_attr "type" "alu")
6791 (set_attr "mode" "<MODE>")])
6792
6793 (define_insn "*addsi3_zext_cc_overflow_2"
6794 [(set (reg:CCC FLAGS_REG)
6795 (compare:CCC
6796 (plus:SI
6797 (match_operand:SI 1 "nonimmediate_operand" "%0")
6798 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6799 (match_dup 2)))
6800 (set (match_operand:DI 0 "register_operand" "=r")
6801 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6802 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6803 "add{l}\t{%2, %k0|%k0, %2}"
6804 [(set_attr "type" "alu")
6805 (set_attr "mode" "SI")])
6806
6807 ;; The patterns that match these are at the end of this file.
6808
6809 (define_expand "<plusminus_insn>xf3"
6810 [(set (match_operand:XF 0 "register_operand")
6811 (plusminus:XF
6812 (match_operand:XF 1 "register_operand")
6813 (match_operand:XF 2 "register_operand")))]
6814 "TARGET_80387")
6815
6816 (define_expand "<plusminus_insn><mode>3"
6817 [(set (match_operand:MODEF 0 "register_operand")
6818 (plusminus:MODEF
6819 (match_operand:MODEF 1 "register_operand")
6820 (match_operand:MODEF 2 "nonimmediate_operand")))]
6821 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6822 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6823 \f
6824 ;; Multiply instructions
6825
6826 (define_expand "mul<mode>3"
6827 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6828 (mult:SWIM248
6829 (match_operand:SWIM248 1 "register_operand")
6830 (match_operand:SWIM248 2 "<general_operand>")))
6831 (clobber (reg:CC FLAGS_REG))])])
6832
6833 (define_expand "mulqi3"
6834 [(parallel [(set (match_operand:QI 0 "register_operand")
6835 (mult:QI
6836 (match_operand:QI 1 "register_operand")
6837 (match_operand:QI 2 "nonimmediate_operand")))
6838 (clobber (reg:CC FLAGS_REG))])]
6839 "TARGET_QIMODE_MATH")
6840
6841 ;; On AMDFAM10
6842 ;; IMUL reg32/64, reg32/64, imm8 Direct
6843 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6844 ;; IMUL reg32/64, reg32/64, imm32 Direct
6845 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6846 ;; IMUL reg32/64, reg32/64 Direct
6847 ;; IMUL reg32/64, mem32/64 Direct
6848 ;;
6849 ;; On BDVER1, all above IMULs use DirectPath
6850 ;;
6851 ;; On AMDFAM10
6852 ;; IMUL reg16, reg16, imm8 VectorPath
6853 ;; IMUL reg16, mem16, imm8 VectorPath
6854 ;; IMUL reg16, reg16, imm16 VectorPath
6855 ;; IMUL reg16, mem16, imm16 VectorPath
6856 ;; IMUL reg16, reg16 Direct
6857 ;; IMUL reg16, mem16 Direct
6858 ;;
6859 ;; On BDVER1, all HI MULs use DoublePath
6860
6861 (define_insn "*mul<mode>3_1"
6862 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6863 (mult:SWIM248
6864 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6865 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6866 (clobber (reg:CC FLAGS_REG))]
6867 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6868 "@
6869 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6870 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6871 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6872 [(set_attr "type" "imul")
6873 (set_attr "prefix_0f" "0,0,1")
6874 (set (attr "athlon_decode")
6875 (cond [(eq_attr "cpu" "athlon")
6876 (const_string "vector")
6877 (eq_attr "alternative" "1")
6878 (const_string "vector")
6879 (and (eq_attr "alternative" "2")
6880 (ior (match_test "<MODE>mode == HImode")
6881 (match_operand 1 "memory_operand")))
6882 (const_string "vector")]
6883 (const_string "direct")))
6884 (set (attr "amdfam10_decode")
6885 (cond [(and (eq_attr "alternative" "0,1")
6886 (ior (match_test "<MODE>mode == HImode")
6887 (match_operand 1 "memory_operand")))
6888 (const_string "vector")]
6889 (const_string "direct")))
6890 (set (attr "bdver1_decode")
6891 (if_then_else
6892 (match_test "<MODE>mode == HImode")
6893 (const_string "double")
6894 (const_string "direct")))
6895 (set_attr "mode" "<MODE>")])
6896
6897 (define_insn "*mulsi3_1_zext"
6898 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6899 (zero_extend:DI
6900 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6901 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6902 (clobber (reg:CC FLAGS_REG))]
6903 "TARGET_64BIT
6904 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6905 "@
6906 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6907 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6908 imul{l}\t{%2, %k0|%k0, %2}"
6909 [(set_attr "type" "imul")
6910 (set_attr "prefix_0f" "0,0,1")
6911 (set (attr "athlon_decode")
6912 (cond [(eq_attr "cpu" "athlon")
6913 (const_string "vector")
6914 (eq_attr "alternative" "1")
6915 (const_string "vector")
6916 (and (eq_attr "alternative" "2")
6917 (match_operand 1 "memory_operand"))
6918 (const_string "vector")]
6919 (const_string "direct")))
6920 (set (attr "amdfam10_decode")
6921 (cond [(and (eq_attr "alternative" "0,1")
6922 (match_operand 1 "memory_operand"))
6923 (const_string "vector")]
6924 (const_string "direct")))
6925 (set_attr "bdver1_decode" "direct")
6926 (set_attr "mode" "SI")])
6927
6928 ;;On AMDFAM10 and BDVER1
6929 ;; MUL reg8 Direct
6930 ;; MUL mem8 Direct
6931
6932 (define_insn "*mulqi3_1"
6933 [(set (match_operand:QI 0 "register_operand" "=a")
6934 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6935 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6936 (clobber (reg:CC FLAGS_REG))]
6937 "TARGET_QIMODE_MATH
6938 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6939 "mul{b}\t%2"
6940 [(set_attr "type" "imul")
6941 (set_attr "length_immediate" "0")
6942 (set (attr "athlon_decode")
6943 (if_then_else (eq_attr "cpu" "athlon")
6944 (const_string "vector")
6945 (const_string "direct")))
6946 (set_attr "amdfam10_decode" "direct")
6947 (set_attr "bdver1_decode" "direct")
6948 (set_attr "mode" "QI")])
6949
6950 ;; Multiply with jump on overflow.
6951 (define_expand "mulv<mode>4"
6952 [(parallel [(set (reg:CCO FLAGS_REG)
6953 (eq:CCO (mult:<DWI>
6954 (sign_extend:<DWI>
6955 (match_operand:SWI248 1 "register_operand"))
6956 (match_dup 4))
6957 (sign_extend:<DWI>
6958 (mult:SWI248 (match_dup 1)
6959 (match_operand:SWI248 2
6960 "<general_operand>")))))
6961 (set (match_operand:SWI248 0 "register_operand")
6962 (mult:SWI248 (match_dup 1) (match_dup 2)))])
6963 (set (pc) (if_then_else
6964 (eq (reg:CCO FLAGS_REG) (const_int 0))
6965 (label_ref (match_operand 3))
6966 (pc)))]
6967 ""
6968 {
6969 if (CONST_INT_P (operands[2]))
6970 operands[4] = operands[2];
6971 else
6972 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6973 })
6974
6975 (define_insn "*mulv<mode>4"
6976 [(set (reg:CCO FLAGS_REG)
6977 (eq:CCO (mult:<DWI>
6978 (sign_extend:<DWI>
6979 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6980 (sign_extend:<DWI>
6981 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6982 (sign_extend:<DWI>
6983 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6984 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6985 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6986 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6987 "@
6988 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6989 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6990 [(set_attr "type" "imul")
6991 (set_attr "prefix_0f" "0,1")
6992 (set (attr "athlon_decode")
6993 (cond [(eq_attr "cpu" "athlon")
6994 (const_string "vector")
6995 (eq_attr "alternative" "0")
6996 (const_string "vector")
6997 (and (eq_attr "alternative" "1")
6998 (match_operand 1 "memory_operand"))
6999 (const_string "vector")]
7000 (const_string "direct")))
7001 (set (attr "amdfam10_decode")
7002 (cond [(and (eq_attr "alternative" "1")
7003 (match_operand 1 "memory_operand"))
7004 (const_string "vector")]
7005 (const_string "direct")))
7006 (set_attr "bdver1_decode" "direct")
7007 (set_attr "mode" "<MODE>")])
7008
7009 (define_insn "*mulvhi4"
7010 [(set (reg:CCO FLAGS_REG)
7011 (eq:CCO (mult:SI
7012 (sign_extend:SI
7013 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7014 (sign_extend:SI
7015 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7016 (sign_extend:SI
7017 (mult:HI (match_dup 1) (match_dup 2)))))
7018 (set (match_operand:HI 0 "register_operand" "=r")
7019 (mult:HI (match_dup 1) (match_dup 2)))]
7020 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7021 "imul{w}\t{%2, %0|%0, %2}"
7022 [(set_attr "type" "imul")
7023 (set_attr "prefix_0f" "1")
7024 (set_attr "athlon_decode" "vector")
7025 (set_attr "amdfam10_decode" "direct")
7026 (set_attr "bdver1_decode" "double")
7027 (set_attr "mode" "HI")])
7028
7029 (define_insn "*mulv<mode>4_1"
7030 [(set (reg:CCO FLAGS_REG)
7031 (eq:CCO (mult:<DWI>
7032 (sign_extend:<DWI>
7033 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7034 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7035 (sign_extend:<DWI>
7036 (mult:SWI248 (match_dup 1)
7037 (match_operand:SWI248 2
7038 "<immediate_operand>" "K,<i>")))))
7039 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7040 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7041 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7042 && CONST_INT_P (operands[2])
7043 && INTVAL (operands[2]) == INTVAL (operands[3])"
7044 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7045 [(set_attr "type" "imul")
7046 (set (attr "prefix_0f")
7047 (if_then_else
7048 (match_test "<MODE>mode == HImode")
7049 (const_string "0")
7050 (const_string "*")))
7051 (set (attr "athlon_decode")
7052 (cond [(eq_attr "cpu" "athlon")
7053 (const_string "vector")
7054 (eq_attr "alternative" "1")
7055 (const_string "vector")]
7056 (const_string "direct")))
7057 (set (attr "amdfam10_decode")
7058 (cond [(ior (match_test "<MODE>mode == HImode")
7059 (match_operand 1 "memory_operand"))
7060 (const_string "vector")]
7061 (const_string "direct")))
7062 (set (attr "bdver1_decode")
7063 (if_then_else
7064 (match_test "<MODE>mode == HImode")
7065 (const_string "double")
7066 (const_string "direct")))
7067 (set_attr "mode" "<MODE>")
7068 (set (attr "length_immediate")
7069 (cond [(eq_attr "alternative" "0")
7070 (const_string "1")
7071 (match_test "<MODE_SIZE> == 8")
7072 (const_string "4")]
7073 (const_string "<MODE_SIZE>")))])
7074
7075 (define_expand "umulv<mode>4"
7076 [(parallel [(set (reg:CCO FLAGS_REG)
7077 (eq:CCO (mult:<DWI>
7078 (zero_extend:<DWI>
7079 (match_operand:SWI248 1
7080 "nonimmediate_operand"))
7081 (zero_extend:<DWI>
7082 (match_operand:SWI248 2
7083 "nonimmediate_operand")))
7084 (zero_extend:<DWI>
7085 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7086 (set (match_operand:SWI248 0 "register_operand")
7087 (mult:SWI248 (match_dup 1) (match_dup 2)))
7088 (clobber (match_scratch:SWI248 4))])
7089 (set (pc) (if_then_else
7090 (eq (reg:CCO FLAGS_REG) (const_int 0))
7091 (label_ref (match_operand 3))
7092 (pc)))]
7093 ""
7094 {
7095 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7096 operands[1] = force_reg (<MODE>mode, operands[1]);
7097 })
7098
7099 (define_insn "*umulv<mode>4"
7100 [(set (reg:CCO FLAGS_REG)
7101 (eq:CCO (mult:<DWI>
7102 (zero_extend:<DWI>
7103 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7104 (zero_extend:<DWI>
7105 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7106 (zero_extend:<DWI>
7107 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7108 (set (match_operand:SWI248 0 "register_operand" "=a")
7109 (mult:SWI248 (match_dup 1) (match_dup 2)))
7110 (clobber (match_scratch:SWI248 3 "=d"))]
7111 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7112 "mul{<imodesuffix>}\t%2"
7113 [(set_attr "type" "imul")
7114 (set_attr "length_immediate" "0")
7115 (set (attr "athlon_decode")
7116 (if_then_else (eq_attr "cpu" "athlon")
7117 (const_string "vector")
7118 (const_string "double")))
7119 (set_attr "amdfam10_decode" "double")
7120 (set_attr "bdver1_decode" "direct")
7121 (set_attr "mode" "<MODE>")])
7122
7123 (define_expand "<u>mulvqi4"
7124 [(parallel [(set (reg:CCO FLAGS_REG)
7125 (eq:CCO (mult:HI
7126 (any_extend:HI
7127 (match_operand:QI 1 "nonimmediate_operand"))
7128 (any_extend:HI
7129 (match_operand:QI 2 "nonimmediate_operand")))
7130 (any_extend:HI
7131 (mult:QI (match_dup 1) (match_dup 2)))))
7132 (set (match_operand:QI 0 "register_operand")
7133 (mult:QI (match_dup 1) (match_dup 2)))])
7134 (set (pc) (if_then_else
7135 (eq (reg:CCO FLAGS_REG) (const_int 0))
7136 (label_ref (match_operand 3))
7137 (pc)))]
7138 "TARGET_QIMODE_MATH"
7139 {
7140 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7141 operands[1] = force_reg (QImode, operands[1]);
7142 })
7143
7144 (define_insn "*<u>mulvqi4"
7145 [(set (reg:CCO FLAGS_REG)
7146 (eq:CCO (mult:HI
7147 (any_extend:HI
7148 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7149 (any_extend:HI
7150 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7151 (any_extend:HI
7152 (mult:QI (match_dup 1) (match_dup 2)))))
7153 (set (match_operand:QI 0 "register_operand" "=a")
7154 (mult:QI (match_dup 1) (match_dup 2)))]
7155 "TARGET_QIMODE_MATH
7156 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7157 "<sgnprefix>mul{b}\t%2"
7158 [(set_attr "type" "imul")
7159 (set_attr "length_immediate" "0")
7160 (set (attr "athlon_decode")
7161 (if_then_else (eq_attr "cpu" "athlon")
7162 (const_string "vector")
7163 (const_string "direct")))
7164 (set_attr "amdfam10_decode" "direct")
7165 (set_attr "bdver1_decode" "direct")
7166 (set_attr "mode" "QI")])
7167
7168 (define_expand "<u>mul<mode><dwi>3"
7169 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7170 (mult:<DWI>
7171 (any_extend:<DWI>
7172 (match_operand:DWIH 1 "nonimmediate_operand"))
7173 (any_extend:<DWI>
7174 (match_operand:DWIH 2 "register_operand"))))
7175 (clobber (reg:CC FLAGS_REG))])])
7176
7177 (define_expand "<u>mulqihi3"
7178 [(parallel [(set (match_operand:HI 0 "register_operand")
7179 (mult:HI
7180 (any_extend:HI
7181 (match_operand:QI 1 "nonimmediate_operand"))
7182 (any_extend:HI
7183 (match_operand:QI 2 "register_operand"))))
7184 (clobber (reg:CC FLAGS_REG))])]
7185 "TARGET_QIMODE_MATH")
7186
7187 (define_insn "*bmi2_umul<mode><dwi>3_1"
7188 [(set (match_operand:DWIH 0 "register_operand" "=r")
7189 (mult:DWIH
7190 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7191 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7192 (set (match_operand:DWIH 1 "register_operand" "=r")
7193 (truncate:DWIH
7194 (lshiftrt:<DWI>
7195 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7196 (zero_extend:<DWI> (match_dup 3)))
7197 (match_operand:QI 4 "const_int_operand" "n"))))]
7198 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7199 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7200 "mulx\t{%3, %0, %1|%1, %0, %3}"
7201 [(set_attr "type" "imulx")
7202 (set_attr "prefix" "vex")
7203 (set_attr "mode" "<MODE>")])
7204
7205 (define_insn "*umul<mode><dwi>3_1"
7206 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7207 (mult:<DWI>
7208 (zero_extend:<DWI>
7209 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7210 (zero_extend:<DWI>
7211 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7212 (clobber (reg:CC FLAGS_REG))]
7213 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7214 "@
7215 #
7216 mul{<imodesuffix>}\t%2"
7217 [(set_attr "isa" "bmi2,*")
7218 (set_attr "type" "imulx,imul")
7219 (set_attr "length_immediate" "*,0")
7220 (set (attr "athlon_decode")
7221 (cond [(eq_attr "alternative" "1")
7222 (if_then_else (eq_attr "cpu" "athlon")
7223 (const_string "vector")
7224 (const_string "double"))]
7225 (const_string "*")))
7226 (set_attr "amdfam10_decode" "*,double")
7227 (set_attr "bdver1_decode" "*,direct")
7228 (set_attr "prefix" "vex,orig")
7229 (set_attr "mode" "<MODE>")])
7230
7231 ;; Convert mul to the mulx pattern to avoid flags dependency.
7232 (define_split
7233 [(set (match_operand:<DWI> 0 "register_operand")
7234 (mult:<DWI>
7235 (zero_extend:<DWI>
7236 (match_operand:DWIH 1 "register_operand"))
7237 (zero_extend:<DWI>
7238 (match_operand:DWIH 2 "nonimmediate_operand"))))
7239 (clobber (reg:CC FLAGS_REG))]
7240 "TARGET_BMI2 && reload_completed
7241 && REGNO (operands[1]) == DX_REG"
7242 [(parallel [(set (match_dup 3)
7243 (mult:DWIH (match_dup 1) (match_dup 2)))
7244 (set (match_dup 4)
7245 (truncate:DWIH
7246 (lshiftrt:<DWI>
7247 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7248 (zero_extend:<DWI> (match_dup 2)))
7249 (match_dup 5))))])]
7250 {
7251 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7252
7253 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7254 })
7255
7256 (define_insn "*mul<mode><dwi>3_1"
7257 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7258 (mult:<DWI>
7259 (sign_extend:<DWI>
7260 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7261 (sign_extend:<DWI>
7262 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7263 (clobber (reg:CC FLAGS_REG))]
7264 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7265 "imul{<imodesuffix>}\t%2"
7266 [(set_attr "type" "imul")
7267 (set_attr "length_immediate" "0")
7268 (set (attr "athlon_decode")
7269 (if_then_else (eq_attr "cpu" "athlon")
7270 (const_string "vector")
7271 (const_string "double")))
7272 (set_attr "amdfam10_decode" "double")
7273 (set_attr "bdver1_decode" "direct")
7274 (set_attr "mode" "<MODE>")])
7275
7276 (define_insn "*<u>mulqihi3_1"
7277 [(set (match_operand:HI 0 "register_operand" "=a")
7278 (mult:HI
7279 (any_extend:HI
7280 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7281 (any_extend:HI
7282 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7283 (clobber (reg:CC FLAGS_REG))]
7284 "TARGET_QIMODE_MATH
7285 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7286 "<sgnprefix>mul{b}\t%2"
7287 [(set_attr "type" "imul")
7288 (set_attr "length_immediate" "0")
7289 (set (attr "athlon_decode")
7290 (if_then_else (eq_attr "cpu" "athlon")
7291 (const_string "vector")
7292 (const_string "direct")))
7293 (set_attr "amdfam10_decode" "direct")
7294 (set_attr "bdver1_decode" "direct")
7295 (set_attr "mode" "QI")])
7296
7297 (define_expand "<s>mul<mode>3_highpart"
7298 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7299 (truncate:SWI48
7300 (lshiftrt:<DWI>
7301 (mult:<DWI>
7302 (any_extend:<DWI>
7303 (match_operand:SWI48 1 "nonimmediate_operand"))
7304 (any_extend:<DWI>
7305 (match_operand:SWI48 2 "register_operand")))
7306 (match_dup 4))))
7307 (clobber (match_scratch:SWI48 3))
7308 (clobber (reg:CC FLAGS_REG))])]
7309 ""
7310 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7311
7312 (define_insn "*<s>muldi3_highpart_1"
7313 [(set (match_operand:DI 0 "register_operand" "=d")
7314 (truncate:DI
7315 (lshiftrt:TI
7316 (mult:TI
7317 (any_extend:TI
7318 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7319 (any_extend:TI
7320 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7321 (const_int 64))))
7322 (clobber (match_scratch:DI 3 "=1"))
7323 (clobber (reg:CC FLAGS_REG))]
7324 "TARGET_64BIT
7325 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7326 "<sgnprefix>mul{q}\t%2"
7327 [(set_attr "type" "imul")
7328 (set_attr "length_immediate" "0")
7329 (set (attr "athlon_decode")
7330 (if_then_else (eq_attr "cpu" "athlon")
7331 (const_string "vector")
7332 (const_string "double")))
7333 (set_attr "amdfam10_decode" "double")
7334 (set_attr "bdver1_decode" "direct")
7335 (set_attr "mode" "DI")])
7336
7337 (define_insn "*<s>mulsi3_highpart_zext"
7338 [(set (match_operand:DI 0 "register_operand" "=d")
7339 (zero_extend:DI (truncate:SI
7340 (lshiftrt:DI
7341 (mult:DI (any_extend:DI
7342 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7343 (any_extend:DI
7344 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7345 (const_int 32)))))
7346 (clobber (match_scratch:SI 3 "=1"))
7347 (clobber (reg:CC FLAGS_REG))]
7348 "TARGET_64BIT
7349 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7350 "<sgnprefix>mul{l}\t%2"
7351 [(set_attr "type" "imul")
7352 (set_attr "length_immediate" "0")
7353 (set (attr "athlon_decode")
7354 (if_then_else (eq_attr "cpu" "athlon")
7355 (const_string "vector")
7356 (const_string "double")))
7357 (set_attr "amdfam10_decode" "double")
7358 (set_attr "bdver1_decode" "direct")
7359 (set_attr "mode" "SI")])
7360
7361 (define_insn "*<s>mulsi3_highpart_1"
7362 [(set (match_operand:SI 0 "register_operand" "=d")
7363 (truncate:SI
7364 (lshiftrt:DI
7365 (mult:DI
7366 (any_extend:DI
7367 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7368 (any_extend:DI
7369 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7370 (const_int 32))))
7371 (clobber (match_scratch:SI 3 "=1"))
7372 (clobber (reg:CC FLAGS_REG))]
7373 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7374 "<sgnprefix>mul{l}\t%2"
7375 [(set_attr "type" "imul")
7376 (set_attr "length_immediate" "0")
7377 (set (attr "athlon_decode")
7378 (if_then_else (eq_attr "cpu" "athlon")
7379 (const_string "vector")
7380 (const_string "double")))
7381 (set_attr "amdfam10_decode" "double")
7382 (set_attr "bdver1_decode" "direct")
7383 (set_attr "mode" "SI")])
7384
7385 ;; The patterns that match these are at the end of this file.
7386
7387 (define_expand "mulxf3"
7388 [(set (match_operand:XF 0 "register_operand")
7389 (mult:XF (match_operand:XF 1 "register_operand")
7390 (match_operand:XF 2 "register_operand")))]
7391 "TARGET_80387")
7392
7393 (define_expand "mul<mode>3"
7394 [(set (match_operand:MODEF 0 "register_operand")
7395 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7396 (match_operand:MODEF 2 "nonimmediate_operand")))]
7397 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7398 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7399 \f
7400 ;; Divide instructions
7401
7402 ;; The patterns that match these are at the end of this file.
7403
7404 (define_expand "divxf3"
7405 [(set (match_operand:XF 0 "register_operand")
7406 (div:XF (match_operand:XF 1 "register_operand")
7407 (match_operand:XF 2 "register_operand")))]
7408 "TARGET_80387")
7409
7410 (define_expand "divdf3"
7411 [(set (match_operand:DF 0 "register_operand")
7412 (div:DF (match_operand:DF 1 "register_operand")
7413 (match_operand:DF 2 "nonimmediate_operand")))]
7414 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7415 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7416
7417 (define_expand "divsf3"
7418 [(set (match_operand:SF 0 "register_operand")
7419 (div:SF (match_operand:SF 1 "register_operand")
7420 (match_operand:SF 2 "nonimmediate_operand")))]
7421 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7422 || TARGET_SSE_MATH"
7423 {
7424 if (TARGET_SSE_MATH
7425 && TARGET_RECIP_DIV
7426 && optimize_insn_for_speed_p ()
7427 && flag_finite_math_only && !flag_trapping_math
7428 && flag_unsafe_math_optimizations)
7429 {
7430 ix86_emit_swdivsf (operands[0], operands[1],
7431 operands[2], SFmode);
7432 DONE;
7433 }
7434 })
7435 \f
7436 ;; Divmod instructions.
7437
7438 (define_expand "divmod<mode>4"
7439 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7440 (div:SWIM248
7441 (match_operand:SWIM248 1 "register_operand")
7442 (match_operand:SWIM248 2 "nonimmediate_operand")))
7443 (set (match_operand:SWIM248 3 "register_operand")
7444 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7445 (clobber (reg:CC FLAGS_REG))])])
7446
7447 ;; Split with 8bit unsigned divide:
7448 ;; if (dividend an divisor are in [0-255])
7449 ;; use 8bit unsigned integer divide
7450 ;; else
7451 ;; use original integer divide
7452 (define_split
7453 [(set (match_operand:SWI48 0 "register_operand")
7454 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7455 (match_operand:SWI48 3 "nonimmediate_operand")))
7456 (set (match_operand:SWI48 1 "register_operand")
7457 (mod:SWI48 (match_dup 2) (match_dup 3)))
7458 (clobber (reg:CC FLAGS_REG))]
7459 "TARGET_USE_8BIT_IDIV
7460 && TARGET_QIMODE_MATH
7461 && can_create_pseudo_p ()
7462 && !optimize_insn_for_size_p ()"
7463 [(const_int 0)]
7464 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7465
7466 (define_insn_and_split "divmod<mode>4_1"
7467 [(set (match_operand:SWI48 0 "register_operand" "=a")
7468 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7469 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7470 (set (match_operand:SWI48 1 "register_operand" "=&d")
7471 (mod:SWI48 (match_dup 2) (match_dup 3)))
7472 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7473 (clobber (reg:CC FLAGS_REG))]
7474 ""
7475 "#"
7476 "reload_completed"
7477 [(parallel [(set (match_dup 1)
7478 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7479 (clobber (reg:CC FLAGS_REG))])
7480 (parallel [(set (match_dup 0)
7481 (div:SWI48 (match_dup 2) (match_dup 3)))
7482 (set (match_dup 1)
7483 (mod:SWI48 (match_dup 2) (match_dup 3)))
7484 (use (match_dup 1))
7485 (clobber (reg:CC FLAGS_REG))])]
7486 {
7487 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7488
7489 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7490 operands[4] = operands[2];
7491 else
7492 {
7493 /* Avoid use of cltd in favor of a mov+shift. */
7494 emit_move_insn (operands[1], operands[2]);
7495 operands[4] = operands[1];
7496 }
7497 }
7498 [(set_attr "type" "multi")
7499 (set_attr "mode" "<MODE>")])
7500
7501 (define_insn_and_split "*divmod<mode>4"
7502 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7503 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7504 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7505 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7506 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7507 (clobber (reg:CC FLAGS_REG))]
7508 ""
7509 "#"
7510 "reload_completed"
7511 [(parallel [(set (match_dup 1)
7512 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7513 (clobber (reg:CC FLAGS_REG))])
7514 (parallel [(set (match_dup 0)
7515 (div:SWIM248 (match_dup 2) (match_dup 3)))
7516 (set (match_dup 1)
7517 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7518 (use (match_dup 1))
7519 (clobber (reg:CC FLAGS_REG))])]
7520 {
7521 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7522
7523 if (<MODE>mode != HImode
7524 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7525 operands[4] = operands[2];
7526 else
7527 {
7528 /* Avoid use of cltd in favor of a mov+shift. */
7529 emit_move_insn (operands[1], operands[2]);
7530 operands[4] = operands[1];
7531 }
7532 }
7533 [(set_attr "type" "multi")
7534 (set_attr "mode" "<MODE>")])
7535
7536 (define_insn "*divmod<mode>4_noext"
7537 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7538 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7539 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7540 (set (match_operand:SWIM248 1 "register_operand" "=d")
7541 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7542 (use (match_operand:SWIM248 4 "register_operand" "1"))
7543 (clobber (reg:CC FLAGS_REG))]
7544 ""
7545 "idiv{<imodesuffix>}\t%3"
7546 [(set_attr "type" "idiv")
7547 (set_attr "mode" "<MODE>")])
7548
7549 (define_expand "divmodqi4"
7550 [(parallel [(set (match_operand:QI 0 "register_operand")
7551 (div:QI
7552 (match_operand:QI 1 "register_operand")
7553 (match_operand:QI 2 "nonimmediate_operand")))
7554 (set (match_operand:QI 3 "register_operand")
7555 (mod:QI (match_dup 1) (match_dup 2)))
7556 (clobber (reg:CC FLAGS_REG))])]
7557 "TARGET_QIMODE_MATH"
7558 {
7559 rtx div, mod;
7560 rtx tmp0, tmp1;
7561
7562 tmp0 = gen_reg_rtx (HImode);
7563 tmp1 = gen_reg_rtx (HImode);
7564
7565 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
7566 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7567 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7568
7569 /* Extract remainder from AH. */
7570 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7571 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7572 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7573
7574 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7575 set_unique_reg_note (insn, REG_EQUAL, mod);
7576
7577 /* Extract quotient from AL. */
7578 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7579
7580 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7581 set_unique_reg_note (insn, REG_EQUAL, div);
7582
7583 DONE;
7584 })
7585
7586 ;; Divide AX by r/m8, with result stored in
7587 ;; AL <- Quotient
7588 ;; AH <- Remainder
7589 ;; Change div/mod to HImode and extend the second argument to HImode
7590 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7591 ;; combine may fail.
7592 (define_insn "divmodhiqi3"
7593 [(set (match_operand:HI 0 "register_operand" "=a")
7594 (ior:HI
7595 (ashift:HI
7596 (zero_extend:HI
7597 (truncate:QI
7598 (mod:HI (match_operand:HI 1 "register_operand" "0")
7599 (sign_extend:HI
7600 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7601 (const_int 8))
7602 (zero_extend:HI
7603 (truncate:QI
7604 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7605 (clobber (reg:CC FLAGS_REG))]
7606 "TARGET_QIMODE_MATH"
7607 "idiv{b}\t%2"
7608 [(set_attr "type" "idiv")
7609 (set_attr "mode" "QI")])
7610
7611 (define_expand "udivmod<mode>4"
7612 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7613 (udiv:SWIM248
7614 (match_operand:SWIM248 1 "register_operand")
7615 (match_operand:SWIM248 2 "nonimmediate_operand")))
7616 (set (match_operand:SWIM248 3 "register_operand")
7617 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7618 (clobber (reg:CC FLAGS_REG))])])
7619
7620 ;; Split with 8bit unsigned divide:
7621 ;; if (dividend an divisor are in [0-255])
7622 ;; use 8bit unsigned integer divide
7623 ;; else
7624 ;; use original integer divide
7625 (define_split
7626 [(set (match_operand:SWI48 0 "register_operand")
7627 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7628 (match_operand:SWI48 3 "nonimmediate_operand")))
7629 (set (match_operand:SWI48 1 "register_operand")
7630 (umod:SWI48 (match_dup 2) (match_dup 3)))
7631 (clobber (reg:CC FLAGS_REG))]
7632 "TARGET_USE_8BIT_IDIV
7633 && TARGET_QIMODE_MATH
7634 && can_create_pseudo_p ()
7635 && !optimize_insn_for_size_p ()"
7636 [(const_int 0)]
7637 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7638
7639 (define_insn_and_split "udivmod<mode>4_1"
7640 [(set (match_operand:SWI48 0 "register_operand" "=a")
7641 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7642 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7643 (set (match_operand:SWI48 1 "register_operand" "=&d")
7644 (umod:SWI48 (match_dup 2) (match_dup 3)))
7645 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7646 (clobber (reg:CC FLAGS_REG))]
7647 ""
7648 "#"
7649 "reload_completed"
7650 [(set (match_dup 1) (const_int 0))
7651 (parallel [(set (match_dup 0)
7652 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7653 (set (match_dup 1)
7654 (umod:SWI48 (match_dup 2) (match_dup 3)))
7655 (use (match_dup 1))
7656 (clobber (reg:CC FLAGS_REG))])]
7657 ""
7658 [(set_attr "type" "multi")
7659 (set_attr "mode" "<MODE>")])
7660
7661 (define_insn_and_split "*udivmod<mode>4"
7662 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7663 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7664 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7665 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7666 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7667 (clobber (reg:CC FLAGS_REG))]
7668 ""
7669 "#"
7670 "reload_completed"
7671 [(set (match_dup 1) (const_int 0))
7672 (parallel [(set (match_dup 0)
7673 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7674 (set (match_dup 1)
7675 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7676 (use (match_dup 1))
7677 (clobber (reg:CC FLAGS_REG))])]
7678 ""
7679 [(set_attr "type" "multi")
7680 (set_attr "mode" "<MODE>")])
7681
7682 ;; Optimize division or modulo by constant power of 2, if the constant
7683 ;; materializes only after expansion.
7684 (define_insn_and_split "*udivmod<mode>4_pow2"
7685 [(set (match_operand:SWI48 0 "register_operand" "=r")
7686 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7687 (match_operand:SWI48 3 "const_int_operand" "n")))
7688 (set (match_operand:SWI48 1 "register_operand" "=r")
7689 (umod:SWI48 (match_dup 2) (match_dup 3)))
7690 (clobber (reg:CC FLAGS_REG))]
7691 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7692 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7693 "#"
7694 "&& 1"
7695 [(set (match_dup 1) (match_dup 2))
7696 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7697 (clobber (reg:CC FLAGS_REG))])
7698 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7699 (clobber (reg:CC FLAGS_REG))])]
7700 {
7701 int v = exact_log2 (UINTVAL (operands[3]));
7702 operands[4] = GEN_INT (v);
7703 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7704 }
7705 [(set_attr "type" "multi")
7706 (set_attr "mode" "<MODE>")])
7707
7708 (define_insn "*udivmod<mode>4_noext"
7709 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7710 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7711 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7712 (set (match_operand:SWIM248 1 "register_operand" "=d")
7713 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7714 (use (match_operand:SWIM248 4 "register_operand" "1"))
7715 (clobber (reg:CC FLAGS_REG))]
7716 ""
7717 "div{<imodesuffix>}\t%3"
7718 [(set_attr "type" "idiv")
7719 (set_attr "mode" "<MODE>")])
7720
7721 (define_expand "udivmodqi4"
7722 [(parallel [(set (match_operand:QI 0 "register_operand")
7723 (udiv:QI
7724 (match_operand:QI 1 "register_operand")
7725 (match_operand:QI 2 "nonimmediate_operand")))
7726 (set (match_operand:QI 3 "register_operand")
7727 (umod:QI (match_dup 1) (match_dup 2)))
7728 (clobber (reg:CC FLAGS_REG))])]
7729 "TARGET_QIMODE_MATH"
7730 {
7731 rtx div, mod;
7732 rtx tmp0, tmp1;
7733
7734 tmp0 = gen_reg_rtx (HImode);
7735 tmp1 = gen_reg_rtx (HImode);
7736
7737 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
7738 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7739 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7740
7741 /* Extract remainder from AH. */
7742 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7743 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7744 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7745
7746 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7747 set_unique_reg_note (insn, REG_EQUAL, mod);
7748
7749 /* Extract quotient from AL. */
7750 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7751
7752 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7753 set_unique_reg_note (insn, REG_EQUAL, div);
7754
7755 DONE;
7756 })
7757
7758 (define_insn "udivmodhiqi3"
7759 [(set (match_operand:HI 0 "register_operand" "=a")
7760 (ior:HI
7761 (ashift:HI
7762 (zero_extend:HI
7763 (truncate:QI
7764 (mod:HI (match_operand:HI 1 "register_operand" "0")
7765 (zero_extend:HI
7766 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7767 (const_int 8))
7768 (zero_extend:HI
7769 (truncate:QI
7770 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7771 (clobber (reg:CC FLAGS_REG))]
7772 "TARGET_QIMODE_MATH"
7773 "div{b}\t%2"
7774 [(set_attr "type" "idiv")
7775 (set_attr "mode" "QI")])
7776
7777 ;; We cannot use div/idiv for double division, because it causes
7778 ;; "division by zero" on the overflow and that's not what we expect
7779 ;; from truncate. Because true (non truncating) double division is
7780 ;; never generated, we can't create this insn anyway.
7781 ;
7782 ;(define_insn ""
7783 ; [(set (match_operand:SI 0 "register_operand" "=a")
7784 ; (truncate:SI
7785 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7786 ; (zero_extend:DI
7787 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7788 ; (set (match_operand:SI 3 "register_operand" "=d")
7789 ; (truncate:SI
7790 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7791 ; (clobber (reg:CC FLAGS_REG))]
7792 ; ""
7793 ; "div{l}\t{%2, %0|%0, %2}"
7794 ; [(set_attr "type" "idiv")])
7795 \f
7796 ;;- Logical AND instructions
7797
7798 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7799 ;; Note that this excludes ah.
7800
7801 (define_expand "testsi_ccno_1"
7802 [(set (reg:CCNO FLAGS_REG)
7803 (compare:CCNO
7804 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7805 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7806 (const_int 0)))])
7807
7808 (define_expand "testqi_ccz_1"
7809 [(set (reg:CCZ FLAGS_REG)
7810 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7811 (match_operand:QI 1 "nonmemory_operand"))
7812 (const_int 0)))])
7813
7814 (define_expand "testdi_ccno_1"
7815 [(set (reg:CCNO FLAGS_REG)
7816 (compare:CCNO
7817 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7818 (match_operand:DI 1 "x86_64_szext_general_operand"))
7819 (const_int 0)))]
7820 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7821
7822 (define_insn "*testdi_1"
7823 [(set (reg FLAGS_REG)
7824 (compare
7825 (and:DI
7826 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7827 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7828 (const_int 0)))]
7829 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7830 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7831 "@
7832 test{l}\t{%k1, %k0|%k0, %k1}
7833 test{l}\t{%k1, %k0|%k0, %k1}
7834 test{q}\t{%1, %0|%0, %1}
7835 test{q}\t{%1, %0|%0, %1}
7836 test{q}\t{%1, %0|%0, %1}"
7837 [(set_attr "type" "test")
7838 (set_attr "modrm" "0,1,0,1,1")
7839 (set_attr "mode" "SI,SI,DI,DI,DI")])
7840
7841 (define_insn "*testqi_1_maybe_si"
7842 [(set (reg FLAGS_REG)
7843 (compare
7844 (and:QI
7845 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7846 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7847 (const_int 0)))]
7848 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7849 && ix86_match_ccmode (insn,
7850 CONST_INT_P (operands[1])
7851 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7852 {
7853 if (which_alternative == 3)
7854 {
7855 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7856 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7857 return "test{l}\t{%1, %k0|%k0, %1}";
7858 }
7859 return "test{b}\t{%1, %0|%0, %1}";
7860 }
7861 [(set_attr "type" "test")
7862 (set_attr "modrm" "0,1,1,1")
7863 (set_attr "mode" "QI,QI,QI,SI")
7864 (set_attr "pent_pair" "uv,np,uv,np")])
7865
7866 (define_insn "*test<mode>_1"
7867 [(set (reg FLAGS_REG)
7868 (compare
7869 (and:SWI124
7870 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7871 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7872 (const_int 0)))]
7873 "ix86_match_ccmode (insn, CCNOmode)
7874 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7875 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7876 [(set_attr "type" "test")
7877 (set_attr "modrm" "0,1,1")
7878 (set_attr "mode" "<MODE>")
7879 (set_attr "pent_pair" "uv,np,uv")])
7880
7881 (define_expand "testqi_ext_1_ccno"
7882 [(set (reg:CCNO FLAGS_REG)
7883 (compare:CCNO
7884 (and:QI
7885 (subreg:QI
7886 (zero_extract:SI (match_operand 0 "ext_register_operand")
7887 (const_int 8)
7888 (const_int 8)) 0)
7889 (match_operand 1 "const_int_operand"))
7890 (const_int 0)))])
7891
7892 (define_insn "*testqi_ext_1"
7893 [(set (reg FLAGS_REG)
7894 (compare
7895 (and:QI
7896 (subreg:QI
7897 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
7898 (const_int 8)
7899 (const_int 8)) 0)
7900 (match_operand:QI 1 "general_operand" "QnBc,m"))
7901 (const_int 0)))]
7902 "ix86_match_ccmode (insn, CCNOmode)"
7903 "test{b}\t{%1, %h0|%h0, %1}"
7904 [(set_attr "isa" "*,nox64")
7905 (set_attr "type" "test")
7906 (set_attr "mode" "QI")])
7907
7908 (define_insn "*testqi_ext_2"
7909 [(set (reg FLAGS_REG)
7910 (compare
7911 (and:QI
7912 (subreg:QI
7913 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
7914 (const_int 8)
7915 (const_int 8)) 0)
7916 (subreg:QI
7917 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
7918 (const_int 8)
7919 (const_int 8)) 0))
7920 (const_int 0)))]
7921 "ix86_match_ccmode (insn, CCNOmode)"
7922 "test{b}\t{%h1, %h0|%h0, %h1}"
7923 [(set_attr "type" "test")
7924 (set_attr "mode" "QI")])
7925
7926 ;; Combine likes to form bit extractions for some tests. Humor it.
7927 (define_insn_and_split "*testqi_ext_3"
7928 [(set (match_operand 0 "flags_reg_operand")
7929 (match_operator 1 "compare_operator"
7930 [(zero_extract:SWI248
7931 (match_operand 2 "nonimmediate_operand" "rm")
7932 (match_operand 3 "const_int_operand" "n")
7933 (match_operand 4 "const_int_operand" "n"))
7934 (const_int 0)]))]
7935 "ix86_match_ccmode (insn, CCNOmode)
7936 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
7937 || GET_MODE (operands[2]) == SImode
7938 || GET_MODE (operands[2]) == HImode
7939 || GET_MODE (operands[2]) == QImode)
7940 /* Ensure that resulting mask is zero or sign extended operand. */
7941 && INTVAL (operands[4]) >= 0
7942 && ((INTVAL (operands[3]) > 0
7943 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
7944 || (<MODE>mode == DImode
7945 && INTVAL (operands[3]) > 32
7946 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
7947 "#"
7948 "&& 1"
7949 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7950 {
7951 rtx val = operands[2];
7952 HOST_WIDE_INT len = INTVAL (operands[3]);
7953 HOST_WIDE_INT pos = INTVAL (operands[4]);
7954 machine_mode mode, submode;
7955
7956 mode = GET_MODE (val);
7957 if (MEM_P (val))
7958 {
7959 /* ??? Combine likes to put non-volatile mem extractions in QImode
7960 no matter the size of the test. So find a mode that works. */
7961 if (! MEM_VOLATILE_P (val))
7962 {
7963 mode = smallest_mode_for_size (pos + len, MODE_INT);
7964 val = adjust_address (val, mode, 0);
7965 }
7966 }
7967 else if (SUBREG_P (val)
7968 && (submode = GET_MODE (SUBREG_REG (val)),
7969 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7970 && pos + len <= GET_MODE_BITSIZE (submode)
7971 && GET_MODE_CLASS (submode) == MODE_INT)
7972 {
7973 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7974 mode = submode;
7975 val = SUBREG_REG (val);
7976 }
7977 else if (mode == HImode && pos + len <= 8)
7978 {
7979 /* Small HImode tests can be converted to QImode. */
7980 mode = QImode;
7981 val = gen_lowpart (QImode, val);
7982 }
7983
7984 wide_int mask
7985 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
7986
7987 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
7988 })
7989
7990 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7991 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7992 ;; this is relatively important trick.
7993 ;; Do the conversion only post-reload to avoid limiting of the register class
7994 ;; to QI regs.
7995 (define_split
7996 [(set (match_operand 0 "flags_reg_operand")
7997 (match_operator 1 "compare_operator"
7998 [(and (match_operand 2 "QIreg_operand")
7999 (match_operand 3 "const_int_operand"))
8000 (const_int 0)]))]
8001 "reload_completed
8002 && GET_MODE (operands[2]) != QImode
8003 && ((ix86_match_ccmode (insn, CCZmode)
8004 && !(INTVAL (operands[3]) & ~(255 << 8)))
8005 || (ix86_match_ccmode (insn, CCNOmode)
8006 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8007 [(set (match_dup 0)
8008 (match_op_dup 1
8009 [(and:QI
8010 (subreg:QI
8011 (zero_extract:SI (match_dup 2)
8012 (const_int 8)
8013 (const_int 8)) 0)
8014 (match_dup 3))
8015 (const_int 0)]))]
8016 {
8017 operands[2] = gen_lowpart (SImode, operands[2]);
8018 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8019 })
8020
8021 (define_split
8022 [(set (match_operand 0 "flags_reg_operand")
8023 (match_operator 1 "compare_operator"
8024 [(and (match_operand 2 "nonimmediate_operand")
8025 (match_operand 3 "const_int_operand"))
8026 (const_int 0)]))]
8027 "reload_completed
8028 && GET_MODE (operands[2]) != QImode
8029 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8030 && ((ix86_match_ccmode (insn, CCZmode)
8031 && !(INTVAL (operands[3]) & ~255))
8032 || (ix86_match_ccmode (insn, CCNOmode)
8033 && !(INTVAL (operands[3]) & ~127)))"
8034 [(set (match_dup 0)
8035 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8036 (const_int 0)]))]
8037 {
8038 operands[2] = gen_lowpart (QImode, operands[2]);
8039 operands[3] = gen_lowpart (QImode, operands[3]);
8040 })
8041
8042 ;; %%% This used to optimize known byte-wide and operations to memory,
8043 ;; and sometimes to QImode registers. If this is considered useful,
8044 ;; it should be done with splitters.
8045
8046 (define_expand "and<mode>3"
8047 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8048 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8049 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8050 ""
8051 {
8052 machine_mode mode = <MODE>mode;
8053 rtx (*insn) (rtx, rtx);
8054
8055 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8056 {
8057 HOST_WIDE_INT ival = INTVAL (operands[2]);
8058
8059 if (ival == (HOST_WIDE_INT) 0xffffffff)
8060 mode = SImode;
8061 else if (ival == 0xffff)
8062 mode = HImode;
8063 else if (ival == 0xff)
8064 mode = QImode;
8065 }
8066
8067 if (mode == <MODE>mode)
8068 {
8069 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8070 DONE;
8071 }
8072
8073 if (<MODE>mode == DImode)
8074 insn = (mode == SImode)
8075 ? gen_zero_extendsidi2
8076 : (mode == HImode)
8077 ? gen_zero_extendhidi2
8078 : gen_zero_extendqidi2;
8079 else if (<MODE>mode == SImode)
8080 insn = (mode == HImode)
8081 ? gen_zero_extendhisi2
8082 : gen_zero_extendqisi2;
8083 else if (<MODE>mode == HImode)
8084 insn = gen_zero_extendqihi2;
8085 else
8086 gcc_unreachable ();
8087
8088 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8089 DONE;
8090 })
8091
8092 (define_insn_and_split "*anddi3_doubleword"
8093 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8094 (and:DI
8095 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8096 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8097 (clobber (reg:CC FLAGS_REG))]
8098 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8099 && ix86_binary_operator_ok (AND, DImode, operands)"
8100 "#"
8101 "&& reload_completed"
8102 [(const_int 0)]
8103 {
8104 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8105 if (operands[2] == const0_rtx)
8106 {
8107 operands[1] = const0_rtx;
8108 ix86_expand_move (SImode, &operands[0]);
8109 }
8110 else if (operands[2] != constm1_rtx)
8111 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8112 else if (operands[5] == constm1_rtx)
8113 emit_note (NOTE_INSN_DELETED);
8114 if (operands[5] == const0_rtx)
8115 {
8116 operands[4] = const0_rtx;
8117 ix86_expand_move (SImode, &operands[3]);
8118 }
8119 else if (operands[5] != constm1_rtx)
8120 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8121 DONE;
8122 })
8123
8124 (define_insn "*anddi_1"
8125 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8126 (and:DI
8127 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8128 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8129 (clobber (reg:CC FLAGS_REG))]
8130 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8131 "@
8132 and{l}\t{%k2, %k0|%k0, %k2}
8133 and{q}\t{%2, %0|%0, %2}
8134 and{q}\t{%2, %0|%0, %2}
8135 #"
8136 [(set_attr "type" "alu,alu,alu,imovx")
8137 (set_attr "length_immediate" "*,*,*,0")
8138 (set (attr "prefix_rex")
8139 (if_then_else
8140 (and (eq_attr "type" "imovx")
8141 (and (match_test "INTVAL (operands[2]) == 0xff")
8142 (match_operand 1 "ext_QIreg_operand")))
8143 (const_string "1")
8144 (const_string "*")))
8145 (set_attr "mode" "SI,DI,DI,SI")])
8146
8147 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8148 (define_split
8149 [(set (match_operand:DI 0 "register_operand")
8150 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8151 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8152 (clobber (reg:CC FLAGS_REG))]
8153 "TARGET_64BIT"
8154 [(parallel [(set (match_dup 0)
8155 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8156 (clobber (reg:CC FLAGS_REG))])]
8157 "operands[2] = gen_lowpart (SImode, operands[2]);")
8158
8159 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8160 (define_insn "*andsi_1_zext"
8161 [(set (match_operand:DI 0 "register_operand" "=r")
8162 (zero_extend:DI
8163 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8164 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8165 (clobber (reg:CC FLAGS_REG))]
8166 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8167 "and{l}\t{%2, %k0|%k0, %2}"
8168 [(set_attr "type" "alu")
8169 (set_attr "mode" "SI")])
8170
8171 (define_insn "*and<mode>_1"
8172 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8173 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8174 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8177 "@
8178 and{<imodesuffix>}\t{%2, %0|%0, %2}
8179 and{<imodesuffix>}\t{%2, %0|%0, %2}
8180 #"
8181 [(set_attr "type" "alu,alu,imovx")
8182 (set_attr "length_immediate" "*,*,0")
8183 (set (attr "prefix_rex")
8184 (if_then_else
8185 (and (eq_attr "type" "imovx")
8186 (and (match_test "INTVAL (operands[2]) == 0xff")
8187 (match_operand 1 "ext_QIreg_operand")))
8188 (const_string "1")
8189 (const_string "*")))
8190 (set_attr "mode" "<MODE>,<MODE>,SI")])
8191
8192 (define_insn "*andqi_1"
8193 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8194 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8195 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8196 (clobber (reg:CC FLAGS_REG))]
8197 "ix86_binary_operator_ok (AND, QImode, operands)"
8198 "@
8199 and{b}\t{%2, %0|%0, %2}
8200 and{b}\t{%2, %0|%0, %2}
8201 and{l}\t{%k2, %k0|%k0, %k2}"
8202 [(set_attr "type" "alu")
8203 (set_attr "mode" "QI,QI,SI")
8204 ;; Potential partial reg stall on alternative 2.
8205 (set (attr "preferred_for_speed")
8206 (cond [(eq_attr "alternative" "2")
8207 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8208 (symbol_ref "true")))])
8209
8210 (define_insn "*andqi_1_slp"
8211 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8212 (and:QI (match_dup 0)
8213 (match_operand:QI 1 "general_operand" "qn,qmn")))
8214 (clobber (reg:CC FLAGS_REG))]
8215 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8216 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8217 "and{b}\t{%1, %0|%0, %1}"
8218 [(set_attr "type" "alu1")
8219 (set_attr "mode" "QI")])
8220
8221 (define_split
8222 [(set (match_operand:SWI248 0 "register_operand")
8223 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8224 (match_operand:SWI248 2 "const_int_operand")))
8225 (clobber (reg:CC FLAGS_REG))]
8226 "reload_completed
8227 && (!REG_P (operands[1])
8228 || REGNO (operands[0]) != REGNO (operands[1]))"
8229 [(const_int 0)]
8230 {
8231 HOST_WIDE_INT ival = INTVAL (operands[2]);
8232 machine_mode mode;
8233 rtx (*insn) (rtx, rtx);
8234
8235 if (ival == (HOST_WIDE_INT) 0xffffffff)
8236 mode = SImode;
8237 else if (ival == 0xffff)
8238 mode = HImode;
8239 else
8240 {
8241 gcc_assert (ival == 0xff);
8242 mode = QImode;
8243 }
8244
8245 if (<MODE>mode == DImode)
8246 insn = (mode == SImode)
8247 ? gen_zero_extendsidi2
8248 : (mode == HImode)
8249 ? gen_zero_extendhidi2
8250 : gen_zero_extendqidi2;
8251 else
8252 {
8253 if (<MODE>mode != SImode)
8254 /* Zero extend to SImode to avoid partial register stalls. */
8255 operands[0] = gen_lowpart (SImode, operands[0]);
8256
8257 insn = (mode == HImode)
8258 ? gen_zero_extendhisi2
8259 : gen_zero_extendqisi2;
8260 }
8261 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8262 DONE;
8263 })
8264
8265 (define_split
8266 [(set (match_operand:SWI48 0 "register_operand")
8267 (and:SWI48 (match_dup 0)
8268 (const_int -65536)))
8269 (clobber (reg:CC FLAGS_REG))]
8270 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8271 || optimize_function_for_size_p (cfun)"
8272 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8273 "operands[1] = gen_lowpart (HImode, operands[0]);")
8274
8275 (define_split
8276 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8277 (and:SWI248 (match_dup 0)
8278 (const_int -256)))
8279 (clobber (reg:CC FLAGS_REG))]
8280 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8281 && reload_completed"
8282 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8283 "operands[1] = gen_lowpart (QImode, operands[0]);")
8284
8285 (define_split
8286 [(set (match_operand:SWI248 0 "QIreg_operand")
8287 (and:SWI248 (match_dup 0)
8288 (const_int -65281)))
8289 (clobber (reg:CC FLAGS_REG))]
8290 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8291 && reload_completed"
8292 [(parallel
8293 [(set (zero_extract:SI (match_dup 0)
8294 (const_int 8)
8295 (const_int 8))
8296 (subreg:SI
8297 (xor:QI
8298 (subreg:QI
8299 (zero_extract:SI (match_dup 0)
8300 (const_int 8)
8301 (const_int 8)) 0)
8302 (subreg:QI
8303 (zero_extract:SI (match_dup 0)
8304 (const_int 8)
8305 (const_int 8)) 0)) 0))
8306 (clobber (reg:CC FLAGS_REG))])]
8307 "operands[0] = gen_lowpart (SImode, operands[0]);")
8308
8309 (define_insn "*anddi_2"
8310 [(set (reg FLAGS_REG)
8311 (compare
8312 (and:DI
8313 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8314 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8315 (const_int 0)))
8316 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8317 (and:DI (match_dup 1) (match_dup 2)))]
8318 "TARGET_64BIT
8319 && ix86_match_ccmode
8320 (insn,
8321 /* If we are going to emit andl instead of andq, and the operands[2]
8322 constant might have the SImode sign bit set, make sure the sign
8323 flag isn't tested, because the instruction will set the sign flag
8324 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8325 conservatively assume it might have bit 31 set. */
8326 (satisfies_constraint_Z (operands[2])
8327 && (!CONST_INT_P (operands[2])
8328 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8329 ? CCZmode : CCNOmode)
8330 && ix86_binary_operator_ok (AND, DImode, operands)"
8331 "@
8332 and{l}\t{%k2, %k0|%k0, %k2}
8333 and{q}\t{%2, %0|%0, %2}
8334 and{q}\t{%2, %0|%0, %2}"
8335 [(set_attr "type" "alu")
8336 (set_attr "mode" "SI,DI,DI")])
8337
8338 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8339 (define_insn "*andsi_2_zext"
8340 [(set (reg FLAGS_REG)
8341 (compare (and:SI
8342 (match_operand:SI 1 "nonimmediate_operand" "%0")
8343 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8344 (const_int 0)))
8345 (set (match_operand:DI 0 "register_operand" "=r")
8346 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8347 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8348 && ix86_binary_operator_ok (AND, SImode, operands)"
8349 "and{l}\t{%2, %k0|%k0, %2}"
8350 [(set_attr "type" "alu")
8351 (set_attr "mode" "SI")])
8352
8353 (define_insn "*andqi_2_maybe_si"
8354 [(set (reg FLAGS_REG)
8355 (compare (and:QI
8356 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8357 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8358 (const_int 0)))
8359 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8360 (and:QI (match_dup 1) (match_dup 2)))]
8361 "ix86_binary_operator_ok (AND, QImode, operands)
8362 && ix86_match_ccmode (insn,
8363 CONST_INT_P (operands[2])
8364 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8365 {
8366 if (which_alternative == 2)
8367 {
8368 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8369 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8370 return "and{l}\t{%2, %k0|%k0, %2}";
8371 }
8372 return "and{b}\t{%2, %0|%0, %2}";
8373 }
8374 [(set_attr "type" "alu")
8375 (set_attr "mode" "QI,QI,SI")])
8376
8377 (define_insn "*and<mode>_2"
8378 [(set (reg FLAGS_REG)
8379 (compare (and:SWI124
8380 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8381 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8382 (const_int 0)))
8383 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8384 (and:SWI124 (match_dup 1) (match_dup 2)))]
8385 "ix86_match_ccmode (insn, CCNOmode)
8386 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8387 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8388 [(set_attr "type" "alu")
8389 (set_attr "mode" "<MODE>")])
8390
8391 (define_insn "*andqi_2_slp"
8392 [(set (reg FLAGS_REG)
8393 (compare (and:QI
8394 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8395 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8396 (const_int 0)))
8397 (set (strict_low_part (match_dup 0))
8398 (and:QI (match_dup 0) (match_dup 1)))]
8399 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8400 && ix86_match_ccmode (insn, CCNOmode)
8401 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8402 "and{b}\t{%1, %0|%0, %1}"
8403 [(set_attr "type" "alu1")
8404 (set_attr "mode" "QI")])
8405
8406 (define_insn "andqi_ext_1"
8407 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8408 (const_int 8)
8409 (const_int 8))
8410 (subreg:SI
8411 (and:QI
8412 (subreg:QI
8413 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8414 (const_int 8)
8415 (const_int 8)) 0)
8416 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8417 (clobber (reg:CC FLAGS_REG))]
8418 ""
8419 "and{b}\t{%2, %h0|%h0, %2}"
8420 [(set_attr "isa" "*,nox64")
8421 (set_attr "type" "alu")
8422 (set_attr "mode" "QI")])
8423
8424 ;; Generated by peephole translating test to and. This shows up
8425 ;; often in fp comparisons.
8426 (define_insn "*andqi_ext_1_cc"
8427 [(set (reg FLAGS_REG)
8428 (compare
8429 (and:QI
8430 (subreg:QI
8431 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8432 (const_int 8)
8433 (const_int 8)) 0)
8434 (match_operand:QI 2 "general_operand" "QnBc,m"))
8435 (const_int 0)))
8436 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8437 (const_int 8)
8438 (const_int 8))
8439 (subreg:SI
8440 (and:QI
8441 (subreg:QI
8442 (zero_extract:SI (match_dup 1)
8443 (const_int 8)
8444 (const_int 8)) 0)
8445 (match_dup 2)) 0))]
8446 "ix86_match_ccmode (insn, CCNOmode)"
8447 "and{b}\t{%2, %h0|%h0, %2}"
8448 [(set_attr "isa" "*,nox64")
8449 (set_attr "type" "alu")
8450 (set_attr "mode" "QI")])
8451
8452 (define_insn "*andqi_ext_2"
8453 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8454 (const_int 8)
8455 (const_int 8))
8456 (subreg:SI
8457 (and:QI
8458 (subreg:QI
8459 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
8460 (const_int 8)
8461 (const_int 8)) 0)
8462 (subreg:QI
8463 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8464 (const_int 8)
8465 (const_int 8)) 0)) 0))
8466 (clobber (reg:CC FLAGS_REG))]
8467 ""
8468 "and{b}\t{%h2, %h0|%h0, %h2}"
8469 [(set_attr "type" "alu")
8470 (set_attr "mode" "QI")])
8471
8472 ;; Convert wide AND instructions with immediate operand to shorter QImode
8473 ;; equivalents when possible.
8474 ;; Don't do the splitting with memory operands, since it introduces risk
8475 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8476 ;; for size, but that can (should?) be handled by generic code instead.
8477 (define_split
8478 [(set (match_operand:SWI248 0 "QIreg_operand")
8479 (and:SWI248 (match_operand:SWI248 1 "register_operand")
8480 (match_operand:SWI248 2 "const_int_operand")))
8481 (clobber (reg:CC FLAGS_REG))]
8482 "reload_completed
8483 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8484 && !(~INTVAL (operands[2]) & ~(255 << 8))"
8485 [(parallel
8486 [(set (zero_extract:SI (match_dup 0)
8487 (const_int 8)
8488 (const_int 8))
8489 (subreg:SI
8490 (and:QI
8491 (subreg:QI
8492 (zero_extract:SI (match_dup 1)
8493 (const_int 8)
8494 (const_int 8)) 0)
8495 (match_dup 2)) 0))
8496 (clobber (reg:CC FLAGS_REG))])]
8497 {
8498 operands[0] = gen_lowpart (SImode, operands[0]);
8499 operands[1] = gen_lowpart (SImode, operands[1]);
8500 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
8501 })
8502
8503 ;; Since AND can be encoded with sign extended immediate, this is only
8504 ;; profitable when 7th bit is not set.
8505 (define_split
8506 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8507 (and:SWI248 (match_operand:SWI248 1 "general_operand")
8508 (match_operand:SWI248 2 "const_int_operand")))
8509 (clobber (reg:CC FLAGS_REG))]
8510 "reload_completed
8511 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8512 && !(~INTVAL (operands[2]) & ~255)
8513 && !(INTVAL (operands[2]) & 128)"
8514 [(parallel [(set (strict_low_part (match_dup 0))
8515 (and:QI (match_dup 1)
8516 (match_dup 2)))
8517 (clobber (reg:CC FLAGS_REG))])]
8518 {
8519 operands[0] = gen_lowpart (QImode, operands[0]);
8520 operands[1] = gen_lowpart (QImode, operands[1]);
8521 operands[2] = gen_lowpart (QImode, operands[2]);
8522 })
8523
8524 (define_insn "*andndi3_doubleword"
8525 [(set (match_operand:DI 0 "register_operand" "=r,&r")
8526 (and:DI
8527 (not:DI (match_operand:DI 1 "register_operand" "r,0"))
8528 (match_operand:DI 2 "nonimmediate_operand" "rm,rm")))
8529 (clobber (reg:CC FLAGS_REG))]
8530 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
8531 "#"
8532 [(set_attr "isa" "bmi,*")])
8533
8534 (define_split
8535 [(set (match_operand:DI 0 "register_operand")
8536 (and:DI
8537 (not:DI (match_operand:DI 1 "register_operand"))
8538 (match_operand:DI 2 "nonimmediate_operand")))
8539 (clobber (reg:CC FLAGS_REG))]
8540 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
8541 && reload_completed"
8542 [(parallel [(set (match_dup 0)
8543 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8544 (clobber (reg:CC FLAGS_REG))])
8545 (parallel [(set (match_dup 3)
8546 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8547 (clobber (reg:CC FLAGS_REG))])]
8548 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8549
8550 (define_split
8551 [(set (match_operand:DI 0 "register_operand")
8552 (and:DI
8553 (not:DI (match_dup 0))
8554 (match_operand:DI 1 "nonimmediate_operand")))
8555 (clobber (reg:CC FLAGS_REG))]
8556 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
8557 && reload_completed"
8558 [(set (match_dup 0) (not:SI (match_dup 0)))
8559 (parallel [(set (match_dup 0)
8560 (and:SI (match_dup 0) (match_dup 1)))
8561 (clobber (reg:CC FLAGS_REG))])
8562 (set (match_dup 2) (not:SI (match_dup 2)))
8563 (parallel [(set (match_dup 2)
8564 (and:SI (match_dup 2) (match_dup 3)))
8565 (clobber (reg:CC FLAGS_REG))])]
8566 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
8567
8568 (define_insn "*andn<mode>_1"
8569 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
8570 (and:SWI48
8571 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8572 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
8573 (clobber (reg:CC FLAGS_REG))]
8574 "TARGET_BMI"
8575 "andn\t{%2, %1, %0|%0, %1, %2}"
8576 [(set_attr "type" "bitmanip")
8577 (set_attr "btver2_decode" "direct, double")
8578 (set_attr "mode" "<MODE>")])
8579
8580 (define_insn "*andn<mode>_1"
8581 [(set (match_operand:SWI12 0 "register_operand" "=r")
8582 (and:SWI12
8583 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
8584 (match_operand:SWI12 2 "register_operand" "r")))
8585 (clobber (reg:CC FLAGS_REG))]
8586 "TARGET_BMI"
8587 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
8588 [(set_attr "type" "bitmanip")
8589 (set_attr "btver2_decode" "direct")
8590 (set_attr "mode" "SI")])
8591
8592 (define_insn "*andn_<mode>_ccno"
8593 [(set (reg FLAGS_REG)
8594 (compare
8595 (and:SWI48
8596 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8597 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
8598 (const_int 0)))
8599 (clobber (match_scratch:SWI48 0 "=r,r"))]
8600 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
8601 "andn\t{%2, %1, %0|%0, %1, %2}"
8602 [(set_attr "type" "bitmanip")
8603 (set_attr "btver2_decode" "direct, double")
8604 (set_attr "mode" "<MODE>")])
8605 \f
8606 ;; Logical inclusive and exclusive OR instructions
8607
8608 ;; %%% This used to optimize known byte-wide and operations to memory.
8609 ;; If this is considered useful, it should be done with splitters.
8610
8611 (define_expand "<code><mode>3"
8612 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8613 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8614 (match_operand:SWIM1248x 2 "<general_operand>")))]
8615 ""
8616 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8617
8618 (define_insn_and_split "*<code>di3_doubleword"
8619 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8620 (any_or:DI
8621 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8622 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8623 (clobber (reg:CC FLAGS_REG))]
8624 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8625 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
8626 "#"
8627 "&& reload_completed"
8628 [(const_int 0)]
8629 {
8630 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8631 if (operands[2] == constm1_rtx)
8632 {
8633 if (<CODE> == IOR)
8634 {
8635 operands[1] = constm1_rtx;
8636 ix86_expand_move (SImode, &operands[0]);
8637 }
8638 else
8639 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
8640 }
8641 else if (operands[2] != const0_rtx)
8642 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
8643 else if (operands[5] == const0_rtx)
8644 emit_note (NOTE_INSN_DELETED);
8645 if (operands[5] == constm1_rtx)
8646 {
8647 if (<CODE> == IOR)
8648 {
8649 operands[4] = constm1_rtx;
8650 ix86_expand_move (SImode, &operands[3]);
8651 }
8652 else
8653 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
8654 }
8655 else if (operands[5] != const0_rtx)
8656 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
8657 DONE;
8658 })
8659
8660 (define_insn "*<code><mode>_1"
8661 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8662 (any_or:SWI248
8663 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8664 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8665 (clobber (reg:CC FLAGS_REG))]
8666 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8667 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8668 [(set_attr "type" "alu")
8669 (set_attr "mode" "<MODE>")])
8670
8671 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8672 (define_insn "*<code>si_1_zext"
8673 [(set (match_operand:DI 0 "register_operand" "=r")
8674 (zero_extend:DI
8675 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8676 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8677 (clobber (reg:CC FLAGS_REG))]
8678 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8679 "<logic>{l}\t{%2, %k0|%k0, %2}"
8680 [(set_attr "type" "alu")
8681 (set_attr "mode" "SI")])
8682
8683 (define_insn "*<code>si_1_zext_imm"
8684 [(set (match_operand:DI 0 "register_operand" "=r")
8685 (any_or:DI
8686 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8687 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8688 (clobber (reg:CC FLAGS_REG))]
8689 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8690 "<logic>{l}\t{%2, %k0|%k0, %2}"
8691 [(set_attr "type" "alu")
8692 (set_attr "mode" "SI")])
8693
8694 (define_insn "*<code>qi_1"
8695 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8696 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8697 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8698 (clobber (reg:CC FLAGS_REG))]
8699 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8700 "@
8701 <logic>{b}\t{%2, %0|%0, %2}
8702 <logic>{b}\t{%2, %0|%0, %2}
8703 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8704 [(set_attr "type" "alu")
8705 (set_attr "mode" "QI,QI,SI")
8706 ;; Potential partial reg stall on alternative 2.
8707 (set (attr "preferred_for_speed")
8708 (cond [(eq_attr "alternative" "2")
8709 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8710 (symbol_ref "true")))])
8711
8712 (define_insn "*<code>qi_1_slp"
8713 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8714 (any_or:QI (match_dup 0)
8715 (match_operand:QI 1 "general_operand" "qmn,qn")))
8716 (clobber (reg:CC FLAGS_REG))]
8717 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8718 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8719 "<logic>{b}\t{%1, %0|%0, %1}"
8720 [(set_attr "type" "alu1")
8721 (set_attr "mode" "QI")])
8722
8723 (define_insn "*<code><mode>_2"
8724 [(set (reg FLAGS_REG)
8725 (compare (any_or:SWI
8726 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8727 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8728 (const_int 0)))
8729 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8730 (any_or:SWI (match_dup 1) (match_dup 2)))]
8731 "ix86_match_ccmode (insn, CCNOmode)
8732 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8733 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8734 [(set_attr "type" "alu")
8735 (set_attr "mode" "<MODE>")])
8736
8737 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8738 ;; ??? Special case for immediate operand is missing - it is tricky.
8739 (define_insn "*<code>si_2_zext"
8740 [(set (reg FLAGS_REG)
8741 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8742 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8743 (const_int 0)))
8744 (set (match_operand:DI 0 "register_operand" "=r")
8745 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8746 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8747 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8748 "<logic>{l}\t{%2, %k0|%k0, %2}"
8749 [(set_attr "type" "alu")
8750 (set_attr "mode" "SI")])
8751
8752 (define_insn "*<code>si_2_zext_imm"
8753 [(set (reg FLAGS_REG)
8754 (compare (any_or:SI
8755 (match_operand:SI 1 "nonimmediate_operand" "%0")
8756 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8757 (const_int 0)))
8758 (set (match_operand:DI 0 "register_operand" "=r")
8759 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8760 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8761 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8762 "<logic>{l}\t{%2, %k0|%k0, %2}"
8763 [(set_attr "type" "alu")
8764 (set_attr "mode" "SI")])
8765
8766 (define_insn "*<code>qi_2_slp"
8767 [(set (reg FLAGS_REG)
8768 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8769 (match_operand:QI 1 "general_operand" "qmn,qn"))
8770 (const_int 0)))
8771 (set (strict_low_part (match_dup 0))
8772 (any_or:QI (match_dup 0) (match_dup 1)))]
8773 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8774 && ix86_match_ccmode (insn, CCNOmode)
8775 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8776 "<logic>{b}\t{%1, %0|%0, %1}"
8777 [(set_attr "type" "alu1")
8778 (set_attr "mode" "QI")])
8779
8780 (define_insn "*<code><mode>_3"
8781 [(set (reg FLAGS_REG)
8782 (compare (any_or:SWI
8783 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8784 (match_operand:SWI 2 "<general_operand>" "<g>"))
8785 (const_int 0)))
8786 (clobber (match_scratch:SWI 0 "=<r>"))]
8787 "ix86_match_ccmode (insn, CCNOmode)
8788 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8789 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8790 [(set_attr "type" "alu")
8791 (set_attr "mode" "<MODE>")])
8792
8793 (define_insn "*<code>qi_ext_1"
8794 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8795 (const_int 8)
8796 (const_int 8))
8797 (subreg:SI
8798 (any_or:QI
8799 (subreg:QI
8800 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8801 (const_int 8)
8802 (const_int 8)) 0)
8803 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8804 (clobber (reg:CC FLAGS_REG))]
8805 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8806 "<logic>{b}\t{%2, %h0|%h0, %2}"
8807 [(set_attr "isa" "*,nox64")
8808 (set_attr "type" "alu")
8809 (set_attr "mode" "QI")])
8810
8811 (define_insn "*<code>qi_ext_2"
8812 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8813 (const_int 8)
8814 (const_int 8))
8815 (subreg:SI
8816 (any_or:QI
8817 (subreg:QI
8818 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
8819 (const_int 8)
8820 (const_int 8)) 0)
8821 (subreg:QI
8822 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8823 (const_int 8)
8824 (const_int 8)) 0)) 0))
8825 (clobber (reg:CC FLAGS_REG))]
8826 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8827 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8828 [(set_attr "type" "alu")
8829 (set_attr "mode" "QI")])
8830
8831 ;; Convert wide OR instructions with immediate operand to shorter QImode
8832 ;; equivalents when possible.
8833 ;; Don't do the splitting with memory operands, since it introduces risk
8834 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8835 ;; for size, but that can (should?) be handled by generic code instead.
8836 (define_split
8837 [(set (match_operand:SWI248 0 "QIreg_operand")
8838 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
8839 (match_operand:SWI248 2 "const_int_operand")))
8840 (clobber (reg:CC FLAGS_REG))]
8841 "reload_completed
8842 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8843 && !(INTVAL (operands[2]) & ~(255 << 8))"
8844 [(parallel
8845 [(set (zero_extract:SI (match_dup 0)
8846 (const_int 8)
8847 (const_int 8))
8848 (subreg:SI
8849 (any_or:QI
8850 (subreg:QI
8851 (zero_extract:SI (match_dup 1)
8852 (const_int 8)
8853 (const_int 8)) 0)
8854 (match_dup 2)) 0))
8855 (clobber (reg:CC FLAGS_REG))])]
8856 {
8857 operands[0] = gen_lowpart (SImode, operands[0]);
8858 operands[1] = gen_lowpart (SImode, operands[1]);
8859 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
8860 })
8861
8862 ;; Since OR can be encoded with sign extended immediate, this is only
8863 ;; profitable when 7th bit is set.
8864 (define_split
8865 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8866 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
8867 (match_operand:SWI248 2 "const_int_operand")))
8868 (clobber (reg:CC FLAGS_REG))]
8869 "reload_completed
8870 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8871 && !(INTVAL (operands[2]) & ~255)
8872 && (INTVAL (operands[2]) & 128)"
8873 [(parallel [(set (strict_low_part (match_dup 0))
8874 (any_or:QI (match_dup 1)
8875 (match_dup 2)))
8876 (clobber (reg:CC FLAGS_REG))])]
8877 {
8878 operands[0] = gen_lowpart (QImode, operands[0]);
8879 operands[1] = gen_lowpart (QImode, operands[1]);
8880 operands[2] = gen_lowpart (QImode, operands[2]);
8881 })
8882
8883 (define_expand "xorqi_ext_1_cc"
8884 [(parallel [
8885 (set (reg:CCNO FLAGS_REG)
8886 (compare:CCNO
8887 (xor:QI
8888 (subreg:QI
8889 (zero_extract:SI (match_operand 1 "ext_register_operand")
8890 (const_int 8)
8891 (const_int 8)) 0)
8892 (match_operand 2 "const_int_operand"))
8893 (const_int 0)))
8894 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8895 (const_int 8)
8896 (const_int 8))
8897 (subreg:SI
8898 (xor:QI
8899 (subreg:QI
8900 (zero_extract:SI (match_dup 1)
8901 (const_int 8)
8902 (const_int 8)) 0)
8903 (match_dup 2)) 0))])])
8904
8905 (define_insn "*xorqi_ext_1_cc"
8906 [(set (reg FLAGS_REG)
8907 (compare
8908 (xor:QI
8909 (subreg:QI
8910 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8911 (const_int 8)
8912 (const_int 8)) 0)
8913 (match_operand:QI 2 "general_operand" "QnBc,m"))
8914 (const_int 0)))
8915 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8916 (const_int 8)
8917 (const_int 8))
8918 (subreg:SI
8919 (xor:QI
8920 (subreg:QI
8921 (zero_extract:SI (match_dup 1)
8922 (const_int 8)
8923 (const_int 8)) 0)
8924 (match_dup 2)) 0))]
8925 "ix86_match_ccmode (insn, CCNOmode)"
8926 "xor{b}\t{%2, %h0|%h0, %2}"
8927 [(set_attr "isa" "*,nox64")
8928 (set_attr "type" "alu")
8929 (set_attr "mode" "QI")])
8930 \f
8931 ;; Negation instructions
8932
8933 (define_expand "neg<mode>2"
8934 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8935 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8936 ""
8937 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8938
8939 (define_insn_and_split "*neg<dwi>2_doubleword"
8940 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8941 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8942 (clobber (reg:CC FLAGS_REG))]
8943 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8944 "#"
8945 "reload_completed"
8946 [(parallel
8947 [(set (reg:CCZ FLAGS_REG)
8948 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8949 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8950 (parallel
8951 [(set (match_dup 2)
8952 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8953 (match_dup 3))
8954 (const_int 0)))
8955 (clobber (reg:CC FLAGS_REG))])
8956 (parallel
8957 [(set (match_dup 2)
8958 (neg:DWIH (match_dup 2)))
8959 (clobber (reg:CC FLAGS_REG))])]
8960 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8961
8962 (define_insn "*neg<mode>2_1"
8963 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8964 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8965 (clobber (reg:CC FLAGS_REG))]
8966 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8967 "neg{<imodesuffix>}\t%0"
8968 [(set_attr "type" "negnot")
8969 (set_attr "mode" "<MODE>")])
8970
8971 ;; Combine is quite creative about this pattern.
8972 (define_insn "*negsi2_1_zext"
8973 [(set (match_operand:DI 0 "register_operand" "=r")
8974 (lshiftrt:DI
8975 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8976 (const_int 32)))
8977 (const_int 32)))
8978 (clobber (reg:CC FLAGS_REG))]
8979 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8980 "neg{l}\t%k0"
8981 [(set_attr "type" "negnot")
8982 (set_attr "mode" "SI")])
8983
8984 ;; The problem with neg is that it does not perform (compare x 0),
8985 ;; it really performs (compare 0 x), which leaves us with the zero
8986 ;; flag being the only useful item.
8987
8988 (define_insn "*neg<mode>2_cmpz"
8989 [(set (reg:CCZ FLAGS_REG)
8990 (compare:CCZ
8991 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8992 (const_int 0)))
8993 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8994 (neg:SWI (match_dup 1)))]
8995 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8996 "neg{<imodesuffix>}\t%0"
8997 [(set_attr "type" "negnot")
8998 (set_attr "mode" "<MODE>")])
8999
9000 (define_insn "*negsi2_cmpz_zext"
9001 [(set (reg:CCZ FLAGS_REG)
9002 (compare:CCZ
9003 (lshiftrt:DI
9004 (neg:DI (ashift:DI
9005 (match_operand:DI 1 "register_operand" "0")
9006 (const_int 32)))
9007 (const_int 32))
9008 (const_int 0)))
9009 (set (match_operand:DI 0 "register_operand" "=r")
9010 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9011 (const_int 32)))
9012 (const_int 32)))]
9013 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9014 "neg{l}\t%k0"
9015 [(set_attr "type" "negnot")
9016 (set_attr "mode" "SI")])
9017
9018 ;; Negate with jump on overflow.
9019 (define_expand "negv<mode>3"
9020 [(parallel [(set (reg:CCO FLAGS_REG)
9021 (ne:CCO (match_operand:SWI 1 "register_operand")
9022 (match_dup 3)))
9023 (set (match_operand:SWI 0 "register_operand")
9024 (neg:SWI (match_dup 1)))])
9025 (set (pc) (if_then_else
9026 (eq (reg:CCO FLAGS_REG) (const_int 0))
9027 (label_ref (match_operand 2))
9028 (pc)))]
9029 ""
9030 {
9031 operands[3]
9032 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9033 <MODE>mode);
9034 })
9035
9036 (define_insn "*negv<mode>3"
9037 [(set (reg:CCO FLAGS_REG)
9038 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9039 (match_operand:SWI 2 "const_int_operand")))
9040 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9041 (neg:SWI (match_dup 1)))]
9042 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9043 && mode_signbit_p (<MODE>mode, operands[2])"
9044 "neg{<imodesuffix>}\t%0"
9045 [(set_attr "type" "negnot")
9046 (set_attr "mode" "<MODE>")])
9047
9048 ;; Changing of sign for FP values is doable using integer unit too.
9049
9050 (define_expand "<code><mode>2"
9051 [(set (match_operand:X87MODEF 0 "register_operand")
9052 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9053 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9054 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9055
9056 (define_insn "*absneg<mode>2"
9057 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9058 (match_operator:MODEF 3 "absneg_operator"
9059 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9060 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9061 (clobber (reg:CC FLAGS_REG))]
9062 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9063 "#"
9064 [(set (attr "enabled")
9065 (if_then_else
9066 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9067 (if_then_else
9068 (eq_attr "alternative" "2")
9069 (symbol_ref "TARGET_MIX_SSE_I387")
9070 (symbol_ref "true"))
9071 (if_then_else
9072 (eq_attr "alternative" "2,3")
9073 (symbol_ref "true")
9074 (symbol_ref "false"))))])
9075
9076 (define_insn "*absnegxf2_i387"
9077 [(set (match_operand:XF 0 "register_operand" "=f,!r")
9078 (match_operator:XF 3 "absneg_operator"
9079 [(match_operand:XF 1 "register_operand" "0,0")]))
9080 (use (match_operand 2))
9081 (clobber (reg:CC FLAGS_REG))]
9082 "TARGET_80387"
9083 "#")
9084
9085 (define_expand "<code>tf2"
9086 [(set (match_operand:TF 0 "register_operand")
9087 (absneg:TF (match_operand:TF 1 "register_operand")))]
9088 "TARGET_SSE"
9089 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9090
9091 (define_insn "*absnegtf2_sse"
9092 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9093 (match_operator:TF 3 "absneg_operator"
9094 [(match_operand:TF 1 "register_operand" "0,Yv")]))
9095 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9096 (clobber (reg:CC FLAGS_REG))]
9097 "TARGET_SSE"
9098 "#")
9099
9100 ;; Splitters for fp abs and neg.
9101
9102 (define_split
9103 [(set (match_operand 0 "fp_register_operand")
9104 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9105 (use (match_operand 2))
9106 (clobber (reg:CC FLAGS_REG))]
9107 "reload_completed"
9108 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9109
9110 (define_split
9111 [(set (match_operand 0 "sse_reg_operand")
9112 (match_operator 3 "absneg_operator"
9113 [(match_operand 1 "register_operand")]))
9114 (use (match_operand 2 "nonimmediate_operand"))
9115 (clobber (reg:CC FLAGS_REG))]
9116 "reload_completed"
9117 [(set (match_dup 0) (match_dup 3))]
9118 {
9119 machine_mode mode = GET_MODE (operands[0]);
9120 machine_mode vmode = GET_MODE (operands[2]);
9121 rtx tmp;
9122
9123 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9124 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9125 if (operands_match_p (operands[0], operands[2]))
9126 std::swap (operands[1], operands[2]);
9127 if (GET_CODE (operands[3]) == ABS)
9128 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9129 else
9130 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9131 operands[3] = tmp;
9132 })
9133
9134 (define_split
9135 [(set (match_operand:SF 0 "general_reg_operand")
9136 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9137 (use (match_operand:V4SF 2))
9138 (clobber (reg:CC FLAGS_REG))]
9139 "reload_completed"
9140 [(parallel [(set (match_dup 0) (match_dup 1))
9141 (clobber (reg:CC FLAGS_REG))])]
9142 {
9143 rtx tmp;
9144 operands[0] = gen_lowpart (SImode, operands[0]);
9145 if (GET_CODE (operands[1]) == ABS)
9146 {
9147 tmp = gen_int_mode (0x7fffffff, SImode);
9148 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9149 }
9150 else
9151 {
9152 tmp = gen_int_mode (0x80000000, SImode);
9153 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9154 }
9155 operands[1] = tmp;
9156 })
9157
9158 (define_split
9159 [(set (match_operand:DF 0 "general_reg_operand")
9160 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9161 (use (match_operand 2))
9162 (clobber (reg:CC FLAGS_REG))]
9163 "reload_completed"
9164 [(parallel [(set (match_dup 0) (match_dup 1))
9165 (clobber (reg:CC FLAGS_REG))])]
9166 {
9167 rtx tmp;
9168 if (TARGET_64BIT)
9169 {
9170 tmp = gen_lowpart (DImode, operands[0]);
9171 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9172 operands[0] = tmp;
9173
9174 if (GET_CODE (operands[1]) == ABS)
9175 tmp = const0_rtx;
9176 else
9177 tmp = gen_rtx_NOT (DImode, tmp);
9178 }
9179 else
9180 {
9181 operands[0] = gen_highpart (SImode, operands[0]);
9182 if (GET_CODE (operands[1]) == ABS)
9183 {
9184 tmp = gen_int_mode (0x7fffffff, SImode);
9185 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9186 }
9187 else
9188 {
9189 tmp = gen_int_mode (0x80000000, SImode);
9190 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9191 }
9192 }
9193 operands[1] = tmp;
9194 })
9195
9196 (define_split
9197 [(set (match_operand:XF 0 "general_reg_operand")
9198 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9199 (use (match_operand 2))
9200 (clobber (reg:CC FLAGS_REG))]
9201 "reload_completed"
9202 [(parallel [(set (match_dup 0) (match_dup 1))
9203 (clobber (reg:CC FLAGS_REG))])]
9204 {
9205 rtx tmp;
9206 operands[0] = gen_rtx_REG (SImode,
9207 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9208 if (GET_CODE (operands[1]) == ABS)
9209 {
9210 tmp = GEN_INT (0x7fff);
9211 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9212 }
9213 else
9214 {
9215 tmp = GEN_INT (0x8000);
9216 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9217 }
9218 operands[1] = tmp;
9219 })
9220
9221 ;; Conditionalize these after reload. If they match before reload, we
9222 ;; lose the clobber and ability to use integer instructions.
9223
9224 (define_insn "*<code><mode>2_1"
9225 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9226 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9227 "TARGET_80387
9228 && (reload_completed
9229 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9230 "f<absneg_mnemonic>"
9231 [(set_attr "type" "fsgn")
9232 (set_attr "mode" "<MODE>")])
9233
9234 (define_insn "*<code>extendsfdf2"
9235 [(set (match_operand:DF 0 "register_operand" "=f")
9236 (absneg:DF (float_extend:DF
9237 (match_operand:SF 1 "register_operand" "0"))))]
9238 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9239 "f<absneg_mnemonic>"
9240 [(set_attr "type" "fsgn")
9241 (set_attr "mode" "DF")])
9242
9243 (define_insn "*<code>extendsfxf2"
9244 [(set (match_operand:XF 0 "register_operand" "=f")
9245 (absneg:XF (float_extend:XF
9246 (match_operand:SF 1 "register_operand" "0"))))]
9247 "TARGET_80387"
9248 "f<absneg_mnemonic>"
9249 [(set_attr "type" "fsgn")
9250 (set_attr "mode" "XF")])
9251
9252 (define_insn "*<code>extenddfxf2"
9253 [(set (match_operand:XF 0 "register_operand" "=f")
9254 (absneg:XF (float_extend:XF
9255 (match_operand:DF 1 "register_operand" "0"))))]
9256 "TARGET_80387"
9257 "f<absneg_mnemonic>"
9258 [(set_attr "type" "fsgn")
9259 (set_attr "mode" "XF")])
9260
9261 ;; Copysign instructions
9262
9263 (define_mode_iterator CSGNMODE [SF DF TF])
9264 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9265
9266 (define_expand "copysign<mode>3"
9267 [(match_operand:CSGNMODE 0 "register_operand")
9268 (match_operand:CSGNMODE 1 "nonmemory_operand")
9269 (match_operand:CSGNMODE 2 "register_operand")]
9270 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9271 || (TARGET_SSE && (<MODE>mode == TFmode))"
9272 "ix86_expand_copysign (operands); DONE;")
9273
9274 (define_insn_and_split "copysign<mode>3_const"
9275 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
9276 (unspec:CSGNMODE
9277 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
9278 (match_operand:CSGNMODE 2 "register_operand" "0")
9279 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
9280 UNSPEC_COPYSIGN))]
9281 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9282 || (TARGET_SSE && (<MODE>mode == TFmode))"
9283 "#"
9284 "&& reload_completed"
9285 [(const_int 0)]
9286 "ix86_split_copysign_const (operands); DONE;")
9287
9288 (define_insn "copysign<mode>3_var"
9289 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9290 (unspec:CSGNMODE
9291 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
9292 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
9293 (match_operand:<CSGNVMODE> 4
9294 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9295 (match_operand:<CSGNVMODE> 5
9296 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9297 UNSPEC_COPYSIGN))
9298 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9299 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9300 || (TARGET_SSE && (<MODE>mode == TFmode))"
9301 "#")
9302
9303 (define_split
9304 [(set (match_operand:CSGNMODE 0 "register_operand")
9305 (unspec:CSGNMODE
9306 [(match_operand:CSGNMODE 2 "register_operand")
9307 (match_operand:CSGNMODE 3 "register_operand")
9308 (match_operand:<CSGNVMODE> 4)
9309 (match_operand:<CSGNVMODE> 5)]
9310 UNSPEC_COPYSIGN))
9311 (clobber (match_scratch:<CSGNVMODE> 1))]
9312 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9313 || (TARGET_SSE && (<MODE>mode == TFmode)))
9314 && reload_completed"
9315 [(const_int 0)]
9316 "ix86_split_copysign_var (operands); DONE;")
9317 \f
9318 ;; One complement instructions
9319
9320 (define_expand "one_cmpl<mode>2"
9321 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9322 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
9323 ""
9324 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9325
9326 (define_insn_and_split "*one_cmpldi2_doubleword"
9327 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9328 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9329 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9330 && ix86_unary_operator_ok (NOT, DImode, operands)"
9331 "#"
9332 "&& reload_completed"
9333 [(set (match_dup 0)
9334 (not:SI (match_dup 1)))
9335 (set (match_dup 2)
9336 (not:SI (match_dup 3)))]
9337 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9338
9339 (define_insn "*one_cmpl<mode>2_1"
9340 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9341 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9342 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9343 "not{<imodesuffix>}\t%0"
9344 [(set_attr "type" "negnot")
9345 (set_attr "mode" "<MODE>")])
9346
9347 ;; ??? Currently never generated - xor is used instead.
9348 (define_insn "*one_cmplsi2_1_zext"
9349 [(set (match_operand:DI 0 "register_operand" "=r")
9350 (zero_extend:DI
9351 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9352 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9353 "not{l}\t%k0"
9354 [(set_attr "type" "negnot")
9355 (set_attr "mode" "SI")])
9356
9357 (define_insn "*one_cmplqi2_1"
9358 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9359 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9360 "ix86_unary_operator_ok (NOT, QImode, operands)"
9361 "@
9362 not{b}\t%0
9363 not{l}\t%k0"
9364 [(set_attr "type" "negnot")
9365 (set_attr "mode" "QI,SI")
9366 ;; Potential partial reg stall on alternative 1.
9367 (set (attr "preferred_for_speed")
9368 (cond [(eq_attr "alternative" "1")
9369 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9370 (symbol_ref "true")))])
9371
9372 (define_insn "*one_cmpl<mode>2_2"
9373 [(set (reg FLAGS_REG)
9374 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9375 (const_int 0)))
9376 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9377 (not:SWI (match_dup 1)))]
9378 "ix86_match_ccmode (insn, CCNOmode)
9379 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9380 "#"
9381 [(set_attr "type" "alu1")
9382 (set_attr "mode" "<MODE>")])
9383
9384 (define_split
9385 [(set (match_operand 0 "flags_reg_operand")
9386 (match_operator 2 "compare_operator"
9387 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9388 (const_int 0)]))
9389 (set (match_operand:SWI 1 "nonimmediate_operand")
9390 (not:SWI (match_dup 3)))]
9391 "ix86_match_ccmode (insn, CCNOmode)"
9392 [(parallel [(set (match_dup 0)
9393 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9394 (const_int 0)]))
9395 (set (match_dup 1)
9396 (xor:SWI (match_dup 3) (const_int -1)))])])
9397
9398 ;; ??? Currently never generated - xor is used instead.
9399 (define_insn "*one_cmplsi2_2_zext"
9400 [(set (reg FLAGS_REG)
9401 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9402 (const_int 0)))
9403 (set (match_operand:DI 0 "register_operand" "=r")
9404 (zero_extend:DI (not:SI (match_dup 1))))]
9405 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9406 && ix86_unary_operator_ok (NOT, SImode, operands)"
9407 "#"
9408 [(set_attr "type" "alu1")
9409 (set_attr "mode" "SI")])
9410
9411 (define_split
9412 [(set (match_operand 0 "flags_reg_operand")
9413 (match_operator 2 "compare_operator"
9414 [(not:SI (match_operand:SI 3 "register_operand"))
9415 (const_int 0)]))
9416 (set (match_operand:DI 1 "register_operand")
9417 (zero_extend:DI (not:SI (match_dup 3))))]
9418 "ix86_match_ccmode (insn, CCNOmode)"
9419 [(parallel [(set (match_dup 0)
9420 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9421 (const_int 0)]))
9422 (set (match_dup 1)
9423 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9424 \f
9425 ;; Shift instructions
9426
9427 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9428 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9429 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9430 ;; from the assembler input.
9431 ;;
9432 ;; This instruction shifts the target reg/mem as usual, but instead of
9433 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9434 ;; is a left shift double, bits are taken from the high order bits of
9435 ;; reg, else if the insn is a shift right double, bits are taken from the
9436 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9437 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9438 ;;
9439 ;; Since sh[lr]d does not change the `reg' operand, that is done
9440 ;; separately, making all shifts emit pairs of shift double and normal
9441 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9442 ;; support a 63 bit shift, each shift where the count is in a reg expands
9443 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9444 ;;
9445 ;; If the shift count is a constant, we need never emit more than one
9446 ;; shift pair, instead using moves and sign extension for counts greater
9447 ;; than 31.
9448
9449 (define_expand "ashl<mode>3"
9450 [(set (match_operand:SDWIM 0 "<shift_operand>")
9451 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9452 (match_operand:QI 2 "nonmemory_operand")))]
9453 ""
9454 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9455
9456 (define_insn "*ashl<mode>3_doubleword"
9457 [(set (match_operand:DWI 0 "register_operand" "=&r")
9458 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
9459 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9460 (clobber (reg:CC FLAGS_REG))]
9461 ""
9462 "#"
9463 [(set_attr "type" "multi")])
9464
9465 (define_split
9466 [(set (match_operand:DWI 0 "register_operand")
9467 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9468 (match_operand:QI 2 "nonmemory_operand")))
9469 (clobber (reg:CC FLAGS_REG))]
9470 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9471 [(const_int 0)]
9472 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9473
9474 ;; By default we don't ask for a scratch register, because when DWImode
9475 ;; values are manipulated, registers are already at a premium. But if
9476 ;; we have one handy, we won't turn it away.
9477
9478 (define_peephole2
9479 [(match_scratch:DWIH 3 "r")
9480 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9481 (ashift:<DWI>
9482 (match_operand:<DWI> 1 "nonmemory_operand")
9483 (match_operand:QI 2 "nonmemory_operand")))
9484 (clobber (reg:CC FLAGS_REG))])
9485 (match_dup 3)]
9486 "TARGET_CMOVE"
9487 [(const_int 0)]
9488 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9489
9490 (define_insn "x86_64_shld"
9491 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9492 (ior:DI (ashift:DI (match_dup 0)
9493 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9494 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9495 (minus:QI (const_int 64) (match_dup 2)))))
9496 (clobber (reg:CC FLAGS_REG))]
9497 "TARGET_64BIT"
9498 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9499 [(set_attr "type" "ishift")
9500 (set_attr "prefix_0f" "1")
9501 (set_attr "mode" "DI")
9502 (set_attr "athlon_decode" "vector")
9503 (set_attr "amdfam10_decode" "vector")
9504 (set_attr "bdver1_decode" "vector")])
9505
9506 (define_insn "x86_shld"
9507 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9508 (ior:SI (ashift:SI (match_dup 0)
9509 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9510 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9511 (minus:QI (const_int 32) (match_dup 2)))))
9512 (clobber (reg:CC FLAGS_REG))]
9513 ""
9514 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9515 [(set_attr "type" "ishift")
9516 (set_attr "prefix_0f" "1")
9517 (set_attr "mode" "SI")
9518 (set_attr "pent_pair" "np")
9519 (set_attr "athlon_decode" "vector")
9520 (set_attr "amdfam10_decode" "vector")
9521 (set_attr "bdver1_decode" "vector")])
9522
9523 (define_expand "x86_shift<mode>_adj_1"
9524 [(set (reg:CCZ FLAGS_REG)
9525 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9526 (match_dup 4))
9527 (const_int 0)))
9528 (set (match_operand:SWI48 0 "register_operand")
9529 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9530 (match_operand:SWI48 1 "register_operand")
9531 (match_dup 0)))
9532 (set (match_dup 1)
9533 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9534 (match_operand:SWI48 3 "register_operand")
9535 (match_dup 1)))]
9536 "TARGET_CMOVE"
9537 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9538
9539 (define_expand "x86_shift<mode>_adj_2"
9540 [(use (match_operand:SWI48 0 "register_operand"))
9541 (use (match_operand:SWI48 1 "register_operand"))
9542 (use (match_operand:QI 2 "register_operand"))]
9543 ""
9544 {
9545 rtx_code_label *label = gen_label_rtx ();
9546 rtx tmp;
9547
9548 emit_insn (gen_testqi_ccz_1 (operands[2],
9549 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9550
9551 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9552 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9553 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9554 gen_rtx_LABEL_REF (VOIDmode, label),
9555 pc_rtx);
9556 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9557 JUMP_LABEL (tmp) = label;
9558
9559 emit_move_insn (operands[0], operands[1]);
9560 ix86_expand_clear (operands[1]);
9561
9562 emit_label (label);
9563 LABEL_NUSES (label) = 1;
9564
9565 DONE;
9566 })
9567
9568 ;; Avoid useless masking of count operand.
9569 (define_insn_and_split "*ashl<mode>3_mask"
9570 [(set (match_operand:SWI48 0 "nonimmediate_operand")
9571 (ashift:SWI48
9572 (match_operand:SWI48 1 "nonimmediate_operand")
9573 (subreg:QI
9574 (and:SI
9575 (match_operand:SI 2 "register_operand")
9576 (match_operand:SI 3 "const_int_operand")) 0)))
9577 (clobber (reg:CC FLAGS_REG))]
9578 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9579 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9580 == GET_MODE_BITSIZE (<MODE>mode)-1
9581 && can_create_pseudo_p ()"
9582 "#"
9583 "&& 1"
9584 [(parallel
9585 [(set (match_dup 0)
9586 (ashift:SWI48 (match_dup 1)
9587 (match_dup 2)))
9588 (clobber (reg:CC FLAGS_REG))])]
9589 "operands[2] = gen_lowpart (QImode, operands[2]);")
9590
9591 (define_insn "*bmi2_ashl<mode>3_1"
9592 [(set (match_operand:SWI48 0 "register_operand" "=r")
9593 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9594 (match_operand:SWI48 2 "register_operand" "r")))]
9595 "TARGET_BMI2"
9596 "shlx\t{%2, %1, %0|%0, %1, %2}"
9597 [(set_attr "type" "ishiftx")
9598 (set_attr "mode" "<MODE>")])
9599
9600 (define_insn "*ashl<mode>3_1"
9601 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9602 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9603 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9604 (clobber (reg:CC FLAGS_REG))]
9605 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9606 {
9607 switch (get_attr_type (insn))
9608 {
9609 case TYPE_LEA:
9610 case TYPE_ISHIFTX:
9611 return "#";
9612
9613 case TYPE_ALU:
9614 gcc_assert (operands[2] == const1_rtx);
9615 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9616 return "add{<imodesuffix>}\t%0, %0";
9617
9618 default:
9619 if (operands[2] == const1_rtx
9620 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9621 return "sal{<imodesuffix>}\t%0";
9622 else
9623 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9624 }
9625 }
9626 [(set_attr "isa" "*,*,bmi2")
9627 (set (attr "type")
9628 (cond [(eq_attr "alternative" "1")
9629 (const_string "lea")
9630 (eq_attr "alternative" "2")
9631 (const_string "ishiftx")
9632 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9633 (match_operand 0 "register_operand"))
9634 (match_operand 2 "const1_operand"))
9635 (const_string "alu")
9636 ]
9637 (const_string "ishift")))
9638 (set (attr "length_immediate")
9639 (if_then_else
9640 (ior (eq_attr "type" "alu")
9641 (and (eq_attr "type" "ishift")
9642 (and (match_operand 2 "const1_operand")
9643 (ior (match_test "TARGET_SHIFT1")
9644 (match_test "optimize_function_for_size_p (cfun)")))))
9645 (const_string "0")
9646 (const_string "*")))
9647 (set_attr "mode" "<MODE>")])
9648
9649 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9650 (define_split
9651 [(set (match_operand:SWI48 0 "register_operand")
9652 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9653 (match_operand:QI 2 "register_operand")))
9654 (clobber (reg:CC FLAGS_REG))]
9655 "TARGET_BMI2 && reload_completed"
9656 [(set (match_dup 0)
9657 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9658 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9659
9660 (define_insn "*bmi2_ashlsi3_1_zext"
9661 [(set (match_operand:DI 0 "register_operand" "=r")
9662 (zero_extend:DI
9663 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9664 (match_operand:SI 2 "register_operand" "r"))))]
9665 "TARGET_64BIT && TARGET_BMI2"
9666 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9667 [(set_attr "type" "ishiftx")
9668 (set_attr "mode" "SI")])
9669
9670 (define_insn "*ashlsi3_1_zext"
9671 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9672 (zero_extend:DI
9673 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9674 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9675 (clobber (reg:CC FLAGS_REG))]
9676 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9677 {
9678 switch (get_attr_type (insn))
9679 {
9680 case TYPE_LEA:
9681 case TYPE_ISHIFTX:
9682 return "#";
9683
9684 case TYPE_ALU:
9685 gcc_assert (operands[2] == const1_rtx);
9686 return "add{l}\t%k0, %k0";
9687
9688 default:
9689 if (operands[2] == const1_rtx
9690 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9691 return "sal{l}\t%k0";
9692 else
9693 return "sal{l}\t{%2, %k0|%k0, %2}";
9694 }
9695 }
9696 [(set_attr "isa" "*,*,bmi2")
9697 (set (attr "type")
9698 (cond [(eq_attr "alternative" "1")
9699 (const_string "lea")
9700 (eq_attr "alternative" "2")
9701 (const_string "ishiftx")
9702 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9703 (match_operand 2 "const1_operand"))
9704 (const_string "alu")
9705 ]
9706 (const_string "ishift")))
9707 (set (attr "length_immediate")
9708 (if_then_else
9709 (ior (eq_attr "type" "alu")
9710 (and (eq_attr "type" "ishift")
9711 (and (match_operand 2 "const1_operand")
9712 (ior (match_test "TARGET_SHIFT1")
9713 (match_test "optimize_function_for_size_p (cfun)")))))
9714 (const_string "0")
9715 (const_string "*")))
9716 (set_attr "mode" "SI")])
9717
9718 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9719 (define_split
9720 [(set (match_operand:DI 0 "register_operand")
9721 (zero_extend:DI
9722 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9723 (match_operand:QI 2 "register_operand"))))
9724 (clobber (reg:CC FLAGS_REG))]
9725 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9726 [(set (match_dup 0)
9727 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9728 "operands[2] = gen_lowpart (SImode, operands[2]);")
9729
9730 (define_insn "*ashlhi3_1"
9731 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9732 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9733 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9734 (clobber (reg:CC FLAGS_REG))]
9735 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9736 {
9737 switch (get_attr_type (insn))
9738 {
9739 case TYPE_LEA:
9740 return "#";
9741
9742 case TYPE_ALU:
9743 gcc_assert (operands[2] == const1_rtx);
9744 return "add{w}\t%0, %0";
9745
9746 default:
9747 if (operands[2] == const1_rtx
9748 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9749 return "sal{w}\t%0";
9750 else
9751 return "sal{w}\t{%2, %0|%0, %2}";
9752 }
9753 }
9754 [(set (attr "type")
9755 (cond [(eq_attr "alternative" "1")
9756 (const_string "lea")
9757 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9758 (match_operand 0 "register_operand"))
9759 (match_operand 2 "const1_operand"))
9760 (const_string "alu")
9761 ]
9762 (const_string "ishift")))
9763 (set (attr "length_immediate")
9764 (if_then_else
9765 (ior (eq_attr "type" "alu")
9766 (and (eq_attr "type" "ishift")
9767 (and (match_operand 2 "const1_operand")
9768 (ior (match_test "TARGET_SHIFT1")
9769 (match_test "optimize_function_for_size_p (cfun)")))))
9770 (const_string "0")
9771 (const_string "*")))
9772 (set_attr "mode" "HI,SI")])
9773
9774 (define_insn "*ashlqi3_1"
9775 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9776 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9777 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9778 (clobber (reg:CC FLAGS_REG))]
9779 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9780 {
9781 switch (get_attr_type (insn))
9782 {
9783 case TYPE_LEA:
9784 return "#";
9785
9786 case TYPE_ALU:
9787 gcc_assert (operands[2] == const1_rtx);
9788 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
9789 return "add{l}\t%k0, %k0";
9790 else
9791 return "add{b}\t%0, %0";
9792
9793 default:
9794 if (operands[2] == const1_rtx
9795 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9796 {
9797 if (get_attr_mode (insn) == MODE_SI)
9798 return "sal{l}\t%k0";
9799 else
9800 return "sal{b}\t%0";
9801 }
9802 else
9803 {
9804 if (get_attr_mode (insn) == MODE_SI)
9805 return "sal{l}\t{%2, %k0|%k0, %2}";
9806 else
9807 return "sal{b}\t{%2, %0|%0, %2}";
9808 }
9809 }
9810 }
9811 [(set (attr "type")
9812 (cond [(eq_attr "alternative" "2")
9813 (const_string "lea")
9814 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9815 (match_operand 0 "register_operand"))
9816 (match_operand 2 "const1_operand"))
9817 (const_string "alu")
9818 ]
9819 (const_string "ishift")))
9820 (set (attr "length_immediate")
9821 (if_then_else
9822 (ior (eq_attr "type" "alu")
9823 (and (eq_attr "type" "ishift")
9824 (and (match_operand 2 "const1_operand")
9825 (ior (match_test "TARGET_SHIFT1")
9826 (match_test "optimize_function_for_size_p (cfun)")))))
9827 (const_string "0")
9828 (const_string "*")))
9829 (set_attr "mode" "QI,SI,SI")
9830 ;; Potential partial reg stall on alternative 1.
9831 (set (attr "preferred_for_speed")
9832 (cond [(eq_attr "alternative" "1")
9833 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9834 (symbol_ref "true")))])
9835
9836 (define_insn "*ashlqi3_1_slp"
9837 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9838 (ashift:QI (match_dup 0)
9839 (match_operand:QI 1 "nonmemory_operand" "cI")))
9840 (clobber (reg:CC FLAGS_REG))]
9841 "(optimize_function_for_size_p (cfun)
9842 || !TARGET_PARTIAL_FLAG_REG_STALL
9843 || (operands[1] == const1_rtx
9844 && (TARGET_SHIFT1
9845 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9846 {
9847 switch (get_attr_type (insn))
9848 {
9849 case TYPE_ALU:
9850 gcc_assert (operands[1] == const1_rtx);
9851 return "add{b}\t%0, %0";
9852
9853 default:
9854 if (operands[1] == const1_rtx
9855 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9856 return "sal{b}\t%0";
9857 else
9858 return "sal{b}\t{%1, %0|%0, %1}";
9859 }
9860 }
9861 [(set (attr "type")
9862 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9863 (match_operand 0 "register_operand"))
9864 (match_operand 1 "const1_operand"))
9865 (const_string "alu")
9866 ]
9867 (const_string "ishift1")))
9868 (set (attr "length_immediate")
9869 (if_then_else
9870 (ior (eq_attr "type" "alu")
9871 (and (eq_attr "type" "ishift1")
9872 (and (match_operand 1 "const1_operand")
9873 (ior (match_test "TARGET_SHIFT1")
9874 (match_test "optimize_function_for_size_p (cfun)")))))
9875 (const_string "0")
9876 (const_string "*")))
9877 (set_attr "mode" "QI")])
9878
9879 ;; Convert ashift to the lea pattern to avoid flags dependency.
9880 (define_split
9881 [(set (match_operand:SWI 0 "register_operand")
9882 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
9883 (match_operand 2 "const_0_to_3_operand")))
9884 (clobber (reg:CC FLAGS_REG))]
9885 "reload_completed
9886 && REGNO (operands[0]) != REGNO (operands[1])"
9887 [(set (match_dup 0)
9888 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
9889 {
9890 if (<MODE>mode != <LEAMODE>mode)
9891 {
9892 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
9893 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
9894 }
9895 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
9896 })
9897
9898 ;; Convert ashift to the lea pattern to avoid flags dependency.
9899 (define_split
9900 [(set (match_operand:DI 0 "register_operand")
9901 (zero_extend:DI
9902 (ashift:SI (match_operand:SI 1 "index_register_operand")
9903 (match_operand 2 "const_0_to_3_operand"))))
9904 (clobber (reg:CC FLAGS_REG))]
9905 "TARGET_64BIT && reload_completed
9906 && REGNO (operands[0]) != REGNO (operands[1])"
9907 [(set (match_dup 0)
9908 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9909 {
9910 operands[1] = gen_lowpart (SImode, operands[1]);
9911 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
9912 })
9913
9914 ;; This pattern can't accept a variable shift count, since shifts by
9915 ;; zero don't affect the flags. We assume that shifts by constant
9916 ;; zero are optimized away.
9917 (define_insn "*ashl<mode>3_cmp"
9918 [(set (reg FLAGS_REG)
9919 (compare
9920 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9921 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9922 (const_int 0)))
9923 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9924 (ashift:SWI (match_dup 1) (match_dup 2)))]
9925 "(optimize_function_for_size_p (cfun)
9926 || !TARGET_PARTIAL_FLAG_REG_STALL
9927 || (operands[2] == const1_rtx
9928 && (TARGET_SHIFT1
9929 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9930 && ix86_match_ccmode (insn, CCGOCmode)
9931 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9932 {
9933 switch (get_attr_type (insn))
9934 {
9935 case TYPE_ALU:
9936 gcc_assert (operands[2] == const1_rtx);
9937 return "add{<imodesuffix>}\t%0, %0";
9938
9939 default:
9940 if (operands[2] == const1_rtx
9941 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9942 return "sal{<imodesuffix>}\t%0";
9943 else
9944 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9945 }
9946 }
9947 [(set (attr "type")
9948 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9949 (match_operand 0 "register_operand"))
9950 (match_operand 2 "const1_operand"))
9951 (const_string "alu")
9952 ]
9953 (const_string "ishift")))
9954 (set (attr "length_immediate")
9955 (if_then_else
9956 (ior (eq_attr "type" "alu")
9957 (and (eq_attr "type" "ishift")
9958 (and (match_operand 2 "const1_operand")
9959 (ior (match_test "TARGET_SHIFT1")
9960 (match_test "optimize_function_for_size_p (cfun)")))))
9961 (const_string "0")
9962 (const_string "*")))
9963 (set_attr "mode" "<MODE>")])
9964
9965 (define_insn "*ashlsi3_cmp_zext"
9966 [(set (reg FLAGS_REG)
9967 (compare
9968 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9969 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9970 (const_int 0)))
9971 (set (match_operand:DI 0 "register_operand" "=r")
9972 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9973 "TARGET_64BIT
9974 && (optimize_function_for_size_p (cfun)
9975 || !TARGET_PARTIAL_FLAG_REG_STALL
9976 || (operands[2] == const1_rtx
9977 && (TARGET_SHIFT1
9978 || TARGET_DOUBLE_WITH_ADD)))
9979 && ix86_match_ccmode (insn, CCGOCmode)
9980 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9981 {
9982 switch (get_attr_type (insn))
9983 {
9984 case TYPE_ALU:
9985 gcc_assert (operands[2] == const1_rtx);
9986 return "add{l}\t%k0, %k0";
9987
9988 default:
9989 if (operands[2] == const1_rtx
9990 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9991 return "sal{l}\t%k0";
9992 else
9993 return "sal{l}\t{%2, %k0|%k0, %2}";
9994 }
9995 }
9996 [(set (attr "type")
9997 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9998 (match_operand 2 "const1_operand"))
9999 (const_string "alu")
10000 ]
10001 (const_string "ishift")))
10002 (set (attr "length_immediate")
10003 (if_then_else
10004 (ior (eq_attr "type" "alu")
10005 (and (eq_attr "type" "ishift")
10006 (and (match_operand 2 "const1_operand")
10007 (ior (match_test "TARGET_SHIFT1")
10008 (match_test "optimize_function_for_size_p (cfun)")))))
10009 (const_string "0")
10010 (const_string "*")))
10011 (set_attr "mode" "SI")])
10012
10013 (define_insn "*ashl<mode>3_cconly"
10014 [(set (reg FLAGS_REG)
10015 (compare
10016 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10017 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10018 (const_int 0)))
10019 (clobber (match_scratch:SWI 0 "=<r>"))]
10020 "(optimize_function_for_size_p (cfun)
10021 || !TARGET_PARTIAL_FLAG_REG_STALL
10022 || (operands[2] == const1_rtx
10023 && (TARGET_SHIFT1
10024 || TARGET_DOUBLE_WITH_ADD)))
10025 && ix86_match_ccmode (insn, CCGOCmode)"
10026 {
10027 switch (get_attr_type (insn))
10028 {
10029 case TYPE_ALU:
10030 gcc_assert (operands[2] == const1_rtx);
10031 return "add{<imodesuffix>}\t%0, %0";
10032
10033 default:
10034 if (operands[2] == const1_rtx
10035 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10036 return "sal{<imodesuffix>}\t%0";
10037 else
10038 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10039 }
10040 }
10041 [(set (attr "type")
10042 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10043 (match_operand 0 "register_operand"))
10044 (match_operand 2 "const1_operand"))
10045 (const_string "alu")
10046 ]
10047 (const_string "ishift")))
10048 (set (attr "length_immediate")
10049 (if_then_else
10050 (ior (eq_attr "type" "alu")
10051 (and (eq_attr "type" "ishift")
10052 (and (match_operand 2 "const1_operand")
10053 (ior (match_test "TARGET_SHIFT1")
10054 (match_test "optimize_function_for_size_p (cfun)")))))
10055 (const_string "0")
10056 (const_string "*")))
10057 (set_attr "mode" "<MODE>")])
10058
10059 ;; See comment above `ashl<mode>3' about how this works.
10060
10061 (define_expand "<shift_insn><mode>3"
10062 [(set (match_operand:SDWIM 0 "<shift_operand>")
10063 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10064 (match_operand:QI 2 "nonmemory_operand")))]
10065 ""
10066 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10067
10068 ;; Avoid useless masking of count operand.
10069 (define_insn_and_split "*<shift_insn><mode>3_mask"
10070 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10071 (any_shiftrt:SWI48
10072 (match_operand:SWI48 1 "nonimmediate_operand")
10073 (subreg:QI
10074 (and:SI
10075 (match_operand:SI 2 "register_operand")
10076 (match_operand:SI 3 "const_int_operand")) 0)))
10077 (clobber (reg:CC FLAGS_REG))]
10078 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10079 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10080 == GET_MODE_BITSIZE (<MODE>mode)-1
10081 && can_create_pseudo_p ()"
10082 "#"
10083 "&& 1"
10084 [(parallel
10085 [(set (match_dup 0)
10086 (any_shiftrt:SWI48 (match_dup 1)
10087 (match_dup 2)))
10088 (clobber (reg:CC FLAGS_REG))])]
10089 "operands[2] = gen_lowpart (QImode, operands[2]);")
10090
10091 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10092 [(set (match_operand:DWI 0 "register_operand" "=&r")
10093 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10094 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10095 (clobber (reg:CC FLAGS_REG))]
10096 ""
10097 "#"
10098 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10099 [(const_int 0)]
10100 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10101 [(set_attr "type" "multi")])
10102
10103 ;; By default we don't ask for a scratch register, because when DWImode
10104 ;; values are manipulated, registers are already at a premium. But if
10105 ;; we have one handy, we won't turn it away.
10106
10107 (define_peephole2
10108 [(match_scratch:DWIH 3 "r")
10109 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10110 (any_shiftrt:<DWI>
10111 (match_operand:<DWI> 1 "register_operand")
10112 (match_operand:QI 2 "nonmemory_operand")))
10113 (clobber (reg:CC FLAGS_REG))])
10114 (match_dup 3)]
10115 "TARGET_CMOVE"
10116 [(const_int 0)]
10117 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10118
10119 (define_insn "x86_64_shrd"
10120 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10121 (ior:DI (lshiftrt:DI (match_dup 0)
10122 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10123 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10124 (minus:QI (const_int 64) (match_dup 2)))))
10125 (clobber (reg:CC FLAGS_REG))]
10126 "TARGET_64BIT"
10127 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10128 [(set_attr "type" "ishift")
10129 (set_attr "prefix_0f" "1")
10130 (set_attr "mode" "DI")
10131 (set_attr "athlon_decode" "vector")
10132 (set_attr "amdfam10_decode" "vector")
10133 (set_attr "bdver1_decode" "vector")])
10134
10135 (define_insn "x86_shrd"
10136 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10137 (ior:SI (lshiftrt:SI (match_dup 0)
10138 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10139 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10140 (minus:QI (const_int 32) (match_dup 2)))))
10141 (clobber (reg:CC FLAGS_REG))]
10142 ""
10143 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10144 [(set_attr "type" "ishift")
10145 (set_attr "prefix_0f" "1")
10146 (set_attr "mode" "SI")
10147 (set_attr "pent_pair" "np")
10148 (set_attr "athlon_decode" "vector")
10149 (set_attr "amdfam10_decode" "vector")
10150 (set_attr "bdver1_decode" "vector")])
10151
10152 (define_insn "ashrdi3_cvt"
10153 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10154 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10155 (match_operand:QI 2 "const_int_operand")))
10156 (clobber (reg:CC FLAGS_REG))]
10157 "TARGET_64BIT && INTVAL (operands[2]) == 63
10158 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10159 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10160 "@
10161 {cqto|cqo}
10162 sar{q}\t{%2, %0|%0, %2}"
10163 [(set_attr "type" "imovx,ishift")
10164 (set_attr "prefix_0f" "0,*")
10165 (set_attr "length_immediate" "0,*")
10166 (set_attr "modrm" "0,1")
10167 (set_attr "mode" "DI")])
10168
10169 (define_insn "*ashrsi3_cvt_zext"
10170 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10171 (zero_extend:DI
10172 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10173 (match_operand:QI 2 "const_int_operand"))))
10174 (clobber (reg:CC FLAGS_REG))]
10175 "TARGET_64BIT && INTVAL (operands[2]) == 31
10176 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10177 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10178 "@
10179 {cltd|cdq}
10180 sar{l}\t{%2, %k0|%k0, %2}"
10181 [(set_attr "type" "imovx,ishift")
10182 (set_attr "prefix_0f" "0,*")
10183 (set_attr "length_immediate" "0,*")
10184 (set_attr "modrm" "0,1")
10185 (set_attr "mode" "SI")])
10186
10187 (define_insn "ashrsi3_cvt"
10188 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10189 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10190 (match_operand:QI 2 "const_int_operand")))
10191 (clobber (reg:CC FLAGS_REG))]
10192 "INTVAL (operands[2]) == 31
10193 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10194 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10195 "@
10196 {cltd|cdq}
10197 sar{l}\t{%2, %0|%0, %2}"
10198 [(set_attr "type" "imovx,ishift")
10199 (set_attr "prefix_0f" "0,*")
10200 (set_attr "length_immediate" "0,*")
10201 (set_attr "modrm" "0,1")
10202 (set_attr "mode" "SI")])
10203
10204 (define_expand "x86_shift<mode>_adj_3"
10205 [(use (match_operand:SWI48 0 "register_operand"))
10206 (use (match_operand:SWI48 1 "register_operand"))
10207 (use (match_operand:QI 2 "register_operand"))]
10208 ""
10209 {
10210 rtx_code_label *label = gen_label_rtx ();
10211 rtx tmp;
10212
10213 emit_insn (gen_testqi_ccz_1 (operands[2],
10214 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10215
10216 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10217 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10218 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10219 gen_rtx_LABEL_REF (VOIDmode, label),
10220 pc_rtx);
10221 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10222 JUMP_LABEL (tmp) = label;
10223
10224 emit_move_insn (operands[0], operands[1]);
10225 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10226 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10227 emit_label (label);
10228 LABEL_NUSES (label) = 1;
10229
10230 DONE;
10231 })
10232
10233 (define_insn "*bmi2_<shift_insn><mode>3_1"
10234 [(set (match_operand:SWI48 0 "register_operand" "=r")
10235 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10236 (match_operand:SWI48 2 "register_operand" "r")))]
10237 "TARGET_BMI2"
10238 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10239 [(set_attr "type" "ishiftx")
10240 (set_attr "mode" "<MODE>")])
10241
10242 (define_insn "*<shift_insn><mode>3_1"
10243 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10244 (any_shiftrt:SWI48
10245 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10246 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10247 (clobber (reg:CC FLAGS_REG))]
10248 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10249 {
10250 switch (get_attr_type (insn))
10251 {
10252 case TYPE_ISHIFTX:
10253 return "#";
10254
10255 default:
10256 if (operands[2] == const1_rtx
10257 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10258 return "<shift>{<imodesuffix>}\t%0";
10259 else
10260 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10261 }
10262 }
10263 [(set_attr "isa" "*,bmi2")
10264 (set_attr "type" "ishift,ishiftx")
10265 (set (attr "length_immediate")
10266 (if_then_else
10267 (and (match_operand 2 "const1_operand")
10268 (ior (match_test "TARGET_SHIFT1")
10269 (match_test "optimize_function_for_size_p (cfun)")))
10270 (const_string "0")
10271 (const_string "*")))
10272 (set_attr "mode" "<MODE>")])
10273
10274 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10275 (define_split
10276 [(set (match_operand:SWI48 0 "register_operand")
10277 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10278 (match_operand:QI 2 "register_operand")))
10279 (clobber (reg:CC FLAGS_REG))]
10280 "TARGET_BMI2 && reload_completed"
10281 [(set (match_dup 0)
10282 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10283 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10284
10285 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10286 [(set (match_operand:DI 0 "register_operand" "=r")
10287 (zero_extend:DI
10288 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10289 (match_operand:SI 2 "register_operand" "r"))))]
10290 "TARGET_64BIT && TARGET_BMI2"
10291 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10292 [(set_attr "type" "ishiftx")
10293 (set_attr "mode" "SI")])
10294
10295 (define_insn "*<shift_insn>si3_1_zext"
10296 [(set (match_operand:DI 0 "register_operand" "=r,r")
10297 (zero_extend:DI
10298 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10299 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10300 (clobber (reg:CC FLAGS_REG))]
10301 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10302 {
10303 switch (get_attr_type (insn))
10304 {
10305 case TYPE_ISHIFTX:
10306 return "#";
10307
10308 default:
10309 if (operands[2] == const1_rtx
10310 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10311 return "<shift>{l}\t%k0";
10312 else
10313 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10314 }
10315 }
10316 [(set_attr "isa" "*,bmi2")
10317 (set_attr "type" "ishift,ishiftx")
10318 (set (attr "length_immediate")
10319 (if_then_else
10320 (and (match_operand 2 "const1_operand")
10321 (ior (match_test "TARGET_SHIFT1")
10322 (match_test "optimize_function_for_size_p (cfun)")))
10323 (const_string "0")
10324 (const_string "*")))
10325 (set_attr "mode" "SI")])
10326
10327 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10328 (define_split
10329 [(set (match_operand:DI 0 "register_operand")
10330 (zero_extend:DI
10331 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10332 (match_operand:QI 2 "register_operand"))))
10333 (clobber (reg:CC FLAGS_REG))]
10334 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10335 [(set (match_dup 0)
10336 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10337 "operands[2] = gen_lowpart (SImode, operands[2]);")
10338
10339 (define_insn "*<shift_insn><mode>3_1"
10340 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10341 (any_shiftrt:SWI12
10342 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10343 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10344 (clobber (reg:CC FLAGS_REG))]
10345 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10346 {
10347 if (operands[2] == const1_rtx
10348 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10349 return "<shift>{<imodesuffix>}\t%0";
10350 else
10351 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10352 }
10353 [(set_attr "type" "ishift")
10354 (set (attr "length_immediate")
10355 (if_then_else
10356 (and (match_operand 2 "const1_operand")
10357 (ior (match_test "TARGET_SHIFT1")
10358 (match_test "optimize_function_for_size_p (cfun)")))
10359 (const_string "0")
10360 (const_string "*")))
10361 (set_attr "mode" "<MODE>")])
10362
10363 (define_insn "*<shift_insn>qi3_1_slp"
10364 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10365 (any_shiftrt:QI (match_dup 0)
10366 (match_operand:QI 1 "nonmemory_operand" "cI")))
10367 (clobber (reg:CC FLAGS_REG))]
10368 "(optimize_function_for_size_p (cfun)
10369 || !TARGET_PARTIAL_REG_STALL
10370 || (operands[1] == const1_rtx
10371 && TARGET_SHIFT1))"
10372 {
10373 if (operands[1] == const1_rtx
10374 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10375 return "<shift>{b}\t%0";
10376 else
10377 return "<shift>{b}\t{%1, %0|%0, %1}";
10378 }
10379 [(set_attr "type" "ishift1")
10380 (set (attr "length_immediate")
10381 (if_then_else
10382 (and (match_operand 1 "const1_operand")
10383 (ior (match_test "TARGET_SHIFT1")
10384 (match_test "optimize_function_for_size_p (cfun)")))
10385 (const_string "0")
10386 (const_string "*")))
10387 (set_attr "mode" "QI")])
10388
10389 ;; This pattern can't accept a variable shift count, since shifts by
10390 ;; zero don't affect the flags. We assume that shifts by constant
10391 ;; zero are optimized away.
10392 (define_insn "*<shift_insn><mode>3_cmp"
10393 [(set (reg FLAGS_REG)
10394 (compare
10395 (any_shiftrt:SWI
10396 (match_operand:SWI 1 "nonimmediate_operand" "0")
10397 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10398 (const_int 0)))
10399 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10400 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10401 "(optimize_function_for_size_p (cfun)
10402 || !TARGET_PARTIAL_FLAG_REG_STALL
10403 || (operands[2] == const1_rtx
10404 && TARGET_SHIFT1))
10405 && ix86_match_ccmode (insn, CCGOCmode)
10406 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10407 {
10408 if (operands[2] == const1_rtx
10409 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10410 return "<shift>{<imodesuffix>}\t%0";
10411 else
10412 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10413 }
10414 [(set_attr "type" "ishift")
10415 (set (attr "length_immediate")
10416 (if_then_else
10417 (and (match_operand 2 "const1_operand")
10418 (ior (match_test "TARGET_SHIFT1")
10419 (match_test "optimize_function_for_size_p (cfun)")))
10420 (const_string "0")
10421 (const_string "*")))
10422 (set_attr "mode" "<MODE>")])
10423
10424 (define_insn "*<shift_insn>si3_cmp_zext"
10425 [(set (reg FLAGS_REG)
10426 (compare
10427 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10428 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10429 (const_int 0)))
10430 (set (match_operand:DI 0 "register_operand" "=r")
10431 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10432 "TARGET_64BIT
10433 && (optimize_function_for_size_p (cfun)
10434 || !TARGET_PARTIAL_FLAG_REG_STALL
10435 || (operands[2] == const1_rtx
10436 && TARGET_SHIFT1))
10437 && ix86_match_ccmode (insn, CCGOCmode)
10438 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10439 {
10440 if (operands[2] == const1_rtx
10441 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10442 return "<shift>{l}\t%k0";
10443 else
10444 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10445 }
10446 [(set_attr "type" "ishift")
10447 (set (attr "length_immediate")
10448 (if_then_else
10449 (and (match_operand 2 "const1_operand")
10450 (ior (match_test "TARGET_SHIFT1")
10451 (match_test "optimize_function_for_size_p (cfun)")))
10452 (const_string "0")
10453 (const_string "*")))
10454 (set_attr "mode" "SI")])
10455
10456 (define_insn "*<shift_insn><mode>3_cconly"
10457 [(set (reg FLAGS_REG)
10458 (compare
10459 (any_shiftrt:SWI
10460 (match_operand:SWI 1 "register_operand" "0")
10461 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10462 (const_int 0)))
10463 (clobber (match_scratch:SWI 0 "=<r>"))]
10464 "(optimize_function_for_size_p (cfun)
10465 || !TARGET_PARTIAL_FLAG_REG_STALL
10466 || (operands[2] == const1_rtx
10467 && TARGET_SHIFT1))
10468 && ix86_match_ccmode (insn, CCGOCmode)"
10469 {
10470 if (operands[2] == const1_rtx
10471 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10472 return "<shift>{<imodesuffix>}\t%0";
10473 else
10474 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10475 }
10476 [(set_attr "type" "ishift")
10477 (set (attr "length_immediate")
10478 (if_then_else
10479 (and (match_operand 2 "const1_operand")
10480 (ior (match_test "TARGET_SHIFT1")
10481 (match_test "optimize_function_for_size_p (cfun)")))
10482 (const_string "0")
10483 (const_string "*")))
10484 (set_attr "mode" "<MODE>")])
10485 \f
10486 ;; Rotate instructions
10487
10488 (define_expand "<rotate_insn>ti3"
10489 [(set (match_operand:TI 0 "register_operand")
10490 (any_rotate:TI (match_operand:TI 1 "register_operand")
10491 (match_operand:QI 2 "nonmemory_operand")))]
10492 "TARGET_64BIT"
10493 {
10494 if (const_1_to_63_operand (operands[2], VOIDmode))
10495 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10496 (operands[0], operands[1], operands[2]));
10497 else
10498 FAIL;
10499
10500 DONE;
10501 })
10502
10503 (define_expand "<rotate_insn>di3"
10504 [(set (match_operand:DI 0 "shiftdi_operand")
10505 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10506 (match_operand:QI 2 "nonmemory_operand")))]
10507 ""
10508 {
10509 if (TARGET_64BIT)
10510 ix86_expand_binary_operator (<CODE>, DImode, operands);
10511 else if (const_1_to_31_operand (operands[2], VOIDmode))
10512 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10513 (operands[0], operands[1], operands[2]));
10514 else
10515 FAIL;
10516
10517 DONE;
10518 })
10519
10520 (define_expand "<rotate_insn><mode>3"
10521 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10522 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10523 (match_operand:QI 2 "nonmemory_operand")))]
10524 ""
10525 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10526
10527 ;; Avoid useless masking of count operand.
10528 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10529 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10530 (any_rotate:SWI48
10531 (match_operand:SWI48 1 "nonimmediate_operand")
10532 (subreg:QI
10533 (and:SI
10534 (match_operand:SI 2 "register_operand")
10535 (match_operand:SI 3 "const_int_operand")) 0)))
10536 (clobber (reg:CC FLAGS_REG))]
10537 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10538 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10539 == GET_MODE_BITSIZE (<MODE>mode)-1
10540 && can_create_pseudo_p ()"
10541 "#"
10542 "&& 1"
10543 [(parallel
10544 [(set (match_dup 0)
10545 (any_rotate:SWI48 (match_dup 1)
10546 (match_dup 2)))
10547 (clobber (reg:CC FLAGS_REG))])]
10548 "operands[2] = gen_lowpart (QImode, operands[2]);")
10549
10550 ;; Implement rotation using two double-precision
10551 ;; shift instructions and a scratch register.
10552
10553 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10554 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10555 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10556 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10557 (clobber (reg:CC FLAGS_REG))
10558 (clobber (match_scratch:DWIH 3 "=&r"))]
10559 ""
10560 "#"
10561 "reload_completed"
10562 [(set (match_dup 3) (match_dup 4))
10563 (parallel
10564 [(set (match_dup 4)
10565 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10566 (lshiftrt:DWIH (match_dup 5)
10567 (minus:QI (match_dup 6) (match_dup 2)))))
10568 (clobber (reg:CC FLAGS_REG))])
10569 (parallel
10570 [(set (match_dup 5)
10571 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10572 (lshiftrt:DWIH (match_dup 3)
10573 (minus:QI (match_dup 6) (match_dup 2)))))
10574 (clobber (reg:CC FLAGS_REG))])]
10575 {
10576 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10577
10578 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10579 })
10580
10581 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10582 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10583 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10584 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10585 (clobber (reg:CC FLAGS_REG))
10586 (clobber (match_scratch:DWIH 3 "=&r"))]
10587 ""
10588 "#"
10589 "reload_completed"
10590 [(set (match_dup 3) (match_dup 4))
10591 (parallel
10592 [(set (match_dup 4)
10593 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10594 (ashift:DWIH (match_dup 5)
10595 (minus:QI (match_dup 6) (match_dup 2)))))
10596 (clobber (reg:CC FLAGS_REG))])
10597 (parallel
10598 [(set (match_dup 5)
10599 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10600 (ashift:DWIH (match_dup 3)
10601 (minus:QI (match_dup 6) (match_dup 2)))))
10602 (clobber (reg:CC FLAGS_REG))])]
10603 {
10604 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10605
10606 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10607 })
10608
10609 (define_insn "*bmi2_rorx<mode>3_1"
10610 [(set (match_operand:SWI48 0 "register_operand" "=r")
10611 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10612 (match_operand:QI 2 "immediate_operand" "<S>")))]
10613 "TARGET_BMI2"
10614 "rorx\t{%2, %1, %0|%0, %1, %2}"
10615 [(set_attr "type" "rotatex")
10616 (set_attr "mode" "<MODE>")])
10617
10618 (define_insn "*<rotate_insn><mode>3_1"
10619 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10620 (any_rotate:SWI48
10621 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10622 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10623 (clobber (reg:CC FLAGS_REG))]
10624 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10625 {
10626 switch (get_attr_type (insn))
10627 {
10628 case TYPE_ROTATEX:
10629 return "#";
10630
10631 default:
10632 if (operands[2] == const1_rtx
10633 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10634 return "<rotate>{<imodesuffix>}\t%0";
10635 else
10636 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10637 }
10638 }
10639 [(set_attr "isa" "*,bmi2")
10640 (set_attr "type" "rotate,rotatex")
10641 (set (attr "length_immediate")
10642 (if_then_else
10643 (and (eq_attr "type" "rotate")
10644 (and (match_operand 2 "const1_operand")
10645 (ior (match_test "TARGET_SHIFT1")
10646 (match_test "optimize_function_for_size_p (cfun)"))))
10647 (const_string "0")
10648 (const_string "*")))
10649 (set_attr "mode" "<MODE>")])
10650
10651 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10652 (define_split
10653 [(set (match_operand:SWI48 0 "register_operand")
10654 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10655 (match_operand:QI 2 "immediate_operand")))
10656 (clobber (reg:CC FLAGS_REG))]
10657 "TARGET_BMI2 && reload_completed"
10658 [(set (match_dup 0)
10659 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10660 {
10661 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
10662
10663 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10664 })
10665
10666 (define_split
10667 [(set (match_operand:SWI48 0 "register_operand")
10668 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10669 (match_operand:QI 2 "immediate_operand")))
10670 (clobber (reg:CC FLAGS_REG))]
10671 "TARGET_BMI2 && reload_completed"
10672 [(set (match_dup 0)
10673 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10674
10675 (define_insn "*bmi2_rorxsi3_1_zext"
10676 [(set (match_operand:DI 0 "register_operand" "=r")
10677 (zero_extend:DI
10678 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10679 (match_operand:QI 2 "immediate_operand" "I"))))]
10680 "TARGET_64BIT && TARGET_BMI2"
10681 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10682 [(set_attr "type" "rotatex")
10683 (set_attr "mode" "SI")])
10684
10685 (define_insn "*<rotate_insn>si3_1_zext"
10686 [(set (match_operand:DI 0 "register_operand" "=r,r")
10687 (zero_extend:DI
10688 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10689 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10690 (clobber (reg:CC FLAGS_REG))]
10691 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10692 {
10693 switch (get_attr_type (insn))
10694 {
10695 case TYPE_ROTATEX:
10696 return "#";
10697
10698 default:
10699 if (operands[2] == const1_rtx
10700 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10701 return "<rotate>{l}\t%k0";
10702 else
10703 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10704 }
10705 }
10706 [(set_attr "isa" "*,bmi2")
10707 (set_attr "type" "rotate,rotatex")
10708 (set (attr "length_immediate")
10709 (if_then_else
10710 (and (eq_attr "type" "rotate")
10711 (and (match_operand 2 "const1_operand")
10712 (ior (match_test "TARGET_SHIFT1")
10713 (match_test "optimize_function_for_size_p (cfun)"))))
10714 (const_string "0")
10715 (const_string "*")))
10716 (set_attr "mode" "SI")])
10717
10718 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10719 (define_split
10720 [(set (match_operand:DI 0 "register_operand")
10721 (zero_extend:DI
10722 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10723 (match_operand:QI 2 "immediate_operand"))))
10724 (clobber (reg:CC FLAGS_REG))]
10725 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10726 [(set (match_dup 0)
10727 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10728 {
10729 int bitsize = GET_MODE_BITSIZE (SImode);
10730
10731 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10732 })
10733
10734 (define_split
10735 [(set (match_operand:DI 0 "register_operand")
10736 (zero_extend:DI
10737 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10738 (match_operand:QI 2 "immediate_operand"))))
10739 (clobber (reg:CC FLAGS_REG))]
10740 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10741 [(set (match_dup 0)
10742 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10743
10744 (define_insn "*<rotate_insn><mode>3_1"
10745 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10746 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10747 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10748 (clobber (reg:CC FLAGS_REG))]
10749 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10750 {
10751 if (operands[2] == const1_rtx
10752 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10753 return "<rotate>{<imodesuffix>}\t%0";
10754 else
10755 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10756 }
10757 [(set_attr "type" "rotate")
10758 (set (attr "length_immediate")
10759 (if_then_else
10760 (and (match_operand 2 "const1_operand")
10761 (ior (match_test "TARGET_SHIFT1")
10762 (match_test "optimize_function_for_size_p (cfun)")))
10763 (const_string "0")
10764 (const_string "*")))
10765 (set_attr "mode" "<MODE>")])
10766
10767 (define_insn "*<rotate_insn>qi3_1_slp"
10768 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10769 (any_rotate:QI (match_dup 0)
10770 (match_operand:QI 1 "nonmemory_operand" "cI")))
10771 (clobber (reg:CC FLAGS_REG))]
10772 "(optimize_function_for_size_p (cfun)
10773 || !TARGET_PARTIAL_REG_STALL
10774 || (operands[1] == const1_rtx
10775 && TARGET_SHIFT1))"
10776 {
10777 if (operands[1] == const1_rtx
10778 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10779 return "<rotate>{b}\t%0";
10780 else
10781 return "<rotate>{b}\t{%1, %0|%0, %1}";
10782 }
10783 [(set_attr "type" "rotate1")
10784 (set (attr "length_immediate")
10785 (if_then_else
10786 (and (match_operand 1 "const1_operand")
10787 (ior (match_test "TARGET_SHIFT1")
10788 (match_test "optimize_function_for_size_p (cfun)")))
10789 (const_string "0")
10790 (const_string "*")))
10791 (set_attr "mode" "QI")])
10792
10793 (define_split
10794 [(set (match_operand:HI 0 "register_operand")
10795 (any_rotate:HI (match_dup 0) (const_int 8)))
10796 (clobber (reg:CC FLAGS_REG))]
10797 "reload_completed
10798 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10799 [(parallel [(set (strict_low_part (match_dup 0))
10800 (bswap:HI (match_dup 0)))
10801 (clobber (reg:CC FLAGS_REG))])])
10802 \f
10803 ;; Bit set / bit test instructions
10804
10805 ;; %%% bts, btr, btc, bt.
10806 ;; In general these instructions are *slow* when applied to memory,
10807 ;; since they enforce atomic operation. When applied to registers,
10808 ;; it depends on the cpu implementation. They're never faster than
10809 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10810 ;; no point. But in 64-bit, we can't hold the relevant immediates
10811 ;; within the instruction itself, so operating on bits in the high
10812 ;; 32-bits of a register becomes easier.
10813 ;;
10814 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10815 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10816 ;; negdf respectively, so they can never be disabled entirely.
10817
10818 (define_insn "*btsq"
10819 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10820 (const_int 1)
10821 (match_operand 1 "const_0_to_63_operand" "J"))
10822 (const_int 1))
10823 (clobber (reg:CC FLAGS_REG))]
10824 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10825 "bts{q}\t{%1, %0|%0, %1}"
10826 [(set_attr "type" "alu1")
10827 (set_attr "prefix_0f" "1")
10828 (set_attr "znver1_decode" "double")
10829 (set_attr "mode" "DI")])
10830
10831 (define_insn "*btrq"
10832 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10833 (const_int 1)
10834 (match_operand 1 "const_0_to_63_operand" "J"))
10835 (const_int 0))
10836 (clobber (reg:CC FLAGS_REG))]
10837 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10838 "btr{q}\t{%1, %0|%0, %1}"
10839 [(set_attr "type" "alu1")
10840 (set_attr "prefix_0f" "1")
10841 (set_attr "znver1_decode" "double")
10842 (set_attr "mode" "DI")])
10843
10844 (define_insn "*btcq"
10845 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10846 (const_int 1)
10847 (match_operand 1 "const_0_to_63_operand" "J"))
10848 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10849 (clobber (reg:CC FLAGS_REG))]
10850 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10851 "btc{q}\t{%1, %0|%0, %1}"
10852 [(set_attr "type" "alu1")
10853 (set_attr "prefix_0f" "1")
10854 (set_attr "znver1_decode" "double")
10855 (set_attr "mode" "DI")])
10856
10857 ;; Allow Nocona to avoid these instructions if a register is available.
10858
10859 (define_peephole2
10860 [(match_scratch:DI 2 "r")
10861 (parallel [(set (zero_extract:DI
10862 (match_operand:DI 0 "register_operand")
10863 (const_int 1)
10864 (match_operand 1 "const_0_to_63_operand"))
10865 (const_int 1))
10866 (clobber (reg:CC FLAGS_REG))])]
10867 "TARGET_64BIT && !TARGET_USE_BT"
10868 [(parallel [(set (match_dup 0)
10869 (ior:DI (match_dup 0) (match_dup 3)))
10870 (clobber (reg:CC FLAGS_REG))])]
10871 {
10872 int i = INTVAL (operands[1]);
10873
10874 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10875
10876 if (!x86_64_immediate_operand (operands[3], DImode))
10877 {
10878 emit_move_insn (operands[2], operands[3]);
10879 operands[3] = operands[2];
10880 }
10881 })
10882
10883 (define_peephole2
10884 [(match_scratch:DI 2 "r")
10885 (parallel [(set (zero_extract:DI
10886 (match_operand:DI 0 "register_operand")
10887 (const_int 1)
10888 (match_operand 1 "const_0_to_63_operand"))
10889 (const_int 0))
10890 (clobber (reg:CC FLAGS_REG))])]
10891 "TARGET_64BIT && !TARGET_USE_BT"
10892 [(parallel [(set (match_dup 0)
10893 (and:DI (match_dup 0) (match_dup 3)))
10894 (clobber (reg:CC FLAGS_REG))])]
10895 {
10896 int i = INTVAL (operands[1]);
10897
10898 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
10899
10900 if (!x86_64_immediate_operand (operands[3], DImode))
10901 {
10902 emit_move_insn (operands[2], operands[3]);
10903 operands[3] = operands[2];
10904 }
10905 })
10906
10907 (define_peephole2
10908 [(match_scratch:DI 2 "r")
10909 (parallel [(set (zero_extract:DI
10910 (match_operand:DI 0 "register_operand")
10911 (const_int 1)
10912 (match_operand 1 "const_0_to_63_operand"))
10913 (not:DI (zero_extract:DI
10914 (match_dup 0) (const_int 1) (match_dup 1))))
10915 (clobber (reg:CC FLAGS_REG))])]
10916 "TARGET_64BIT && !TARGET_USE_BT"
10917 [(parallel [(set (match_dup 0)
10918 (xor:DI (match_dup 0) (match_dup 3)))
10919 (clobber (reg:CC FLAGS_REG))])]
10920 {
10921 int i = INTVAL (operands[1]);
10922
10923 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10924
10925 if (!x86_64_immediate_operand (operands[3], DImode))
10926 {
10927 emit_move_insn (operands[2], operands[3]);
10928 operands[3] = operands[2];
10929 }
10930 })
10931
10932 (define_insn "*bt<mode>"
10933 [(set (reg:CCC FLAGS_REG)
10934 (compare:CCC
10935 (zero_extract:SWI48
10936 (match_operand:SWI48 0 "register_operand" "r")
10937 (const_int 1)
10938 (match_operand:SI 1 "nonmemory_operand" "rN"))
10939 (const_int 0)))]
10940 ""
10941 {
10942 switch (get_attr_mode (insn))
10943 {
10944 case MODE_SI:
10945 return "bt{l}\t{%1, %k0|%k0, %1}";
10946
10947 case MODE_DI:
10948 return "bt{q}\t{%q1, %0|%0, %q1}";
10949
10950 default:
10951 gcc_unreachable ();
10952 }
10953 }
10954 [(set_attr "type" "alu1")
10955 (set_attr "prefix_0f" "1")
10956 (set (attr "mode")
10957 (if_then_else
10958 (and (match_test "CONST_INT_P (operands[1])")
10959 (match_test "INTVAL (operands[1]) < 32"))
10960 (const_string "SI")
10961 (const_string "<MODE>")))])
10962
10963 (define_insn_and_split "*jcc_bt<mode>"
10964 [(set (pc)
10965 (if_then_else (match_operator 0 "bt_comparison_operator"
10966 [(zero_extract:SWI48
10967 (match_operand:SWI48 1 "register_operand")
10968 (const_int 1)
10969 (match_operand:SI 2 "nonmemory_operand"))
10970 (const_int 0)])
10971 (label_ref (match_operand 3))
10972 (pc)))
10973 (clobber (reg:CC FLAGS_REG))]
10974 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10975 && (CONST_INT_P (operands[2])
10976 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
10977 && INTVAL (operands[2])
10978 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
10979 : register_operand (operands[2], SImode))
10980 && can_create_pseudo_p ()"
10981 "#"
10982 "&& 1"
10983 [(set (reg:CCC FLAGS_REG)
10984 (compare:CCC
10985 (zero_extract:SWI48
10986 (match_dup 1)
10987 (const_int 1)
10988 (match_dup 2))
10989 (const_int 0)))
10990 (set (pc)
10991 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10992 (label_ref (match_dup 3))
10993 (pc)))]
10994 {
10995 operands[0] = shallow_copy_rtx (operands[0]);
10996 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10997 })
10998
10999 (define_insn_and_split "*jcc_bt<mode>_1"
11000 [(set (pc)
11001 (if_then_else (match_operator 0 "bt_comparison_operator"
11002 [(zero_extract:SWI48
11003 (match_operand:SWI48 1 "register_operand")
11004 (const_int 1)
11005 (zero_extend:SI
11006 (match_operand:QI 2 "register_operand")))
11007 (const_int 0)])
11008 (label_ref (match_operand 3))
11009 (pc)))
11010 (clobber (reg:CC FLAGS_REG))]
11011 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11012 && can_create_pseudo_p ()"
11013 "#"
11014 "&& 1"
11015 [(set (reg:CCC FLAGS_REG)
11016 (compare:CCC
11017 (zero_extract:SWI48
11018 (match_dup 1)
11019 (const_int 1)
11020 (match_dup 2))
11021 (const_int 0)))
11022 (set (pc)
11023 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11024 (label_ref (match_dup 3))
11025 (pc)))]
11026 {
11027 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11028 operands[0] = shallow_copy_rtx (operands[0]);
11029 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11030 })
11031
11032 ;; Avoid useless masking of bit offset operand.
11033 (define_insn_and_split "*jcc_bt<mode>_mask"
11034 [(set (pc)
11035 (if_then_else (match_operator 0 "bt_comparison_operator"
11036 [(zero_extract:SWI48
11037 (match_operand:SWI48 1 "register_operand")
11038 (const_int 1)
11039 (and:SI
11040 (match_operand:SI 2 "register_operand")
11041 (match_operand 3 "const_int_operand")))])
11042 (label_ref (match_operand 4))
11043 (pc)))
11044 (clobber (reg:CC FLAGS_REG))]
11045 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11046 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11047 == GET_MODE_BITSIZE (<MODE>mode)-1
11048 && can_create_pseudo_p ()"
11049 "#"
11050 "&& 1"
11051 [(set (reg:CCC FLAGS_REG)
11052 (compare:CCC
11053 (zero_extract:SWI48
11054 (match_dup 1)
11055 (const_int 1)
11056 (match_dup 2))
11057 (const_int 0)))
11058 (set (pc)
11059 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11060 (label_ref (match_dup 4))
11061 (pc)))]
11062 {
11063 operands[0] = shallow_copy_rtx (operands[0]);
11064 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11065 })
11066 \f
11067 ;; Store-flag instructions.
11068
11069 ;; For all sCOND expanders, also expand the compare or test insn that
11070 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11071
11072 (define_insn_and_split "*setcc_di_1"
11073 [(set (match_operand:DI 0 "register_operand" "=q")
11074 (match_operator:DI 1 "ix86_comparison_operator"
11075 [(reg FLAGS_REG) (const_int 0)]))]
11076 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11077 "#"
11078 "&& reload_completed"
11079 [(set (match_dup 2) (match_dup 1))
11080 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11081 {
11082 operands[1] = shallow_copy_rtx (operands[1]);
11083 PUT_MODE (operands[1], QImode);
11084 operands[2] = gen_lowpart (QImode, operands[0]);
11085 })
11086
11087 (define_insn_and_split "*setcc_si_1_and"
11088 [(set (match_operand:SI 0 "register_operand" "=q")
11089 (match_operator:SI 1 "ix86_comparison_operator"
11090 [(reg FLAGS_REG) (const_int 0)]))
11091 (clobber (reg:CC FLAGS_REG))]
11092 "!TARGET_PARTIAL_REG_STALL
11093 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11094 "#"
11095 "&& reload_completed"
11096 [(set (match_dup 2) (match_dup 1))
11097 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11098 (clobber (reg:CC FLAGS_REG))])]
11099 {
11100 operands[1] = shallow_copy_rtx (operands[1]);
11101 PUT_MODE (operands[1], QImode);
11102 operands[2] = gen_lowpart (QImode, operands[0]);
11103 })
11104
11105 (define_insn_and_split "*setcc_si_1_movzbl"
11106 [(set (match_operand:SI 0 "register_operand" "=q")
11107 (match_operator:SI 1 "ix86_comparison_operator"
11108 [(reg FLAGS_REG) (const_int 0)]))]
11109 "!TARGET_PARTIAL_REG_STALL
11110 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11111 "#"
11112 "&& reload_completed"
11113 [(set (match_dup 2) (match_dup 1))
11114 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11115 {
11116 operands[1] = shallow_copy_rtx (operands[1]);
11117 PUT_MODE (operands[1], QImode);
11118 operands[2] = gen_lowpart (QImode, operands[0]);
11119 })
11120
11121 (define_insn "*setcc_qi"
11122 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11123 (match_operator:QI 1 "ix86_comparison_operator"
11124 [(reg FLAGS_REG) (const_int 0)]))]
11125 ""
11126 "set%C1\t%0"
11127 [(set_attr "type" "setcc")
11128 (set_attr "mode" "QI")])
11129
11130 (define_insn "*setcc_qi_slp"
11131 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11132 (match_operator:QI 1 "ix86_comparison_operator"
11133 [(reg FLAGS_REG) (const_int 0)]))]
11134 ""
11135 "set%C1\t%0"
11136 [(set_attr "type" "setcc")
11137 (set_attr "mode" "QI")])
11138
11139 ;; In general it is not safe to assume too much about CCmode registers,
11140 ;; so simplify-rtx stops when it sees a second one. Under certain
11141 ;; conditions this is safe on x86, so help combine not create
11142 ;;
11143 ;; seta %al
11144 ;; testb %al, %al
11145 ;; sete %al
11146
11147 (define_split
11148 [(set (match_operand:QI 0 "nonimmediate_operand")
11149 (ne:QI (match_operator 1 "ix86_comparison_operator"
11150 [(reg FLAGS_REG) (const_int 0)])
11151 (const_int 0)))]
11152 ""
11153 [(set (match_dup 0) (match_dup 1))]
11154 {
11155 operands[1] = shallow_copy_rtx (operands[1]);
11156 PUT_MODE (operands[1], QImode);
11157 })
11158
11159 (define_split
11160 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11161 (ne:QI (match_operator 1 "ix86_comparison_operator"
11162 [(reg FLAGS_REG) (const_int 0)])
11163 (const_int 0)))]
11164 ""
11165 [(set (match_dup 0) (match_dup 1))]
11166 {
11167 operands[1] = shallow_copy_rtx (operands[1]);
11168 PUT_MODE (operands[1], QImode);
11169 })
11170
11171 (define_split
11172 [(set (match_operand:QI 0 "nonimmediate_operand")
11173 (eq:QI (match_operator 1 "ix86_comparison_operator"
11174 [(reg FLAGS_REG) (const_int 0)])
11175 (const_int 0)))]
11176 ""
11177 [(set (match_dup 0) (match_dup 1))]
11178 {
11179 operands[1] = shallow_copy_rtx (operands[1]);
11180 PUT_MODE (operands[1], QImode);
11181 PUT_CODE (operands[1],
11182 ix86_reverse_condition (GET_CODE (operands[1]),
11183 GET_MODE (XEXP (operands[1], 0))));
11184
11185 /* Make sure that (a) the CCmode we have for the flags is strong
11186 enough for the reversed compare or (b) we have a valid FP compare. */
11187 if (! ix86_comparison_operator (operands[1], VOIDmode))
11188 FAIL;
11189 })
11190
11191 (define_split
11192 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11193 (eq:QI (match_operator 1 "ix86_comparison_operator"
11194 [(reg FLAGS_REG) (const_int 0)])
11195 (const_int 0)))]
11196 ""
11197 [(set (match_dup 0) (match_dup 1))]
11198 {
11199 operands[1] = shallow_copy_rtx (operands[1]);
11200 PUT_MODE (operands[1], QImode);
11201 PUT_CODE (operands[1],
11202 ix86_reverse_condition (GET_CODE (operands[1]),
11203 GET_MODE (XEXP (operands[1], 0))));
11204
11205 /* Make sure that (a) the CCmode we have for the flags is strong
11206 enough for the reversed compare or (b) we have a valid FP compare. */
11207 if (! ix86_comparison_operator (operands[1], VOIDmode))
11208 FAIL;
11209 })
11210
11211 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11212 ;; subsequent logical operations are used to imitate conditional moves.
11213 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11214 ;; it directly.
11215
11216 (define_insn "setcc_<mode>_sse"
11217 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11218 (match_operator:MODEF 3 "sse_comparison_operator"
11219 [(match_operand:MODEF 1 "register_operand" "0,x")
11220 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11221 "SSE_FLOAT_MODE_P (<MODE>mode)"
11222 "@
11223 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11224 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11225 [(set_attr "isa" "noavx,avx")
11226 (set_attr "type" "ssecmp")
11227 (set_attr "length_immediate" "1")
11228 (set_attr "prefix" "orig,vex")
11229 (set_attr "mode" "<MODE>")])
11230 \f
11231 ;; Basic conditional jump instructions.
11232 ;; We ignore the overflow flag for signed branch instructions.
11233
11234 (define_insn "*jcc_1"
11235 [(set (pc)
11236 (if_then_else (match_operator 1 "ix86_comparison_operator"
11237 [(reg FLAGS_REG) (const_int 0)])
11238 (label_ref (match_operand 0))
11239 (pc)))]
11240 ""
11241 "%!%+j%C1\t%l0"
11242 [(set_attr "type" "ibr")
11243 (set_attr "modrm" "0")
11244 (set (attr "length")
11245 (if_then_else
11246 (and (ge (minus (match_dup 0) (pc))
11247 (const_int -126))
11248 (lt (minus (match_dup 0) (pc))
11249 (const_int 128)))
11250 (const_int 2)
11251 (const_int 6)))
11252 (set_attr "maybe_prefix_bnd" "1")])
11253
11254 (define_insn "*jcc_2"
11255 [(set (pc)
11256 (if_then_else (match_operator 1 "ix86_comparison_operator"
11257 [(reg FLAGS_REG) (const_int 0)])
11258 (pc)
11259 (label_ref (match_operand 0))))]
11260 ""
11261 "%!%+j%c1\t%l0"
11262 [(set_attr "type" "ibr")
11263 (set_attr "modrm" "0")
11264 (set (attr "length")
11265 (if_then_else
11266 (and (ge (minus (match_dup 0) (pc))
11267 (const_int -126))
11268 (lt (minus (match_dup 0) (pc))
11269 (const_int 128)))
11270 (const_int 2)
11271 (const_int 6)))
11272 (set_attr "maybe_prefix_bnd" "1")])
11273
11274 ;; In general it is not safe to assume too much about CCmode registers,
11275 ;; so simplify-rtx stops when it sees a second one. Under certain
11276 ;; conditions this is safe on x86, so help combine not create
11277 ;;
11278 ;; seta %al
11279 ;; testb %al, %al
11280 ;; je Lfoo
11281
11282 (define_split
11283 [(set (pc)
11284 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11285 [(reg FLAGS_REG) (const_int 0)])
11286 (const_int 0))
11287 (label_ref (match_operand 1))
11288 (pc)))]
11289 ""
11290 [(set (pc)
11291 (if_then_else (match_dup 0)
11292 (label_ref (match_dup 1))
11293 (pc)))]
11294 {
11295 operands[0] = shallow_copy_rtx (operands[0]);
11296 PUT_MODE (operands[0], VOIDmode);
11297 })
11298
11299 (define_split
11300 [(set (pc)
11301 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11302 [(reg FLAGS_REG) (const_int 0)])
11303 (const_int 0))
11304 (label_ref (match_operand 1))
11305 (pc)))]
11306 ""
11307 [(set (pc)
11308 (if_then_else (match_dup 0)
11309 (label_ref (match_dup 1))
11310 (pc)))]
11311 {
11312 operands[0] = shallow_copy_rtx (operands[0]);
11313 PUT_MODE (operands[0], VOIDmode);
11314 PUT_CODE (operands[0],
11315 ix86_reverse_condition (GET_CODE (operands[0]),
11316 GET_MODE (XEXP (operands[0], 0))));
11317
11318 /* Make sure that (a) the CCmode we have for the flags is strong
11319 enough for the reversed compare or (b) we have a valid FP compare. */
11320 if (! ix86_comparison_operator (operands[0], VOIDmode))
11321 FAIL;
11322 })
11323
11324 ;; Define combination compare-and-branch fp compare instructions to help
11325 ;; combine.
11326
11327 (define_insn "*jcc<mode>_0_i387"
11328 [(set (pc)
11329 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11330 [(match_operand:X87MODEF 1 "register_operand" "f")
11331 (match_operand:X87MODEF 2 "const0_operand")])
11332 (label_ref (match_operand 3))
11333 (pc)))
11334 (clobber (reg:CCFP FPSR_REG))
11335 (clobber (reg:CCFP FLAGS_REG))
11336 (clobber (match_scratch:HI 4 "=a"))]
11337 "TARGET_80387 && !TARGET_CMOVE"
11338 "#")
11339
11340 (define_insn "*jcc<mode>_0_r_i387"
11341 [(set (pc)
11342 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11343 [(match_operand:X87MODEF 1 "register_operand" "f")
11344 (match_operand:X87MODEF 2 "const0_operand")])
11345 (pc)
11346 (label_ref (match_operand 3))))
11347 (clobber (reg:CCFP FPSR_REG))
11348 (clobber (reg:CCFP FLAGS_REG))
11349 (clobber (match_scratch:HI 4 "=a"))]
11350 "TARGET_80387 && !TARGET_CMOVE"
11351 "#")
11352
11353 (define_insn "*jccxf_i387"
11354 [(set (pc)
11355 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11356 [(match_operand:XF 1 "register_operand" "f")
11357 (match_operand:XF 2 "register_operand" "f")])
11358 (label_ref (match_operand 3))
11359 (pc)))
11360 (clobber (reg:CCFP FPSR_REG))
11361 (clobber (reg:CCFP FLAGS_REG))
11362 (clobber (match_scratch:HI 4 "=a"))]
11363 "TARGET_80387 && !TARGET_CMOVE"
11364 "#")
11365
11366 (define_insn "*jccxf_r_i387"
11367 [(set (pc)
11368 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11369 [(match_operand:XF 1 "register_operand" "f")
11370 (match_operand:XF 2 "register_operand" "f")])
11371 (pc)
11372 (label_ref (match_operand 3))))
11373 (clobber (reg:CCFP FPSR_REG))
11374 (clobber (reg:CCFP FLAGS_REG))
11375 (clobber (match_scratch:HI 4 "=a"))]
11376 "TARGET_80387 && !TARGET_CMOVE"
11377 "#")
11378
11379 (define_insn "*jcc<mode>_i387"
11380 [(set (pc)
11381 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11382 [(match_operand:MODEF 1 "register_operand" "f")
11383 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11384 (label_ref (match_operand 3))
11385 (pc)))
11386 (clobber (reg:CCFP FPSR_REG))
11387 (clobber (reg:CCFP FLAGS_REG))
11388 (clobber (match_scratch:HI 4 "=a"))]
11389 "TARGET_80387 && !TARGET_CMOVE"
11390 "#")
11391
11392 (define_insn "*jcc<mode>_r_i387"
11393 [(set (pc)
11394 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11395 [(match_operand:MODEF 1 "register_operand" "f")
11396 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11397 (pc)
11398 (label_ref (match_operand 3))))
11399 (clobber (reg:CCFP FPSR_REG))
11400 (clobber (reg:CCFP FLAGS_REG))
11401 (clobber (match_scratch:HI 4 "=a"))]
11402 "TARGET_80387 && !TARGET_CMOVE"
11403 "#")
11404
11405 (define_insn "*jccu<mode>_i387"
11406 [(set (pc)
11407 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11408 [(match_operand:X87MODEF 1 "register_operand" "f")
11409 (match_operand:X87MODEF 2 "register_operand" "f")])
11410 (label_ref (match_operand 3))
11411 (pc)))
11412 (clobber (reg:CCFP FPSR_REG))
11413 (clobber (reg:CCFP FLAGS_REG))
11414 (clobber (match_scratch:HI 4 "=a"))]
11415 "TARGET_80387 && !TARGET_CMOVE"
11416 "#")
11417
11418 (define_insn "*jccu<mode>_r_i387"
11419 [(set (pc)
11420 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11421 [(match_operand:X87MODEF 1 "register_operand" "f")
11422 (match_operand:X87MODEF 2 "register_operand" "f")])
11423 (pc)
11424 (label_ref (match_operand 3))))
11425 (clobber (reg:CCFP FPSR_REG))
11426 (clobber (reg:CCFP FLAGS_REG))
11427 (clobber (match_scratch:HI 4 "=a"))]
11428 "TARGET_80387 && !TARGET_CMOVE"
11429 "#")
11430
11431 (define_split
11432 [(set (pc)
11433 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11434 [(match_operand:X87MODEF 1 "register_operand")
11435 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11436 (match_operand 3)
11437 (match_operand 4)))
11438 (clobber (reg:CCFP FPSR_REG))
11439 (clobber (reg:CCFP FLAGS_REG))]
11440 "TARGET_80387 && !TARGET_CMOVE
11441 && reload_completed"
11442 [(const_int 0)]
11443 {
11444 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11445 operands[3], operands[4], NULL_RTX);
11446 DONE;
11447 })
11448
11449 (define_split
11450 [(set (pc)
11451 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11452 [(match_operand:X87MODEF 1 "register_operand")
11453 (match_operand:X87MODEF 2 "general_operand")])
11454 (match_operand 3)
11455 (match_operand 4)))
11456 (clobber (reg:CCFP FPSR_REG))
11457 (clobber (reg:CCFP FLAGS_REG))
11458 (clobber (match_scratch:HI 5))]
11459 "TARGET_80387 && !TARGET_CMOVE
11460 && reload_completed"
11461 [(const_int 0)]
11462 {
11463 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11464 operands[3], operands[4], operands[5]);
11465 DONE;
11466 })
11467
11468 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11469 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11470 ;; with a precedence over other operators and is always put in the first
11471 ;; place. Swap condition and operands to match ficom instruction.
11472
11473 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11474 [(set (pc)
11475 (if_then_else
11476 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11477 [(match_operator:X87MODEF 1 "float_operator"
11478 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11479 (match_operand:X87MODEF 3 "register_operand" "f")])
11480 (label_ref (match_operand 4))
11481 (pc)))
11482 (clobber (reg:CCFP FPSR_REG))
11483 (clobber (reg:CCFP FLAGS_REG))
11484 (clobber (match_scratch:HI 5 "=a"))]
11485 "TARGET_80387 && !TARGET_CMOVE
11486 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11487 || optimize_function_for_size_p (cfun))"
11488 "#")
11489
11490 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11491 [(set (pc)
11492 (if_then_else
11493 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11494 [(match_operator:X87MODEF 1 "float_operator"
11495 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11496 (match_operand:X87MODEF 3 "register_operand" "f")])
11497 (pc)
11498 (label_ref (match_operand 4))))
11499 (clobber (reg:CCFP FPSR_REG))
11500 (clobber (reg:CCFP FLAGS_REG))
11501 (clobber (match_scratch:HI 5 "=a"))]
11502 "TARGET_80387 && !TARGET_CMOVE
11503 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11504 || optimize_function_for_size_p (cfun))"
11505 "#")
11506
11507 (define_split
11508 [(set (pc)
11509 (if_then_else
11510 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11511 [(match_operator:X87MODEF 1 "float_operator"
11512 [(match_operand:SWI24 2 "memory_operand")])
11513 (match_operand:X87MODEF 3 "register_operand")])
11514 (match_operand 4)
11515 (match_operand 5)))
11516 (clobber (reg:CCFP FPSR_REG))
11517 (clobber (reg:CCFP FLAGS_REG))
11518 (clobber (match_scratch:HI 6))]
11519 "TARGET_80387 && !TARGET_CMOVE
11520 && reload_completed"
11521 [(const_int 0)]
11522 {
11523 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11524 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11525 operands[4], operands[5], operands[6]);
11526 DONE;
11527 })
11528 \f
11529 ;; Unconditional and other jump instructions
11530
11531 (define_insn "jump"
11532 [(set (pc)
11533 (label_ref (match_operand 0)))]
11534 ""
11535 "%!jmp\t%l0"
11536 [(set_attr "type" "ibr")
11537 (set_attr "modrm" "0")
11538 (set (attr "length")
11539 (if_then_else
11540 (and (ge (minus (match_dup 0) (pc))
11541 (const_int -126))
11542 (lt (minus (match_dup 0) (pc))
11543 (const_int 128)))
11544 (const_int 2)
11545 (const_int 5)))
11546 (set_attr "maybe_prefix_bnd" "1")])
11547
11548 (define_expand "indirect_jump"
11549 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11550 ""
11551 {
11552 if (TARGET_X32)
11553 operands[0] = convert_memory_address (word_mode, operands[0]);
11554 })
11555
11556 (define_insn "*indirect_jump"
11557 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11558 ""
11559 "%!jmp\t%A0"
11560 [(set_attr "type" "ibr")
11561 (set_attr "length_immediate" "0")
11562 (set_attr "maybe_prefix_bnd" "1")])
11563
11564 (define_expand "tablejump"
11565 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11566 (use (label_ref (match_operand 1)))])]
11567 ""
11568 {
11569 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11570 relative. Convert the relative address to an absolute address. */
11571 if (flag_pic)
11572 {
11573 rtx op0, op1;
11574 enum rtx_code code;
11575
11576 /* We can't use @GOTOFF for text labels on VxWorks;
11577 see gotoff_operand. */
11578 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11579 {
11580 code = PLUS;
11581 op0 = operands[0];
11582 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11583 }
11584 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11585 {
11586 code = PLUS;
11587 op0 = operands[0];
11588 op1 = pic_offset_table_rtx;
11589 }
11590 else
11591 {
11592 code = MINUS;
11593 op0 = pic_offset_table_rtx;
11594 op1 = operands[0];
11595 }
11596
11597 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11598 OPTAB_DIRECT);
11599 }
11600
11601 if (TARGET_X32)
11602 operands[0] = convert_memory_address (word_mode, operands[0]);
11603 })
11604
11605 (define_insn "*tablejump_1"
11606 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11607 (use (label_ref (match_operand 1)))]
11608 ""
11609 "%!jmp\t%A0"
11610 [(set_attr "type" "ibr")
11611 (set_attr "length_immediate" "0")
11612 (set_attr "maybe_prefix_bnd" "1")])
11613 \f
11614 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11615
11616 (define_peephole2
11617 [(set (reg FLAGS_REG) (match_operand 0))
11618 (set (match_operand:QI 1 "register_operand")
11619 (match_operator:QI 2 "ix86_comparison_operator"
11620 [(reg FLAGS_REG) (const_int 0)]))
11621 (set (match_operand 3 "any_QIreg_operand")
11622 (zero_extend (match_dup 1)))]
11623 "(peep2_reg_dead_p (3, operands[1])
11624 || operands_match_p (operands[1], operands[3]))
11625 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11626 [(set (match_dup 4) (match_dup 0))
11627 (set (strict_low_part (match_dup 5))
11628 (match_dup 2))]
11629 {
11630 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11631 operands[5] = gen_lowpart (QImode, operands[3]);
11632 ix86_expand_clear (operands[3]);
11633 })
11634
11635 (define_peephole2
11636 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11637 (match_operand 4)])
11638 (set (match_operand:QI 1 "register_operand")
11639 (match_operator:QI 2 "ix86_comparison_operator"
11640 [(reg FLAGS_REG) (const_int 0)]))
11641 (set (match_operand 3 "any_QIreg_operand")
11642 (zero_extend (match_dup 1)))]
11643 "(peep2_reg_dead_p (3, operands[1])
11644 || operands_match_p (operands[1], operands[3]))
11645 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11646 && ! reg_set_p (operands[3], operands[4])"
11647 [(parallel [(set (match_dup 5) (match_dup 0))
11648 (match_dup 4)])
11649 (set (strict_low_part (match_dup 6))
11650 (match_dup 2))]
11651 {
11652 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11653 operands[6] = gen_lowpart (QImode, operands[3]);
11654 ix86_expand_clear (operands[3]);
11655 })
11656
11657 ;; Similar, but match zero extend with andsi3.
11658
11659 (define_peephole2
11660 [(set (reg FLAGS_REG) (match_operand 0))
11661 (set (match_operand:QI 1 "register_operand")
11662 (match_operator:QI 2 "ix86_comparison_operator"
11663 [(reg FLAGS_REG) (const_int 0)]))
11664 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11665 (and:SI (match_dup 3) (const_int 255)))
11666 (clobber (reg:CC FLAGS_REG))])]
11667 "REGNO (operands[1]) == REGNO (operands[3])
11668 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11669 [(set (match_dup 4) (match_dup 0))
11670 (set (strict_low_part (match_dup 5))
11671 (match_dup 2))]
11672 {
11673 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11674 operands[5] = gen_lowpart (QImode, operands[3]);
11675 ix86_expand_clear (operands[3]);
11676 })
11677
11678 (define_peephole2
11679 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11680 (match_operand 4)])
11681 (set (match_operand:QI 1 "register_operand")
11682 (match_operator:QI 2 "ix86_comparison_operator"
11683 [(reg FLAGS_REG) (const_int 0)]))
11684 (parallel [(set (match_operand 3 "any_QIreg_operand")
11685 (zero_extend (match_dup 1)))
11686 (clobber (reg:CC FLAGS_REG))])]
11687 "(peep2_reg_dead_p (3, operands[1])
11688 || operands_match_p (operands[1], operands[3]))
11689 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11690 && ! reg_set_p (operands[3], operands[4])"
11691 [(parallel [(set (match_dup 5) (match_dup 0))
11692 (match_dup 4)])
11693 (set (strict_low_part (match_dup 6))
11694 (match_dup 2))]
11695 {
11696 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11697 operands[6] = gen_lowpart (QImode, operands[3]);
11698 ix86_expand_clear (operands[3]);
11699 })
11700 \f
11701 ;; Call instructions.
11702
11703 ;; The predicates normally associated with named expanders are not properly
11704 ;; checked for calls. This is a bug in the generic code, but it isn't that
11705 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11706
11707 ;; P6 processors will jump to the address after the decrement when %esp
11708 ;; is used as a call operand, so they will execute return address as a code.
11709 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11710
11711 ;; Register constraint for call instruction.
11712 (define_mode_attr c [(SI "l") (DI "r")])
11713
11714 ;; Call subroutine returning no value.
11715
11716 (define_expand "call"
11717 [(call (match_operand:QI 0)
11718 (match_operand 1))
11719 (use (match_operand 2))]
11720 ""
11721 {
11722 ix86_expand_call (NULL, operands[0], operands[1],
11723 operands[2], NULL, false);
11724 DONE;
11725 })
11726
11727 (define_expand "sibcall"
11728 [(call (match_operand:QI 0)
11729 (match_operand 1))
11730 (use (match_operand 2))]
11731 ""
11732 {
11733 ix86_expand_call (NULL, operands[0], operands[1],
11734 operands[2], NULL, true);
11735 DONE;
11736 })
11737
11738 (define_insn "*call"
11739 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11740 (match_operand 1))]
11741 "!SIBLING_CALL_P (insn)"
11742 "* return ix86_output_call_insn (insn, operands[0]);"
11743 [(set_attr "type" "call")])
11744
11745 ;; This covers both call and sibcall since only GOT slot is allowed.
11746 (define_insn "*call_got_x32"
11747 [(call (mem:QI (zero_extend:DI
11748 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
11749 (match_operand 1))]
11750 "TARGET_X32"
11751 {
11752 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
11753 return ix86_output_call_insn (insn, fnaddr);
11754 }
11755 [(set_attr "type" "call")])
11756
11757 ;; Since sibcall never returns, we can only use call-clobbered register
11758 ;; as GOT base.
11759 (define_insn "*sibcall_GOT_32"
11760 [(call (mem:QI
11761 (mem:SI (plus:SI
11762 (match_operand:SI 0 "register_no_elim_operand" "U")
11763 (match_operand:SI 1 "GOT32_symbol_operand"))))
11764 (match_operand 2))]
11765 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11766 {
11767 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
11768 fnaddr = gen_const_mem (SImode, fnaddr);
11769 return ix86_output_call_insn (insn, fnaddr);
11770 }
11771 [(set_attr "type" "call")])
11772
11773 (define_insn "*sibcall"
11774 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11775 (match_operand 1))]
11776 "SIBLING_CALL_P (insn)"
11777 "* return ix86_output_call_insn (insn, operands[0]);"
11778 [(set_attr "type" "call")])
11779
11780 (define_insn "*sibcall_memory"
11781 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11782 (match_operand 1))
11783 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11784 "!TARGET_X32"
11785 "* return ix86_output_call_insn (insn, operands[0]);"
11786 [(set_attr "type" "call")])
11787
11788 (define_peephole2
11789 [(set (match_operand:W 0 "register_operand")
11790 (match_operand:W 1 "memory_operand"))
11791 (call (mem:QI (match_dup 0))
11792 (match_operand 3))]
11793 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11794 && !reg_mentioned_p (operands[0],
11795 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11796 [(parallel [(call (mem:QI (match_dup 1))
11797 (match_dup 3))
11798 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11799
11800 (define_peephole2
11801 [(set (match_operand:W 0 "register_operand")
11802 (match_operand:W 1 "memory_operand"))
11803 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11804 (call (mem:QI (match_dup 0))
11805 (match_operand 3))]
11806 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11807 && !reg_mentioned_p (operands[0],
11808 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11809 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11810 (parallel [(call (mem:QI (match_dup 1))
11811 (match_dup 3))
11812 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11813
11814 (define_expand "call_pop"
11815 [(parallel [(call (match_operand:QI 0)
11816 (match_operand:SI 1))
11817 (set (reg:SI SP_REG)
11818 (plus:SI (reg:SI SP_REG)
11819 (match_operand:SI 3)))])]
11820 "!TARGET_64BIT"
11821 {
11822 ix86_expand_call (NULL, operands[0], operands[1],
11823 operands[2], operands[3], false);
11824 DONE;
11825 })
11826
11827 (define_insn "*call_pop"
11828 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11829 (match_operand 1))
11830 (set (reg:SI SP_REG)
11831 (plus:SI (reg:SI SP_REG)
11832 (match_operand:SI 2 "immediate_operand" "i")))]
11833 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11834 "* return ix86_output_call_insn (insn, operands[0]);"
11835 [(set_attr "type" "call")])
11836
11837 (define_insn "*sibcall_pop"
11838 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11839 (match_operand 1))
11840 (set (reg:SI SP_REG)
11841 (plus:SI (reg:SI SP_REG)
11842 (match_operand:SI 2 "immediate_operand" "i")))]
11843 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11844 "* return ix86_output_call_insn (insn, operands[0]);"
11845 [(set_attr "type" "call")])
11846
11847 (define_insn "*sibcall_pop_memory"
11848 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11849 (match_operand 1))
11850 (set (reg:SI SP_REG)
11851 (plus:SI (reg:SI SP_REG)
11852 (match_operand:SI 2 "immediate_operand" "i")))
11853 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11854 "!TARGET_64BIT"
11855 "* return ix86_output_call_insn (insn, operands[0]);"
11856 [(set_attr "type" "call")])
11857
11858 (define_peephole2
11859 [(set (match_operand:SI 0 "register_operand")
11860 (match_operand:SI 1 "memory_operand"))
11861 (parallel [(call (mem:QI (match_dup 0))
11862 (match_operand 3))
11863 (set (reg:SI SP_REG)
11864 (plus:SI (reg:SI SP_REG)
11865 (match_operand:SI 4 "immediate_operand")))])]
11866 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11867 && !reg_mentioned_p (operands[0],
11868 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11869 [(parallel [(call (mem:QI (match_dup 1))
11870 (match_dup 3))
11871 (set (reg:SI SP_REG)
11872 (plus:SI (reg:SI SP_REG)
11873 (match_dup 4)))
11874 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11875
11876 (define_peephole2
11877 [(set (match_operand:SI 0 "register_operand")
11878 (match_operand:SI 1 "memory_operand"))
11879 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11880 (parallel [(call (mem:QI (match_dup 0))
11881 (match_operand 3))
11882 (set (reg:SI SP_REG)
11883 (plus:SI (reg:SI SP_REG)
11884 (match_operand:SI 4 "immediate_operand")))])]
11885 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11886 && !reg_mentioned_p (operands[0],
11887 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11888 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11889 (parallel [(call (mem:QI (match_dup 1))
11890 (match_dup 3))
11891 (set (reg:SI SP_REG)
11892 (plus:SI (reg:SI SP_REG)
11893 (match_dup 4)))
11894 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11895
11896 ;; Combining simple memory jump instruction
11897
11898 (define_peephole2
11899 [(set (match_operand:W 0 "register_operand")
11900 (match_operand:W 1 "memory_operand"))
11901 (set (pc) (match_dup 0))]
11902 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11903 [(set (pc) (match_dup 1))])
11904
11905 ;; Call subroutine, returning value in operand 0
11906
11907 (define_expand "call_value"
11908 [(set (match_operand 0)
11909 (call (match_operand:QI 1)
11910 (match_operand 2)))
11911 (use (match_operand 3))]
11912 ""
11913 {
11914 ix86_expand_call (operands[0], operands[1], operands[2],
11915 operands[3], NULL, false);
11916 DONE;
11917 })
11918
11919 (define_expand "sibcall_value"
11920 [(set (match_operand 0)
11921 (call (match_operand:QI 1)
11922 (match_operand 2)))
11923 (use (match_operand 3))]
11924 ""
11925 {
11926 ix86_expand_call (operands[0], operands[1], operands[2],
11927 operands[3], NULL, true);
11928 DONE;
11929 })
11930
11931 (define_insn "*call_value"
11932 [(set (match_operand 0)
11933 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11934 (match_operand 2)))]
11935 "!SIBLING_CALL_P (insn)"
11936 "* return ix86_output_call_insn (insn, operands[1]);"
11937 [(set_attr "type" "callv")])
11938
11939 ;; This covers both call and sibcall since only GOT slot is allowed.
11940 (define_insn "*call_value_got_x32"
11941 [(set (match_operand 0)
11942 (call (mem:QI
11943 (zero_extend:DI
11944 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
11945 (match_operand 2)))]
11946 "TARGET_X32"
11947 {
11948 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
11949 return ix86_output_call_insn (insn, fnaddr);
11950 }
11951 [(set_attr "type" "callv")])
11952
11953 ;; Since sibcall never returns, we can only use call-clobbered register
11954 ;; as GOT base.
11955 (define_insn "*sibcall_value_GOT_32"
11956 [(set (match_operand 0)
11957 (call (mem:QI
11958 (mem:SI (plus:SI
11959 (match_operand:SI 1 "register_no_elim_operand" "U")
11960 (match_operand:SI 2 "GOT32_symbol_operand"))))
11961 (match_operand 3)))]
11962 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11963 {
11964 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
11965 fnaddr = gen_const_mem (SImode, fnaddr);
11966 return ix86_output_call_insn (insn, fnaddr);
11967 }
11968 [(set_attr "type" "callv")])
11969
11970 (define_insn "*sibcall_value"
11971 [(set (match_operand 0)
11972 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11973 (match_operand 2)))]
11974 "SIBLING_CALL_P (insn)"
11975 "* return ix86_output_call_insn (insn, operands[1]);"
11976 [(set_attr "type" "callv")])
11977
11978 (define_insn "*sibcall_value_memory"
11979 [(set (match_operand 0)
11980 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11981 (match_operand 2)))
11982 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11983 "!TARGET_X32"
11984 "* return ix86_output_call_insn (insn, operands[1]);"
11985 [(set_attr "type" "callv")])
11986
11987 (define_peephole2
11988 [(set (match_operand:W 0 "register_operand")
11989 (match_operand:W 1 "memory_operand"))
11990 (set (match_operand 2)
11991 (call (mem:QI (match_dup 0))
11992 (match_operand 3)))]
11993 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11994 && !reg_mentioned_p (operands[0],
11995 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11996 [(parallel [(set (match_dup 2)
11997 (call (mem:QI (match_dup 1))
11998 (match_dup 3)))
11999 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12000
12001 (define_peephole2
12002 [(set (match_operand:W 0 "register_operand")
12003 (match_operand:W 1 "memory_operand"))
12004 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12005 (set (match_operand 2)
12006 (call (mem:QI (match_dup 0))
12007 (match_operand 3)))]
12008 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12009 && !reg_mentioned_p (operands[0],
12010 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12011 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12012 (parallel [(set (match_dup 2)
12013 (call (mem:QI (match_dup 1))
12014 (match_dup 3)))
12015 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12016
12017 (define_expand "call_value_pop"
12018 [(parallel [(set (match_operand 0)
12019 (call (match_operand:QI 1)
12020 (match_operand:SI 2)))
12021 (set (reg:SI SP_REG)
12022 (plus:SI (reg:SI SP_REG)
12023 (match_operand:SI 4)))])]
12024 "!TARGET_64BIT"
12025 {
12026 ix86_expand_call (operands[0], operands[1], operands[2],
12027 operands[3], operands[4], false);
12028 DONE;
12029 })
12030
12031 (define_insn "*call_value_pop"
12032 [(set (match_operand 0)
12033 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12034 (match_operand 2)))
12035 (set (reg:SI SP_REG)
12036 (plus:SI (reg:SI SP_REG)
12037 (match_operand:SI 3 "immediate_operand" "i")))]
12038 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12039 "* return ix86_output_call_insn (insn, operands[1]);"
12040 [(set_attr "type" "callv")])
12041
12042 (define_insn "*sibcall_value_pop"
12043 [(set (match_operand 0)
12044 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12045 (match_operand 2)))
12046 (set (reg:SI SP_REG)
12047 (plus:SI (reg:SI SP_REG)
12048 (match_operand:SI 3 "immediate_operand" "i")))]
12049 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12050 "* return ix86_output_call_insn (insn, operands[1]);"
12051 [(set_attr "type" "callv")])
12052
12053 (define_insn "*sibcall_value_pop_memory"
12054 [(set (match_operand 0)
12055 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12056 (match_operand 2)))
12057 (set (reg:SI SP_REG)
12058 (plus:SI (reg:SI SP_REG)
12059 (match_operand:SI 3 "immediate_operand" "i")))
12060 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12061 "!TARGET_64BIT"
12062 "* return ix86_output_call_insn (insn, operands[1]);"
12063 [(set_attr "type" "callv")])
12064
12065 (define_peephole2
12066 [(set (match_operand:SI 0 "register_operand")
12067 (match_operand:SI 1 "memory_operand"))
12068 (parallel [(set (match_operand 2)
12069 (call (mem:QI (match_dup 0))
12070 (match_operand 3)))
12071 (set (reg:SI SP_REG)
12072 (plus:SI (reg:SI SP_REG)
12073 (match_operand:SI 4 "immediate_operand")))])]
12074 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12075 && !reg_mentioned_p (operands[0],
12076 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12077 [(parallel [(set (match_dup 2)
12078 (call (mem:QI (match_dup 1))
12079 (match_dup 3)))
12080 (set (reg:SI SP_REG)
12081 (plus:SI (reg:SI SP_REG)
12082 (match_dup 4)))
12083 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12084
12085 (define_peephole2
12086 [(set (match_operand:SI 0 "register_operand")
12087 (match_operand:SI 1 "memory_operand"))
12088 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12089 (parallel [(set (match_operand 2)
12090 (call (mem:QI (match_dup 0))
12091 (match_operand 3)))
12092 (set (reg:SI SP_REG)
12093 (plus:SI (reg:SI SP_REG)
12094 (match_operand:SI 4 "immediate_operand")))])]
12095 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12096 && !reg_mentioned_p (operands[0],
12097 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12098 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12099 (parallel [(set (match_dup 2)
12100 (call (mem:QI (match_dup 1))
12101 (match_dup 3)))
12102 (set (reg:SI SP_REG)
12103 (plus:SI (reg:SI SP_REG)
12104 (match_dup 4)))
12105 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12106
12107 ;; Call subroutine returning any type.
12108
12109 (define_expand "untyped_call"
12110 [(parallel [(call (match_operand 0)
12111 (const_int 0))
12112 (match_operand 1)
12113 (match_operand 2)])]
12114 ""
12115 {
12116 int i;
12117
12118 /* In order to give reg-stack an easier job in validating two
12119 coprocessor registers as containing a possible return value,
12120 simply pretend the untyped call returns a complex long double
12121 value.
12122
12123 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12124 and should have the default ABI. */
12125
12126 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12127 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12128 operands[0], const0_rtx,
12129 GEN_INT ((TARGET_64BIT
12130 ? (ix86_abi == SYSV_ABI
12131 ? X86_64_SSE_REGPARM_MAX
12132 : X86_64_MS_SSE_REGPARM_MAX)
12133 : X86_32_SSE_REGPARM_MAX)
12134 - 1),
12135 NULL, false);
12136
12137 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12138 {
12139 rtx set = XVECEXP (operands[2], 0, i);
12140 emit_move_insn (SET_DEST (set), SET_SRC (set));
12141 }
12142
12143 /* The optimizer does not know that the call sets the function value
12144 registers we stored in the result block. We avoid problems by
12145 claiming that all hard registers are used and clobbered at this
12146 point. */
12147 emit_insn (gen_blockage ());
12148
12149 DONE;
12150 })
12151 \f
12152 ;; Prologue and epilogue instructions
12153
12154 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12155 ;; all of memory. This blocks insns from being moved across this point.
12156
12157 (define_insn "blockage"
12158 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12159 ""
12160 ""
12161 [(set_attr "length" "0")])
12162
12163 ;; Do not schedule instructions accessing memory across this point.
12164
12165 (define_expand "memory_blockage"
12166 [(set (match_dup 0)
12167 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12168 ""
12169 {
12170 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12171 MEM_VOLATILE_P (operands[0]) = 1;
12172 })
12173
12174 (define_insn "*memory_blockage"
12175 [(set (match_operand:BLK 0)
12176 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12177 ""
12178 ""
12179 [(set_attr "length" "0")])
12180
12181 ;; As USE insns aren't meaningful after reload, this is used instead
12182 ;; to prevent deleting instructions setting registers for PIC code
12183 (define_insn "prologue_use"
12184 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12185 ""
12186 ""
12187 [(set_attr "length" "0")])
12188
12189 ;; Insn emitted into the body of a function to return from a function.
12190 ;; This is only done if the function's epilogue is known to be simple.
12191 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12192
12193 (define_expand "return"
12194 [(simple_return)]
12195 "ix86_can_use_return_insn_p ()"
12196 {
12197 if (crtl->args.pops_args)
12198 {
12199 rtx popc = GEN_INT (crtl->args.pops_args);
12200 emit_jump_insn (gen_simple_return_pop_internal (popc));
12201 DONE;
12202 }
12203 })
12204
12205 ;; We need to disable this for TARGET_SEH, as otherwise
12206 ;; shrink-wrapped prologue gets enabled too. This might exceed
12207 ;; the maximum size of prologue in unwind information.
12208 ;; Also disallow shrink-wrapping if using stack slot to pass the
12209 ;; static chain pointer - the first instruction has to be pushl %esi
12210 ;; and it can't be moved around, as we use alternate entry points
12211 ;; in that case.
12212
12213 (define_expand "simple_return"
12214 [(simple_return)]
12215 "!TARGET_SEH && !ix86_static_chain_on_stack"
12216 {
12217 if (crtl->args.pops_args)
12218 {
12219 rtx popc = GEN_INT (crtl->args.pops_args);
12220 emit_jump_insn (gen_simple_return_pop_internal (popc));
12221 DONE;
12222 }
12223 })
12224
12225 (define_insn "simple_return_internal"
12226 [(simple_return)]
12227 "reload_completed"
12228 "%!ret"
12229 [(set_attr "length" "1")
12230 (set_attr "atom_unit" "jeu")
12231 (set_attr "length_immediate" "0")
12232 (set_attr "modrm" "0")
12233 (set_attr "maybe_prefix_bnd" "1")])
12234
12235 (define_insn "interrupt_return"
12236 [(simple_return)
12237 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12238 "reload_completed"
12239 {
12240 return TARGET_64BIT ? "iretq" : "iret";
12241 })
12242
12243 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12244 ;; instruction Athlon and K8 have.
12245
12246 (define_insn "simple_return_internal_long"
12247 [(simple_return)
12248 (unspec [(const_int 0)] UNSPEC_REP)]
12249 "reload_completed"
12250 {
12251 if (ix86_bnd_prefixed_insn_p (insn))
12252 return "%!ret";
12253
12254 return "rep%; ret";
12255 }
12256 [(set_attr "length" "2")
12257 (set_attr "atom_unit" "jeu")
12258 (set_attr "length_immediate" "0")
12259 (set_attr "prefix_rep" "1")
12260 (set_attr "modrm" "0")])
12261
12262 (define_insn "simple_return_pop_internal"
12263 [(simple_return)
12264 (use (match_operand:SI 0 "const_int_operand"))]
12265 "reload_completed"
12266 "%!ret\t%0"
12267 [(set_attr "length" "3")
12268 (set_attr "atom_unit" "jeu")
12269 (set_attr "length_immediate" "2")
12270 (set_attr "modrm" "0")
12271 (set_attr "maybe_prefix_bnd" "1")])
12272
12273 (define_insn "simple_return_indirect_internal"
12274 [(simple_return)
12275 (use (match_operand:SI 0 "register_operand" "r"))]
12276 "reload_completed"
12277 "%!jmp\t%A0"
12278 [(set_attr "type" "ibr")
12279 (set_attr "length_immediate" "0")
12280 (set_attr "maybe_prefix_bnd" "1")])
12281
12282 (define_insn "nop"
12283 [(const_int 0)]
12284 ""
12285 "nop"
12286 [(set_attr "length" "1")
12287 (set_attr "length_immediate" "0")
12288 (set_attr "modrm" "0")])
12289
12290 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12291 (define_insn "nops"
12292 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12293 UNSPECV_NOPS)]
12294 "reload_completed"
12295 {
12296 int num = INTVAL (operands[0]);
12297
12298 gcc_assert (IN_RANGE (num, 1, 8));
12299
12300 while (num--)
12301 fputs ("\tnop\n", asm_out_file);
12302
12303 return "";
12304 }
12305 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12306 (set_attr "length_immediate" "0")
12307 (set_attr "modrm" "0")])
12308
12309 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12310 ;; branch prediction penalty for the third jump in a 16-byte
12311 ;; block on K8.
12312
12313 (define_insn "pad"
12314 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12315 ""
12316 {
12317 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12318 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12319 #else
12320 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12321 The align insn is used to avoid 3 jump instructions in the row to improve
12322 branch prediction and the benefits hardly outweigh the cost of extra 8
12323 nops on the average inserted by full alignment pseudo operation. */
12324 #endif
12325 return "";
12326 }
12327 [(set_attr "length" "16")])
12328
12329 (define_expand "prologue"
12330 [(const_int 0)]
12331 ""
12332 "ix86_expand_prologue (); DONE;")
12333
12334 (define_expand "set_got"
12335 [(parallel
12336 [(set (match_operand:SI 0 "register_operand")
12337 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12338 (clobber (reg:CC FLAGS_REG))])]
12339 "!TARGET_64BIT"
12340 {
12341 if (flag_pic && !TARGET_VXWORKS_RTP)
12342 ix86_pc_thunk_call_expanded = true;
12343 })
12344
12345 (define_insn "*set_got"
12346 [(set (match_operand:SI 0 "register_operand" "=r")
12347 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12348 (clobber (reg:CC FLAGS_REG))]
12349 "!TARGET_64BIT"
12350 "* return output_set_got (operands[0], NULL_RTX);"
12351 [(set_attr "type" "multi")
12352 (set_attr "length" "12")])
12353
12354 (define_expand "set_got_labelled"
12355 [(parallel
12356 [(set (match_operand:SI 0 "register_operand")
12357 (unspec:SI [(label_ref (match_operand 1))]
12358 UNSPEC_SET_GOT))
12359 (clobber (reg:CC FLAGS_REG))])]
12360 "!TARGET_64BIT"
12361 {
12362 if (flag_pic && !TARGET_VXWORKS_RTP)
12363 ix86_pc_thunk_call_expanded = true;
12364 })
12365
12366 (define_insn "*set_got_labelled"
12367 [(set (match_operand:SI 0 "register_operand" "=r")
12368 (unspec:SI [(label_ref (match_operand 1))]
12369 UNSPEC_SET_GOT))
12370 (clobber (reg:CC FLAGS_REG))]
12371 "!TARGET_64BIT"
12372 "* return output_set_got (operands[0], operands[1]);"
12373 [(set_attr "type" "multi")
12374 (set_attr "length" "12")])
12375
12376 (define_insn "set_got_rex64"
12377 [(set (match_operand:DI 0 "register_operand" "=r")
12378 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12379 "TARGET_64BIT"
12380 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12381 [(set_attr "type" "lea")
12382 (set_attr "length_address" "4")
12383 (set_attr "modrm_class" "unknown")
12384 (set_attr "mode" "DI")])
12385
12386 (define_insn "set_rip_rex64"
12387 [(set (match_operand:DI 0 "register_operand" "=r")
12388 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12389 "TARGET_64BIT"
12390 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12391 [(set_attr "type" "lea")
12392 (set_attr "length_address" "4")
12393 (set_attr "mode" "DI")])
12394
12395 (define_insn "set_got_offset_rex64"
12396 [(set (match_operand:DI 0 "register_operand" "=r")
12397 (unspec:DI
12398 [(label_ref (match_operand 1))]
12399 UNSPEC_SET_GOT_OFFSET))]
12400 "TARGET_LP64"
12401 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12402 [(set_attr "type" "imov")
12403 (set_attr "length_immediate" "0")
12404 (set_attr "length_address" "8")
12405 (set_attr "mode" "DI")])
12406
12407 (define_expand "epilogue"
12408 [(const_int 0)]
12409 ""
12410 "ix86_expand_epilogue (1); DONE;")
12411
12412 (define_expand "sibcall_epilogue"
12413 [(const_int 0)]
12414 ""
12415 "ix86_expand_epilogue (0); DONE;")
12416
12417 (define_expand "eh_return"
12418 [(use (match_operand 0 "register_operand"))]
12419 ""
12420 {
12421 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12422
12423 /* Tricky bit: we write the address of the handler to which we will
12424 be returning into someone else's stack frame, one word below the
12425 stack address we wish to restore. */
12426 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12427 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12428 tmp = gen_rtx_MEM (Pmode, tmp);
12429 emit_move_insn (tmp, ra);
12430
12431 emit_jump_insn (gen_eh_return_internal ());
12432 emit_barrier ();
12433 DONE;
12434 })
12435
12436 (define_insn_and_split "eh_return_internal"
12437 [(eh_return)]
12438 ""
12439 "#"
12440 "epilogue_completed"
12441 [(const_int 0)]
12442 "ix86_expand_epilogue (2); DONE;")
12443
12444 (define_insn "leave"
12445 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12446 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12447 (clobber (mem:BLK (scratch)))]
12448 "!TARGET_64BIT"
12449 "leave"
12450 [(set_attr "type" "leave")])
12451
12452 (define_insn "leave_rex64"
12453 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12454 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12455 (clobber (mem:BLK (scratch)))]
12456 "TARGET_64BIT"
12457 "leave"
12458 [(set_attr "type" "leave")])
12459 \f
12460 ;; Handle -fsplit-stack.
12461
12462 (define_expand "split_stack_prologue"
12463 [(const_int 0)]
12464 ""
12465 {
12466 ix86_expand_split_stack_prologue ();
12467 DONE;
12468 })
12469
12470 ;; In order to support the call/return predictor, we use a return
12471 ;; instruction which the middle-end doesn't see.
12472 (define_insn "split_stack_return"
12473 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12474 UNSPECV_SPLIT_STACK_RETURN)]
12475 ""
12476 {
12477 if (operands[0] == const0_rtx)
12478 return "ret";
12479 else
12480 return "ret\t%0";
12481 }
12482 [(set_attr "atom_unit" "jeu")
12483 (set_attr "modrm" "0")
12484 (set (attr "length")
12485 (if_then_else (match_operand:SI 0 "const0_operand")
12486 (const_int 1)
12487 (const_int 3)))
12488 (set (attr "length_immediate")
12489 (if_then_else (match_operand:SI 0 "const0_operand")
12490 (const_int 0)
12491 (const_int 2)))])
12492
12493 ;; If there are operand 0 bytes available on the stack, jump to
12494 ;; operand 1.
12495
12496 (define_expand "split_stack_space_check"
12497 [(set (pc) (if_then_else
12498 (ltu (minus (reg SP_REG)
12499 (match_operand 0 "register_operand"))
12500 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12501 (label_ref (match_operand 1))
12502 (pc)))]
12503 ""
12504 {
12505 rtx reg, size, limit;
12506
12507 reg = gen_reg_rtx (Pmode);
12508 size = force_reg (Pmode, operands[0]);
12509 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12510 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12511 UNSPEC_STACK_CHECK);
12512 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12513 ix86_expand_branch (GEU, reg, limit, operands[1]);
12514
12515 DONE;
12516 })
12517 \f
12518 ;; Bit manipulation instructions.
12519
12520 (define_expand "ffs<mode>2"
12521 [(set (match_dup 2) (const_int -1))
12522 (parallel [(set (match_dup 3) (match_dup 4))
12523 (set (match_operand:SWI48 0 "register_operand")
12524 (ctz:SWI48
12525 (match_operand:SWI48 1 "nonimmediate_operand")))])
12526 (set (match_dup 0) (if_then_else:SWI48
12527 (eq (match_dup 3) (const_int 0))
12528 (match_dup 2)
12529 (match_dup 0)))
12530 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12531 (clobber (reg:CC FLAGS_REG))])]
12532 ""
12533 {
12534 machine_mode flags_mode;
12535
12536 if (<MODE>mode == SImode && !TARGET_CMOVE)
12537 {
12538 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12539 DONE;
12540 }
12541
12542 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12543
12544 operands[2] = gen_reg_rtx (<MODE>mode);
12545 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12546 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12547 })
12548
12549 (define_insn_and_split "ffssi2_no_cmove"
12550 [(set (match_operand:SI 0 "register_operand" "=r")
12551 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12552 (clobber (match_scratch:SI 2 "=&q"))
12553 (clobber (reg:CC FLAGS_REG))]
12554 "!TARGET_CMOVE"
12555 "#"
12556 "&& reload_completed"
12557 [(parallel [(set (match_dup 4) (match_dup 5))
12558 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12559 (set (strict_low_part (match_dup 3))
12560 (eq:QI (match_dup 4) (const_int 0)))
12561 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12562 (clobber (reg:CC FLAGS_REG))])
12563 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12564 (clobber (reg:CC FLAGS_REG))])
12565 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12566 (clobber (reg:CC FLAGS_REG))])]
12567 {
12568 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12569
12570 operands[3] = gen_lowpart (QImode, operands[2]);
12571 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12572 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12573
12574 ix86_expand_clear (operands[2]);
12575 })
12576
12577 (define_insn_and_split "*tzcnt<mode>_1"
12578 [(set (reg:CCC FLAGS_REG)
12579 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12580 (const_int 0)))
12581 (set (match_operand:SWI48 0 "register_operand" "=r")
12582 (ctz:SWI48 (match_dup 1)))]
12583 "TARGET_BMI"
12584 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12585 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
12586 && optimize_function_for_speed_p (cfun)
12587 && !reg_mentioned_p (operands[0], operands[1])"
12588 [(parallel
12589 [(set (reg:CCC FLAGS_REG)
12590 (compare:CCC (match_dup 1) (const_int 0)))
12591 (set (match_dup 0)
12592 (ctz:SWI48 (match_dup 1)))
12593 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
12594 "ix86_expand_clear (operands[0]);"
12595 [(set_attr "type" "alu1")
12596 (set_attr "prefix_0f" "1")
12597 (set_attr "prefix_rep" "1")
12598 (set_attr "btver2_decode" "double")
12599 (set_attr "mode" "<MODE>")])
12600
12601 ; False dependency happens when destination is only updated by tzcnt,
12602 ; lzcnt or popcnt. There is no false dependency when destination is
12603 ; also used in source.
12604 (define_insn "*tzcnt<mode>_1_falsedep"
12605 [(set (reg:CCC FLAGS_REG)
12606 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12607 (const_int 0)))
12608 (set (match_operand:SWI48 0 "register_operand" "=r")
12609 (ctz:SWI48 (match_dup 1)))
12610 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12611 UNSPEC_INSN_FALSE_DEP)]
12612 "TARGET_BMI"
12613 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12614 [(set_attr "type" "alu1")
12615 (set_attr "prefix_0f" "1")
12616 (set_attr "prefix_rep" "1")
12617 (set_attr "btver2_decode" "double")
12618 (set_attr "mode" "<MODE>")])
12619
12620 (define_insn "*bsf<mode>_1"
12621 [(set (reg:CCZ FLAGS_REG)
12622 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12623 (const_int 0)))
12624 (set (match_operand:SWI48 0 "register_operand" "=r")
12625 (ctz:SWI48 (match_dup 1)))]
12626 ""
12627 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12628 [(set_attr "type" "alu1")
12629 (set_attr "prefix_0f" "1")
12630 (set_attr "btver2_decode" "double")
12631 (set_attr "znver1_decode" "vector")
12632 (set_attr "mode" "<MODE>")])
12633
12634 (define_insn_and_split "*ctzhi2"
12635 [(set (match_operand:SI 0 "register_operand")
12636 (ctz:SI
12637 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
12638 (clobber (reg:CC FLAGS_REG))]
12639 "TARGET_BMI
12640 && can_create_pseudo_p ()"
12641 "#"
12642 "&& 1"
12643 [(const_int 0)]
12644 {
12645 rtx tmp = gen_reg_rtx (HImode);
12646
12647 emit_insn (gen_tzcnt_hi (tmp, operands[1]));
12648 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
12649 DONE;
12650 })
12651
12652 (define_insn_and_split "ctz<mode>2"
12653 [(set (match_operand:SWI48 0 "register_operand" "=r")
12654 (ctz:SWI48
12655 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12656 (clobber (reg:CC FLAGS_REG))]
12657 ""
12658 {
12659 if (TARGET_BMI)
12660 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12661 else if (optimize_function_for_size_p (cfun))
12662 ;
12663 else if (TARGET_GENERIC)
12664 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12665 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12666
12667 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12668 }
12669 "(TARGET_BMI || TARGET_GENERIC)
12670 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
12671 && optimize_function_for_speed_p (cfun)
12672 && !reg_mentioned_p (operands[0], operands[1])"
12673 [(parallel
12674 [(set (match_dup 0)
12675 (ctz:SWI48 (match_dup 1)))
12676 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12677 (clobber (reg:CC FLAGS_REG))])]
12678 "ix86_expand_clear (operands[0]);"
12679 [(set_attr "type" "alu1")
12680 (set_attr "prefix_0f" "1")
12681 (set (attr "prefix_rep")
12682 (if_then_else
12683 (ior (match_test "TARGET_BMI")
12684 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12685 (match_test "TARGET_GENERIC")))
12686 (const_string "1")
12687 (const_string "0")))
12688 (set_attr "mode" "<MODE>")])
12689
12690 ; False dependency happens when destination is only updated by tzcnt,
12691 ; lzcnt or popcnt. There is no false dependency when destination is
12692 ; also used in source.
12693 (define_insn "*ctz<mode>2_falsedep"
12694 [(set (match_operand:SWI48 0 "register_operand" "=r")
12695 (ctz:SWI48
12696 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12697 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12698 UNSPEC_INSN_FALSE_DEP)
12699 (clobber (reg:CC FLAGS_REG))]
12700 ""
12701 {
12702 if (TARGET_BMI)
12703 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12704 else if (TARGET_GENERIC)
12705 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12706 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12707 else
12708 gcc_unreachable ();
12709 }
12710 [(set_attr "type" "alu1")
12711 (set_attr "prefix_0f" "1")
12712 (set_attr "prefix_rep" "1")
12713 (set_attr "mode" "<MODE>")])
12714
12715 (define_insn "bsr_rex64"
12716 [(set (match_operand:DI 0 "register_operand" "=r")
12717 (minus:DI (const_int 63)
12718 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12719 (clobber (reg:CC FLAGS_REG))]
12720 "TARGET_64BIT"
12721 "bsr{q}\t{%1, %0|%0, %1}"
12722 [(set_attr "type" "alu1")
12723 (set_attr "prefix_0f" "1")
12724 (set_attr "znver1_decode" "vector")
12725 (set_attr "mode" "DI")])
12726
12727 (define_insn "bsr"
12728 [(set (match_operand:SI 0 "register_operand" "=r")
12729 (minus:SI (const_int 31)
12730 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12731 (clobber (reg:CC FLAGS_REG))]
12732 ""
12733 "bsr{l}\t{%1, %0|%0, %1}"
12734 [(set_attr "type" "alu1")
12735 (set_attr "prefix_0f" "1")
12736 (set_attr "znver1_decode" "vector")
12737 (set_attr "mode" "SI")])
12738
12739 (define_insn "*bsrhi"
12740 [(set (match_operand:HI 0 "register_operand" "=r")
12741 (minus:HI (const_int 15)
12742 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12743 (clobber (reg:CC FLAGS_REG))]
12744 ""
12745 "bsr{w}\t{%1, %0|%0, %1}"
12746 [(set_attr "type" "alu1")
12747 (set_attr "prefix_0f" "1")
12748 (set_attr "znver1_decode" "vector")
12749 (set_attr "mode" "HI")])
12750
12751 (define_expand "clz<mode>2"
12752 [(parallel
12753 [(set (match_operand:SWI48 0 "register_operand")
12754 (minus:SWI48
12755 (match_dup 2)
12756 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
12757 (clobber (reg:CC FLAGS_REG))])
12758 (parallel
12759 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
12760 (clobber (reg:CC FLAGS_REG))])]
12761 ""
12762 {
12763 if (TARGET_LZCNT)
12764 {
12765 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12766 DONE;
12767 }
12768 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12769 })
12770
12771 (define_insn_and_split "*clzhi2"
12772 [(set (match_operand:SI 0 "register_operand")
12773 (clz:SI
12774 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
12775 (clobber (reg:CC FLAGS_REG))]
12776 "TARGET_LZCNT
12777 && can_create_pseudo_p ()"
12778 "#"
12779 "&& 1"
12780 [(const_int 0)]
12781 {
12782 rtx tmp = gen_reg_rtx (HImode);
12783
12784 emit_insn (gen_lzcnt_hi (tmp, operands[1]));
12785 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
12786 DONE;
12787 })
12788
12789 (define_insn_and_split "clz<mode>2_lzcnt"
12790 [(set (match_operand:SWI48 0 "register_operand" "=r")
12791 (clz:SWI48
12792 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12793 (clobber (reg:CC FLAGS_REG))]
12794 "TARGET_LZCNT"
12795 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12796 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
12797 && optimize_function_for_speed_p (cfun)
12798 && !reg_mentioned_p (operands[0], operands[1])"
12799 [(parallel
12800 [(set (match_dup 0)
12801 (clz:SWI48 (match_dup 1)))
12802 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12803 (clobber (reg:CC FLAGS_REG))])]
12804 "ix86_expand_clear (operands[0]);"
12805 [(set_attr "prefix_rep" "1")
12806 (set_attr "type" "bitmanip")
12807 (set_attr "mode" "<MODE>")])
12808
12809 ; False dependency happens when destination is only updated by tzcnt,
12810 ; lzcnt or popcnt. There is no false dependency when destination is
12811 ; also used in source.
12812 (define_insn "*clz<mode>2_lzcnt_falsedep"
12813 [(set (match_operand:SWI48 0 "register_operand" "=r")
12814 (clz:SWI48
12815 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12816 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12817 UNSPEC_INSN_FALSE_DEP)
12818 (clobber (reg:CC FLAGS_REG))]
12819 "TARGET_LZCNT"
12820 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12821 [(set_attr "prefix_rep" "1")
12822 (set_attr "type" "bitmanip")
12823 (set_attr "mode" "<MODE>")])
12824
12825 (define_int_iterator LT_ZCNT
12826 [(UNSPEC_TZCNT "TARGET_BMI")
12827 (UNSPEC_LZCNT "TARGET_LZCNT")])
12828
12829 (define_int_attr lt_zcnt
12830 [(UNSPEC_TZCNT "tzcnt")
12831 (UNSPEC_LZCNT "lzcnt")])
12832
12833 (define_int_attr lt_zcnt_type
12834 [(UNSPEC_TZCNT "alu1")
12835 (UNSPEC_LZCNT "bitmanip")])
12836
12837 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
12838 ;; provides operand size as output when source operand is zero.
12839
12840 (define_insn_and_split "<lt_zcnt>_<mode>"
12841 [(set (match_operand:SWI48 0 "register_operand" "=r")
12842 (unspec:SWI48
12843 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
12844 (clobber (reg:CC FLAGS_REG))]
12845 ""
12846 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
12847 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
12848 && optimize_function_for_speed_p (cfun)
12849 && !reg_mentioned_p (operands[0], operands[1])"
12850 [(parallel
12851 [(set (match_dup 0)
12852 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
12853 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12854 (clobber (reg:CC FLAGS_REG))])]
12855 "ix86_expand_clear (operands[0]);"
12856 [(set_attr "type" "<lt_zcnt_type>")
12857 (set_attr "prefix_0f" "1")
12858 (set_attr "prefix_rep" "1")
12859 (set_attr "mode" "<MODE>")])
12860
12861 ; False dependency happens when destination is only updated by tzcnt,
12862 ; lzcnt or popcnt. There is no false dependency when destination is
12863 ; also used in source.
12864 (define_insn "*<lt_zcnt>_<mode>_falsedep"
12865 [(set (match_operand:SWI48 0 "register_operand" "=r")
12866 (unspec:SWI48
12867 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
12868 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12869 UNSPEC_INSN_FALSE_DEP)
12870 (clobber (reg:CC FLAGS_REG))]
12871 ""
12872 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
12873 [(set_attr "type" "<lt_zcnt_type>")
12874 (set_attr "prefix_0f" "1")
12875 (set_attr "prefix_rep" "1")
12876 (set_attr "mode" "<MODE>")])
12877
12878 (define_insn "<lt_zcnt>_hi"
12879 [(set (match_operand:HI 0 "register_operand" "=r")
12880 (unspec:HI
12881 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
12882 (clobber (reg:CC FLAGS_REG))]
12883 ""
12884 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
12885 [(set_attr "type" "<lt_zcnt_type>")
12886 (set_attr "prefix_0f" "1")
12887 (set_attr "prefix_rep" "1")
12888 (set_attr "mode" "HI")])
12889
12890 ;; BMI instructions.
12891
12892 (define_insn "bmi_bextr_<mode>"
12893 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12894 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12895 (match_operand:SWI48 2 "register_operand" "r,r")]
12896 UNSPEC_BEXTR))
12897 (clobber (reg:CC FLAGS_REG))]
12898 "TARGET_BMI"
12899 "bextr\t{%2, %1, %0|%0, %1, %2}"
12900 [(set_attr "type" "bitmanip")
12901 (set_attr "btver2_decode" "direct, double")
12902 (set_attr "mode" "<MODE>")])
12903
12904 (define_insn "*bmi_bextr_<mode>_ccz"
12905 [(set (reg:CCZ FLAGS_REG)
12906 (compare:CCZ
12907 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12908 (match_operand:SWI48 2 "register_operand" "r,r")]
12909 UNSPEC_BEXTR)
12910 (const_int 0)))
12911 (clobber (match_scratch:SWI48 0 "=r,r"))]
12912 "TARGET_BMI"
12913 "bextr\t{%2, %1, %0|%0, %1, %2}"
12914 [(set_attr "type" "bitmanip")
12915 (set_attr "btver2_decode" "direct, double")
12916 (set_attr "mode" "<MODE>")])
12917
12918 (define_insn "*bmi_blsi_<mode>"
12919 [(set (match_operand:SWI48 0 "register_operand" "=r")
12920 (and:SWI48
12921 (neg:SWI48
12922 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12923 (match_dup 1)))
12924 (clobber (reg:CC FLAGS_REG))]
12925 "TARGET_BMI"
12926 "blsi\t{%1, %0|%0, %1}"
12927 [(set_attr "type" "bitmanip")
12928 (set_attr "btver2_decode" "double")
12929 (set_attr "mode" "<MODE>")])
12930
12931 (define_insn "*bmi_blsmsk_<mode>"
12932 [(set (match_operand:SWI48 0 "register_operand" "=r")
12933 (xor:SWI48
12934 (plus:SWI48
12935 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12936 (const_int -1))
12937 (match_dup 1)))
12938 (clobber (reg:CC FLAGS_REG))]
12939 "TARGET_BMI"
12940 "blsmsk\t{%1, %0|%0, %1}"
12941 [(set_attr "type" "bitmanip")
12942 (set_attr "btver2_decode" "double")
12943 (set_attr "mode" "<MODE>")])
12944
12945 (define_insn "*bmi_blsr_<mode>"
12946 [(set (match_operand:SWI48 0 "register_operand" "=r")
12947 (and:SWI48
12948 (plus:SWI48
12949 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12950 (const_int -1))
12951 (match_dup 1)))
12952 (clobber (reg:CC FLAGS_REG))]
12953 "TARGET_BMI"
12954 "blsr\t{%1, %0|%0, %1}"
12955 [(set_attr "type" "bitmanip")
12956 (set_attr "btver2_decode" "double")
12957 (set_attr "mode" "<MODE>")])
12958
12959 ;; BMI2 instructions.
12960 (define_expand "bmi2_bzhi_<mode>3"
12961 [(parallel
12962 [(set (match_operand:SWI48 0 "register_operand")
12963 (zero_extract:SWI48
12964 (match_operand:SWI48 1 "nonimmediate_operand")
12965 (umin:SWI48
12966 (and:SWI48 (match_operand:SWI48 2 "register_operand")
12967 (const_int 255))
12968 (match_dup 3))
12969 (const_int 0)))
12970 (clobber (reg:CC FLAGS_REG))])]
12971 "TARGET_BMI2"
12972 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12973
12974 (define_insn "*bmi2_bzhi_<mode>3"
12975 [(set (match_operand:SWI48 0 "register_operand" "=r")
12976 (zero_extract:SWI48
12977 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12978 (umin:SWI48
12979 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12980 (const_int 255))
12981 (match_operand:SWI48 3 "const_int_operand" "n"))
12982 (const_int 0)))
12983 (clobber (reg:CC FLAGS_REG))]
12984 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12985 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12986 [(set_attr "type" "bitmanip")
12987 (set_attr "prefix" "vex")
12988 (set_attr "mode" "<MODE>")])
12989
12990 (define_mode_attr k [(SI "k") (DI "q")])
12991
12992 (define_insn "*bmi2_bzhi_<mode>3_1"
12993 [(set (match_operand:SWI48 0 "register_operand" "=r")
12994 (zero_extract:SWI48
12995 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12996 (umin:SWI48
12997 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12998 (match_operand:SWI48 3 "const_int_operand" "n"))
12999 (const_int 0)))
13000 (clobber (reg:CC FLAGS_REG))]
13001 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13002 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13003 [(set_attr "type" "bitmanip")
13004 (set_attr "prefix" "vex")
13005 (set_attr "mode" "<MODE>")])
13006
13007 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13008 [(set (reg:CCZ FLAGS_REG)
13009 (compare:CCZ
13010 (zero_extract:SWI48
13011 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13012 (umin:SWI48
13013 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13014 (match_operand:SWI48 3 "const_int_operand" "n"))
13015 (const_int 0))
13016 (const_int 0)))
13017 (clobber (match_scratch:SWI48 0 "=r"))]
13018 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13019 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13020 [(set_attr "type" "bitmanip")
13021 (set_attr "prefix" "vex")
13022 (set_attr "mode" "<MODE>")])
13023
13024 (define_insn "bmi2_pdep_<mode>3"
13025 [(set (match_operand:SWI48 0 "register_operand" "=r")
13026 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13027 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13028 UNSPEC_PDEP))]
13029 "TARGET_BMI2"
13030 "pdep\t{%2, %1, %0|%0, %1, %2}"
13031 [(set_attr "type" "bitmanip")
13032 (set_attr "prefix" "vex")
13033 (set_attr "mode" "<MODE>")])
13034
13035 (define_insn "bmi2_pext_<mode>3"
13036 [(set (match_operand:SWI48 0 "register_operand" "=r")
13037 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13038 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13039 UNSPEC_PEXT))]
13040 "TARGET_BMI2"
13041 "pext\t{%2, %1, %0|%0, %1, %2}"
13042 [(set_attr "type" "bitmanip")
13043 (set_attr "prefix" "vex")
13044 (set_attr "mode" "<MODE>")])
13045
13046 ;; TBM instructions.
13047 (define_insn "tbm_bextri_<mode>"
13048 [(set (match_operand:SWI48 0 "register_operand" "=r")
13049 (zero_extract:SWI48
13050 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13051 (match_operand 2 "const_0_to_255_operand" "N")
13052 (match_operand 3 "const_0_to_255_operand" "N")))
13053 (clobber (reg:CC FLAGS_REG))]
13054 "TARGET_TBM"
13055 {
13056 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13057 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13058 }
13059 [(set_attr "type" "bitmanip")
13060 (set_attr "mode" "<MODE>")])
13061
13062 (define_insn "*tbm_blcfill_<mode>"
13063 [(set (match_operand:SWI48 0 "register_operand" "=r")
13064 (and:SWI48
13065 (plus:SWI48
13066 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13067 (const_int 1))
13068 (match_dup 1)))
13069 (clobber (reg:CC FLAGS_REG))]
13070 "TARGET_TBM"
13071 "blcfill\t{%1, %0|%0, %1}"
13072 [(set_attr "type" "bitmanip")
13073 (set_attr "mode" "<MODE>")])
13074
13075 (define_insn "*tbm_blci_<mode>"
13076 [(set (match_operand:SWI48 0 "register_operand" "=r")
13077 (ior:SWI48
13078 (not:SWI48
13079 (plus:SWI48
13080 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13081 (const_int 1)))
13082 (match_dup 1)))
13083 (clobber (reg:CC FLAGS_REG))]
13084 "TARGET_TBM"
13085 "blci\t{%1, %0|%0, %1}"
13086 [(set_attr "type" "bitmanip")
13087 (set_attr "mode" "<MODE>")])
13088
13089 (define_insn "*tbm_blcic_<mode>"
13090 [(set (match_operand:SWI48 0 "register_operand" "=r")
13091 (and:SWI48
13092 (plus:SWI48
13093 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13094 (const_int 1))
13095 (not:SWI48
13096 (match_dup 1))))
13097 (clobber (reg:CC FLAGS_REG))]
13098 "TARGET_TBM"
13099 "blcic\t{%1, %0|%0, %1}"
13100 [(set_attr "type" "bitmanip")
13101 (set_attr "mode" "<MODE>")])
13102
13103 (define_insn "*tbm_blcmsk_<mode>"
13104 [(set (match_operand:SWI48 0 "register_operand" "=r")
13105 (xor:SWI48
13106 (plus:SWI48
13107 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13108 (const_int 1))
13109 (match_dup 1)))
13110 (clobber (reg:CC FLAGS_REG))]
13111 "TARGET_TBM"
13112 "blcmsk\t{%1, %0|%0, %1}"
13113 [(set_attr "type" "bitmanip")
13114 (set_attr "mode" "<MODE>")])
13115
13116 (define_insn "*tbm_blcs_<mode>"
13117 [(set (match_operand:SWI48 0 "register_operand" "=r")
13118 (ior:SWI48
13119 (plus:SWI48
13120 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13121 (const_int 1))
13122 (match_dup 1)))
13123 (clobber (reg:CC FLAGS_REG))]
13124 "TARGET_TBM"
13125 "blcs\t{%1, %0|%0, %1}"
13126 [(set_attr "type" "bitmanip")
13127 (set_attr "mode" "<MODE>")])
13128
13129 (define_insn "*tbm_blsfill_<mode>"
13130 [(set (match_operand:SWI48 0 "register_operand" "=r")
13131 (ior:SWI48
13132 (plus:SWI48
13133 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13134 (const_int -1))
13135 (match_dup 1)))
13136 (clobber (reg:CC FLAGS_REG))]
13137 "TARGET_TBM"
13138 "blsfill\t{%1, %0|%0, %1}"
13139 [(set_attr "type" "bitmanip")
13140 (set_attr "mode" "<MODE>")])
13141
13142 (define_insn "*tbm_blsic_<mode>"
13143 [(set (match_operand:SWI48 0 "register_operand" "=r")
13144 (ior:SWI48
13145 (plus:SWI48
13146 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13147 (const_int -1))
13148 (not:SWI48
13149 (match_dup 1))))
13150 (clobber (reg:CC FLAGS_REG))]
13151 "TARGET_TBM"
13152 "blsic\t{%1, %0|%0, %1}"
13153 [(set_attr "type" "bitmanip")
13154 (set_attr "mode" "<MODE>")])
13155
13156 (define_insn "*tbm_t1mskc_<mode>"
13157 [(set (match_operand:SWI48 0 "register_operand" "=r")
13158 (ior:SWI48
13159 (plus:SWI48
13160 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13161 (const_int 1))
13162 (not:SWI48
13163 (match_dup 1))))
13164 (clobber (reg:CC FLAGS_REG))]
13165 "TARGET_TBM"
13166 "t1mskc\t{%1, %0|%0, %1}"
13167 [(set_attr "type" "bitmanip")
13168 (set_attr "mode" "<MODE>")])
13169
13170 (define_insn "*tbm_tzmsk_<mode>"
13171 [(set (match_operand:SWI48 0 "register_operand" "=r")
13172 (and:SWI48
13173 (plus:SWI48
13174 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13175 (const_int -1))
13176 (not:SWI48
13177 (match_dup 1))))
13178 (clobber (reg:CC FLAGS_REG))]
13179 "TARGET_TBM"
13180 "tzmsk\t{%1, %0|%0, %1}"
13181 [(set_attr "type" "bitmanip")
13182 (set_attr "mode" "<MODE>")])
13183
13184 (define_insn_and_split "popcount<mode>2"
13185 [(set (match_operand:SWI48 0 "register_operand" "=r")
13186 (popcount:SWI48
13187 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13188 (clobber (reg:CC FLAGS_REG))]
13189 "TARGET_POPCNT"
13190 {
13191 #if TARGET_MACHO
13192 return "popcnt\t{%1, %0|%0, %1}";
13193 #else
13194 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13195 #endif
13196 }
13197 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13198 && optimize_function_for_speed_p (cfun)
13199 && !reg_mentioned_p (operands[0], operands[1])"
13200 [(parallel
13201 [(set (match_dup 0)
13202 (popcount:SWI48 (match_dup 1)))
13203 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13204 (clobber (reg:CC FLAGS_REG))])]
13205 "ix86_expand_clear (operands[0]);"
13206 [(set_attr "prefix_rep" "1")
13207 (set_attr "type" "bitmanip")
13208 (set_attr "mode" "<MODE>")])
13209
13210 ; False dependency happens when destination is only updated by tzcnt,
13211 ; lzcnt or popcnt. There is no false dependency when destination is
13212 ; also used in source.
13213 (define_insn "*popcount<mode>2_falsedep"
13214 [(set (match_operand:SWI48 0 "register_operand" "=r")
13215 (popcount:SWI48
13216 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13217 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13218 UNSPEC_INSN_FALSE_DEP)
13219 (clobber (reg:CC FLAGS_REG))]
13220 "TARGET_POPCNT"
13221 {
13222 #if TARGET_MACHO
13223 return "popcnt\t{%1, %0|%0, %1}";
13224 #else
13225 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13226 #endif
13227 }
13228 [(set_attr "prefix_rep" "1")
13229 (set_attr "type" "bitmanip")
13230 (set_attr "mode" "<MODE>")])
13231
13232 (define_insn_and_split "*popcounthi2_1"
13233 [(set (match_operand:SI 0 "register_operand")
13234 (popcount:SI
13235 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
13236 (clobber (reg:CC FLAGS_REG))]
13237 "TARGET_POPCNT
13238 && can_create_pseudo_p ()"
13239 "#"
13240 "&& 1"
13241 [(const_int 0)]
13242 {
13243 rtx tmp = gen_reg_rtx (HImode);
13244
13245 emit_insn (gen_popcounthi2 (tmp, operands[1]));
13246 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
13247 DONE;
13248 })
13249
13250 (define_insn "popcounthi2"
13251 [(set (match_operand:HI 0 "register_operand" "=r")
13252 (popcount:HI
13253 (match_operand:HI 1 "nonimmediate_operand" "rm")))
13254 (clobber (reg:CC FLAGS_REG))]
13255 "TARGET_POPCNT"
13256 {
13257 #if TARGET_MACHO
13258 return "popcnt\t{%1, %0|%0, %1}";
13259 #else
13260 return "popcnt{w}\t{%1, %0|%0, %1}";
13261 #endif
13262 }
13263 [(set_attr "prefix_rep" "1")
13264 (set_attr "type" "bitmanip")
13265 (set_attr "mode" "HI")])
13266
13267 (define_expand "bswapdi2"
13268 [(set (match_operand:DI 0 "register_operand")
13269 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13270 "TARGET_64BIT"
13271 {
13272 if (!TARGET_MOVBE)
13273 operands[1] = force_reg (DImode, operands[1]);
13274 })
13275
13276 (define_expand "bswapsi2"
13277 [(set (match_operand:SI 0 "register_operand")
13278 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13279 ""
13280 {
13281 if (TARGET_MOVBE)
13282 ;
13283 else if (TARGET_BSWAP)
13284 operands[1] = force_reg (SImode, operands[1]);
13285 else
13286 {
13287 rtx x = operands[0];
13288
13289 emit_move_insn (x, operands[1]);
13290 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13291 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13292 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13293 DONE;
13294 }
13295 })
13296
13297 (define_insn "*bswap<mode>2_movbe"
13298 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13299 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13300 "TARGET_MOVBE
13301 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13302 "@
13303 bswap\t%0
13304 movbe\t{%1, %0|%0, %1}
13305 movbe\t{%1, %0|%0, %1}"
13306 [(set_attr "type" "bitmanip,imov,imov")
13307 (set_attr "modrm" "0,1,1")
13308 (set_attr "prefix_0f" "*,1,1")
13309 (set_attr "prefix_extra" "*,1,1")
13310 (set_attr "mode" "<MODE>")])
13311
13312 (define_insn "*bswap<mode>2"
13313 [(set (match_operand:SWI48 0 "register_operand" "=r")
13314 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13315 "TARGET_BSWAP"
13316 "bswap\t%0"
13317 [(set_attr "type" "bitmanip")
13318 (set_attr "modrm" "0")
13319 (set_attr "mode" "<MODE>")])
13320
13321 (define_insn "*bswaphi_lowpart_1"
13322 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13323 (bswap:HI (match_dup 0)))
13324 (clobber (reg:CC FLAGS_REG))]
13325 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13326 "@
13327 xchg{b}\t{%h0, %b0|%b0, %h0}
13328 rol{w}\t{$8, %0|%0, 8}"
13329 [(set_attr "length" "2,4")
13330 (set_attr "mode" "QI,HI")])
13331
13332 (define_insn "bswaphi_lowpart"
13333 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13334 (bswap:HI (match_dup 0)))
13335 (clobber (reg:CC FLAGS_REG))]
13336 ""
13337 "rol{w}\t{$8, %0|%0, 8}"
13338 [(set_attr "length" "4")
13339 (set_attr "mode" "HI")])
13340
13341 (define_expand "paritydi2"
13342 [(set (match_operand:DI 0 "register_operand")
13343 (parity:DI (match_operand:DI 1 "register_operand")))]
13344 "! TARGET_POPCNT"
13345 {
13346 rtx scratch = gen_reg_rtx (QImode);
13347
13348 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13349 NULL_RTX, operands[1]));
13350
13351 ix86_expand_setcc (scratch, ORDERED,
13352 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13353
13354 if (TARGET_64BIT)
13355 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13356 else
13357 {
13358 rtx tmp = gen_reg_rtx (SImode);
13359
13360 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13361 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13362 }
13363 DONE;
13364 })
13365
13366 (define_expand "paritysi2"
13367 [(set (match_operand:SI 0 "register_operand")
13368 (parity:SI (match_operand:SI 1 "register_operand")))]
13369 "! TARGET_POPCNT"
13370 {
13371 rtx scratch = gen_reg_rtx (QImode);
13372
13373 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13374
13375 ix86_expand_setcc (scratch, ORDERED,
13376 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13377
13378 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13379 DONE;
13380 })
13381
13382 (define_insn_and_split "paritydi2_cmp"
13383 [(set (reg:CC FLAGS_REG)
13384 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13385 UNSPEC_PARITY))
13386 (clobber (match_scratch:DI 0 "=r"))
13387 (clobber (match_scratch:SI 1 "=&r"))
13388 (clobber (match_scratch:HI 2 "=Q"))]
13389 "! TARGET_POPCNT"
13390 "#"
13391 "&& reload_completed"
13392 [(parallel
13393 [(set (match_dup 1)
13394 (xor:SI (match_dup 1) (match_dup 4)))
13395 (clobber (reg:CC FLAGS_REG))])
13396 (parallel
13397 [(set (reg:CC FLAGS_REG)
13398 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13399 (clobber (match_dup 1))
13400 (clobber (match_dup 2))])]
13401 {
13402 operands[4] = gen_lowpart (SImode, operands[3]);
13403
13404 if (TARGET_64BIT)
13405 {
13406 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13407 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13408 }
13409 else
13410 operands[1] = gen_highpart (SImode, operands[3]);
13411 })
13412
13413 (define_insn_and_split "paritysi2_cmp"
13414 [(set (reg:CC FLAGS_REG)
13415 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13416 UNSPEC_PARITY))
13417 (clobber (match_scratch:SI 0 "=r"))
13418 (clobber (match_scratch:HI 1 "=&Q"))]
13419 "! TARGET_POPCNT"
13420 "#"
13421 "&& reload_completed"
13422 [(parallel
13423 [(set (match_dup 1)
13424 (xor:HI (match_dup 1) (match_dup 3)))
13425 (clobber (reg:CC FLAGS_REG))])
13426 (parallel
13427 [(set (reg:CC FLAGS_REG)
13428 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13429 (clobber (match_dup 1))])]
13430 {
13431 operands[3] = gen_lowpart (HImode, operands[2]);
13432
13433 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13434 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13435 })
13436
13437 (define_insn "*parityhi2_cmp"
13438 [(set (reg:CC FLAGS_REG)
13439 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13440 UNSPEC_PARITY))
13441 (clobber (match_scratch:HI 0 "=Q"))]
13442 "! TARGET_POPCNT"
13443 "xor{b}\t{%h0, %b0|%b0, %h0}"
13444 [(set_attr "length" "2")
13445 (set_attr "mode" "HI")])
13446
13447 \f
13448 ;; Thread-local storage patterns for ELF.
13449 ;;
13450 ;; Note that these code sequences must appear exactly as shown
13451 ;; in order to allow linker relaxation.
13452
13453 (define_insn "*tls_global_dynamic_32_gnu"
13454 [(set (match_operand:SI 0 "register_operand" "=a")
13455 (unspec:SI
13456 [(match_operand:SI 1 "register_operand" "Yb")
13457 (match_operand 2 "tls_symbolic_operand")
13458 (match_operand 3 "constant_call_address_operand" "Bz")
13459 (reg:SI SP_REG)]
13460 UNSPEC_TLS_GD))
13461 (clobber (match_scratch:SI 4 "=d"))
13462 (clobber (match_scratch:SI 5 "=c"))
13463 (clobber (reg:CC FLAGS_REG))]
13464 "!TARGET_64BIT && TARGET_GNU_TLS"
13465 {
13466 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13467 output_asm_insn
13468 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13469 else
13470 output_asm_insn
13471 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
13472 if (TARGET_SUN_TLS)
13473 #ifdef HAVE_AS_IX86_TLSGDPLT
13474 return "call\t%a2@tlsgdplt";
13475 #else
13476 return "call\t%p3@plt";
13477 #endif
13478 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13479 return "call\t%P3";
13480 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
13481 }
13482 [(set_attr "type" "multi")
13483 (set_attr "length" "12")])
13484
13485 (define_expand "tls_global_dynamic_32"
13486 [(parallel
13487 [(set (match_operand:SI 0 "register_operand")
13488 (unspec:SI [(match_operand:SI 2 "register_operand")
13489 (match_operand 1 "tls_symbolic_operand")
13490 (match_operand 3 "constant_call_address_operand")
13491 (reg:SI SP_REG)]
13492 UNSPEC_TLS_GD))
13493 (clobber (match_scratch:SI 4))
13494 (clobber (match_scratch:SI 5))
13495 (clobber (reg:CC FLAGS_REG))])]
13496 ""
13497 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13498
13499 (define_insn "*tls_global_dynamic_64_<mode>"
13500 [(set (match_operand:P 0 "register_operand" "=a")
13501 (call:P
13502 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13503 (match_operand 3)))
13504 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13505 (reg:P SP_REG)]
13506 UNSPEC_TLS_GD)]
13507 "TARGET_64BIT"
13508 {
13509 if (!TARGET_X32)
13510 fputs (ASM_BYTE "0x66\n", asm_out_file);
13511 output_asm_insn
13512 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13513 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13514 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13515 else
13516 fputs (ASM_BYTE "0x66\n", asm_out_file);
13517 fputs ("\trex64\n", asm_out_file);
13518 if (TARGET_SUN_TLS)
13519 return "call\t%p2@plt";
13520 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13521 return "call\t%P2";
13522 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
13523 }
13524 [(set_attr "type" "multi")
13525 (set (attr "length")
13526 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13527
13528 (define_insn "*tls_global_dynamic_64_largepic"
13529 [(set (match_operand:DI 0 "register_operand" "=a")
13530 (call:DI
13531 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13532 (match_operand:DI 3 "immediate_operand" "i")))
13533 (match_operand 4)))
13534 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13535 (reg:DI SP_REG)]
13536 UNSPEC_TLS_GD)]
13537 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13538 && GET_CODE (operands[3]) == CONST
13539 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13540 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13541 {
13542 output_asm_insn
13543 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13544 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13545 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13546 return "call\t{*%%rax|rax}";
13547 }
13548 [(set_attr "type" "multi")
13549 (set_attr "length" "22")])
13550
13551 (define_expand "tls_global_dynamic_64_<mode>"
13552 [(parallel
13553 [(set (match_operand:P 0 "register_operand")
13554 (call:P
13555 (mem:QI (match_operand 2))
13556 (const_int 0)))
13557 (unspec:P [(match_operand 1 "tls_symbolic_operand")
13558 (reg:P SP_REG)]
13559 UNSPEC_TLS_GD)])]
13560 "TARGET_64BIT"
13561 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13562
13563 (define_insn "*tls_local_dynamic_base_32_gnu"
13564 [(set (match_operand:SI 0 "register_operand" "=a")
13565 (unspec:SI
13566 [(match_operand:SI 1 "register_operand" "Yb")
13567 (match_operand 2 "constant_call_address_operand" "Bz")
13568 (reg:SI SP_REG)]
13569 UNSPEC_TLS_LD_BASE))
13570 (clobber (match_scratch:SI 3 "=d"))
13571 (clobber (match_scratch:SI 4 "=c"))
13572 (clobber (reg:CC FLAGS_REG))]
13573 "!TARGET_64BIT && TARGET_GNU_TLS"
13574 {
13575 output_asm_insn
13576 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13577 if (TARGET_SUN_TLS)
13578 {
13579 if (HAVE_AS_IX86_TLSLDMPLT)
13580 return "call\t%&@tlsldmplt";
13581 else
13582 return "call\t%p2@plt";
13583 }
13584 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13585 return "call\t%P2";
13586 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
13587 }
13588 [(set_attr "type" "multi")
13589 (set_attr "length" "11")])
13590
13591 (define_expand "tls_local_dynamic_base_32"
13592 [(parallel
13593 [(set (match_operand:SI 0 "register_operand")
13594 (unspec:SI
13595 [(match_operand:SI 1 "register_operand")
13596 (match_operand 2 "constant_call_address_operand")
13597 (reg:SI SP_REG)]
13598 UNSPEC_TLS_LD_BASE))
13599 (clobber (match_scratch:SI 3))
13600 (clobber (match_scratch:SI 4))
13601 (clobber (reg:CC FLAGS_REG))])]
13602 ""
13603 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13604
13605 (define_insn "*tls_local_dynamic_base_64_<mode>"
13606 [(set (match_operand:P 0 "register_operand" "=a")
13607 (call:P
13608 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13609 (match_operand 2)))
13610 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13611 "TARGET_64BIT"
13612 {
13613 output_asm_insn
13614 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13615 if (TARGET_SUN_TLS)
13616 return "call\t%p1@plt";
13617 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13618 return "call\t%P1";
13619 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
13620 }
13621 [(set_attr "type" "multi")
13622 (set_attr "length" "12")])
13623
13624 (define_insn "*tls_local_dynamic_base_64_largepic"
13625 [(set (match_operand:DI 0 "register_operand" "=a")
13626 (call:DI
13627 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13628 (match_operand:DI 2 "immediate_operand" "i")))
13629 (match_operand 3)))
13630 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13631 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13632 && GET_CODE (operands[2]) == CONST
13633 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13634 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13635 {
13636 output_asm_insn
13637 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13638 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13639 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13640 return "call\t{*%%rax|rax}";
13641 }
13642 [(set_attr "type" "multi")
13643 (set_attr "length" "22")])
13644
13645 (define_expand "tls_local_dynamic_base_64_<mode>"
13646 [(parallel
13647 [(set (match_operand:P 0 "register_operand")
13648 (call:P
13649 (mem:QI (match_operand 1))
13650 (const_int 0)))
13651 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13652 "TARGET_64BIT"
13653 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13654
13655 ;; Local dynamic of a single variable is a lose. Show combine how
13656 ;; to convert that back to global dynamic.
13657
13658 (define_insn_and_split "*tls_local_dynamic_32_once"
13659 [(set (match_operand:SI 0 "register_operand" "=a")
13660 (plus:SI
13661 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13662 (match_operand 2 "constant_call_address_operand" "Bz")
13663 (reg:SI SP_REG)]
13664 UNSPEC_TLS_LD_BASE)
13665 (const:SI (unspec:SI
13666 [(match_operand 3 "tls_symbolic_operand")]
13667 UNSPEC_DTPOFF))))
13668 (clobber (match_scratch:SI 4 "=d"))
13669 (clobber (match_scratch:SI 5 "=c"))
13670 (clobber (reg:CC FLAGS_REG))]
13671 ""
13672 "#"
13673 ""
13674 [(parallel
13675 [(set (match_dup 0)
13676 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13677 (reg:SI SP_REG)]
13678 UNSPEC_TLS_GD))
13679 (clobber (match_dup 4))
13680 (clobber (match_dup 5))
13681 (clobber (reg:CC FLAGS_REG))])])
13682
13683 ;; Segment register for the thread base ptr load
13684 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13685
13686 ;; Load and add the thread base pointer from %<tp_seg>:0.
13687 (define_insn "*load_tp_x32"
13688 [(set (match_operand:SI 0 "register_operand" "=r")
13689 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13690 "TARGET_X32"
13691 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13692 [(set_attr "type" "imov")
13693 (set_attr "modrm" "0")
13694 (set_attr "length" "7")
13695 (set_attr "memory" "load")
13696 (set_attr "imm_disp" "false")])
13697
13698 (define_insn "*load_tp_x32_zext"
13699 [(set (match_operand:DI 0 "register_operand" "=r")
13700 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13701 "TARGET_X32"
13702 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13703 [(set_attr "type" "imov")
13704 (set_attr "modrm" "0")
13705 (set_attr "length" "7")
13706 (set_attr "memory" "load")
13707 (set_attr "imm_disp" "false")])
13708
13709 (define_insn "*load_tp_<mode>"
13710 [(set (match_operand:P 0 "register_operand" "=r")
13711 (unspec:P [(const_int 0)] UNSPEC_TP))]
13712 "!TARGET_X32"
13713 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13714 [(set_attr "type" "imov")
13715 (set_attr "modrm" "0")
13716 (set_attr "length" "7")
13717 (set_attr "memory" "load")
13718 (set_attr "imm_disp" "false")])
13719
13720 (define_insn "*add_tp_x32"
13721 [(set (match_operand:SI 0 "register_operand" "=r")
13722 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13723 (match_operand:SI 1 "register_operand" "0")))
13724 (clobber (reg:CC FLAGS_REG))]
13725 "TARGET_X32"
13726 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13727 [(set_attr "type" "alu")
13728 (set_attr "modrm" "0")
13729 (set_attr "length" "7")
13730 (set_attr "memory" "load")
13731 (set_attr "imm_disp" "false")])
13732
13733 (define_insn "*add_tp_x32_zext"
13734 [(set (match_operand:DI 0 "register_operand" "=r")
13735 (zero_extend:DI
13736 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13737 (match_operand:SI 1 "register_operand" "0"))))
13738 (clobber (reg:CC FLAGS_REG))]
13739 "TARGET_X32"
13740 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13741 [(set_attr "type" "alu")
13742 (set_attr "modrm" "0")
13743 (set_attr "length" "7")
13744 (set_attr "memory" "load")
13745 (set_attr "imm_disp" "false")])
13746
13747 (define_insn "*add_tp_<mode>"
13748 [(set (match_operand:P 0 "register_operand" "=r")
13749 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13750 (match_operand:P 1 "register_operand" "0")))
13751 (clobber (reg:CC FLAGS_REG))]
13752 "!TARGET_X32"
13753 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13754 [(set_attr "type" "alu")
13755 (set_attr "modrm" "0")
13756 (set_attr "length" "7")
13757 (set_attr "memory" "load")
13758 (set_attr "imm_disp" "false")])
13759
13760 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13761 ;; %rax as destination of the initial executable code sequence.
13762 (define_insn "tls_initial_exec_64_sun"
13763 [(set (match_operand:DI 0 "register_operand" "=a")
13764 (unspec:DI
13765 [(match_operand 1 "tls_symbolic_operand")]
13766 UNSPEC_TLS_IE_SUN))
13767 (clobber (reg:CC FLAGS_REG))]
13768 "TARGET_64BIT && TARGET_SUN_TLS"
13769 {
13770 output_asm_insn
13771 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13772 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13773 }
13774 [(set_attr "type" "multi")])
13775
13776 ;; GNU2 TLS patterns can be split.
13777
13778 (define_expand "tls_dynamic_gnu2_32"
13779 [(set (match_dup 3)
13780 (plus:SI (match_operand:SI 2 "register_operand")
13781 (const:SI
13782 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13783 UNSPEC_TLSDESC))))
13784 (parallel
13785 [(set (match_operand:SI 0 "register_operand")
13786 (unspec:SI [(match_dup 1) (match_dup 3)
13787 (match_dup 2) (reg:SI SP_REG)]
13788 UNSPEC_TLSDESC))
13789 (clobber (reg:CC FLAGS_REG))])]
13790 "!TARGET_64BIT && TARGET_GNU2_TLS"
13791 {
13792 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13793 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13794 })
13795
13796 (define_insn "*tls_dynamic_gnu2_lea_32"
13797 [(set (match_operand:SI 0 "register_operand" "=r")
13798 (plus:SI (match_operand:SI 1 "register_operand" "b")
13799 (const:SI
13800 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13801 UNSPEC_TLSDESC))))]
13802 "!TARGET_64BIT && TARGET_GNU2_TLS"
13803 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13804 [(set_attr "type" "lea")
13805 (set_attr "mode" "SI")
13806 (set_attr "length" "6")
13807 (set_attr "length_address" "4")])
13808
13809 (define_insn "*tls_dynamic_gnu2_call_32"
13810 [(set (match_operand:SI 0 "register_operand" "=a")
13811 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13812 (match_operand:SI 2 "register_operand" "0")
13813 ;; we have to make sure %ebx still points to the GOT
13814 (match_operand:SI 3 "register_operand" "b")
13815 (reg:SI SP_REG)]
13816 UNSPEC_TLSDESC))
13817 (clobber (reg:CC FLAGS_REG))]
13818 "!TARGET_64BIT && TARGET_GNU2_TLS"
13819 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13820 [(set_attr "type" "call")
13821 (set_attr "length" "2")
13822 (set_attr "length_address" "0")])
13823
13824 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13825 [(set (match_operand:SI 0 "register_operand" "=&a")
13826 (plus:SI
13827 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13828 (match_operand:SI 4)
13829 (match_operand:SI 2 "register_operand" "b")
13830 (reg:SI SP_REG)]
13831 UNSPEC_TLSDESC)
13832 (const:SI (unspec:SI
13833 [(match_operand 1 "tls_symbolic_operand")]
13834 UNSPEC_DTPOFF))))
13835 (clobber (reg:CC FLAGS_REG))]
13836 "!TARGET_64BIT && TARGET_GNU2_TLS"
13837 "#"
13838 ""
13839 [(set (match_dup 0) (match_dup 5))]
13840 {
13841 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13842 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13843 })
13844
13845 (define_expand "tls_dynamic_gnu2_64"
13846 [(set (match_dup 2)
13847 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13848 UNSPEC_TLSDESC))
13849 (parallel
13850 [(set (match_operand:DI 0 "register_operand")
13851 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13852 UNSPEC_TLSDESC))
13853 (clobber (reg:CC FLAGS_REG))])]
13854 "TARGET_64BIT && TARGET_GNU2_TLS"
13855 {
13856 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13857 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13858 })
13859
13860 (define_insn "*tls_dynamic_gnu2_lea_64"
13861 [(set (match_operand:DI 0 "register_operand" "=r")
13862 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13863 UNSPEC_TLSDESC))]
13864 "TARGET_64BIT && TARGET_GNU2_TLS"
13865 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13866 [(set_attr "type" "lea")
13867 (set_attr "mode" "DI")
13868 (set_attr "length" "7")
13869 (set_attr "length_address" "4")])
13870
13871 (define_insn "*tls_dynamic_gnu2_call_64"
13872 [(set (match_operand:DI 0 "register_operand" "=a")
13873 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13874 (match_operand:DI 2 "register_operand" "0")
13875 (reg:DI SP_REG)]
13876 UNSPEC_TLSDESC))
13877 (clobber (reg:CC FLAGS_REG))]
13878 "TARGET_64BIT && TARGET_GNU2_TLS"
13879 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13880 [(set_attr "type" "call")
13881 (set_attr "length" "2")
13882 (set_attr "length_address" "0")])
13883
13884 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13885 [(set (match_operand:DI 0 "register_operand" "=&a")
13886 (plus:DI
13887 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13888 (match_operand:DI 3)
13889 (reg:DI SP_REG)]
13890 UNSPEC_TLSDESC)
13891 (const:DI (unspec:DI
13892 [(match_operand 1 "tls_symbolic_operand")]
13893 UNSPEC_DTPOFF))))
13894 (clobber (reg:CC FLAGS_REG))]
13895 "TARGET_64BIT && TARGET_GNU2_TLS"
13896 "#"
13897 ""
13898 [(set (match_dup 0) (match_dup 4))]
13899 {
13900 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13901 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13902 })
13903 \f
13904 ;; These patterns match the binary 387 instructions for addM3, subM3,
13905 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13906 ;; SFmode. The first is the normal insn, the second the same insn but
13907 ;; with one operand a conversion, and the third the same insn but with
13908 ;; the other operand a conversion. The conversion may be SFmode or
13909 ;; SImode if the target mode DFmode, but only SImode if the target mode
13910 ;; is SFmode.
13911
13912 ;; Gcc is slightly more smart about handling normal two address instructions
13913 ;; so use special patterns for add and mull.
13914
13915 (define_insn "*fop_<mode>_comm"
13916 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
13917 (match_operator:MODEF 3 "binary_fp_operator"
13918 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
13919 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
13920 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13921 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
13922 && COMMUTATIVE_ARITH_P (operands[3])
13923 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13924 "* return output_387_binary_op (insn, operands);"
13925 [(set (attr "type")
13926 (if_then_else (eq_attr "alternative" "1,2")
13927 (if_then_else (match_operand:MODEF 3 "mult_operator")
13928 (const_string "ssemul")
13929 (const_string "sseadd"))
13930 (if_then_else (match_operand:MODEF 3 "mult_operator")
13931 (const_string "fmul")
13932 (const_string "fop"))))
13933 (set_attr "isa" "*,noavx,avx")
13934 (set_attr "prefix" "orig,orig,vex")
13935 (set_attr "mode" "<MODE>")
13936 (set (attr "enabled")
13937 (if_then_else
13938 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13939 (if_then_else
13940 (eq_attr "alternative" "0")
13941 (symbol_ref "TARGET_MIX_SSE_I387
13942 && X87_ENABLE_ARITH (<MODE>mode)")
13943 (const_string "*"))
13944 (if_then_else
13945 (eq_attr "alternative" "0")
13946 (symbol_ref "true")
13947 (symbol_ref "false"))))])
13948
13949 (define_insn "*rcpsf2_sse"
13950 [(set (match_operand:SF 0 "register_operand" "=x")
13951 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13952 UNSPEC_RCP))]
13953 "TARGET_SSE_MATH"
13954 "%vrcpss\t{%1, %d0|%d0, %1}"
13955 [(set_attr "type" "sse")
13956 (set_attr "atom_sse_attr" "rcp")
13957 (set_attr "btver2_sse_attr" "rcp")
13958 (set_attr "prefix" "maybe_vex")
13959 (set_attr "mode" "SF")])
13960
13961 (define_insn "*fop_<mode>_1"
13962 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
13963 (match_operator:MODEF 3 "binary_fp_operator"
13964 [(match_operand:MODEF 1
13965 "x87nonimm_ssenomem_operand" "0,fm,0,v")
13966 (match_operand:MODEF 2
13967 "nonimmediate_operand" "fm,0,xm,vm")]))]
13968 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13969 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
13970 && !COMMUTATIVE_ARITH_P (operands[3])
13971 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13972 "* return output_387_binary_op (insn, operands);"
13973 [(set (attr "type")
13974 (if_then_else (eq_attr "alternative" "2,3")
13975 (if_then_else (match_operand:MODEF 3 "div_operator")
13976 (const_string "ssediv")
13977 (const_string "sseadd"))
13978 (if_then_else (match_operand:MODEF 3 "div_operator")
13979 (const_string "fdiv")
13980 (const_string "fop"))))
13981 (set_attr "isa" "*,*,noavx,avx")
13982 (set_attr "prefix" "orig,orig,orig,vex")
13983 (set_attr "mode" "<MODE>")
13984 (set (attr "enabled")
13985 (if_then_else
13986 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13987 (if_then_else
13988 (eq_attr "alternative" "0,1")
13989 (symbol_ref "TARGET_MIX_SSE_I387
13990 && X87_ENABLE_ARITH (<MODE>mode)")
13991 (const_string "*"))
13992 (if_then_else
13993 (eq_attr "alternative" "0,1")
13994 (symbol_ref "true")
13995 (symbol_ref "false"))))])
13996
13997 ;; ??? Add SSE splitters for these!
13998 (define_insn "*fop_<MODEF:mode>_2_i387"
13999 [(set (match_operand:MODEF 0 "register_operand" "=f")
14000 (match_operator:MODEF 3 "binary_fp_operator"
14001 [(float:MODEF
14002 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14003 (match_operand:MODEF 2 "register_operand" "0")]))]
14004 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14005 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14006 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14007 || optimize_function_for_size_p (cfun))"
14008 "* return output_387_binary_op (insn, operands);"
14009 [(set (attr "type")
14010 (cond [(match_operand:MODEF 3 "mult_operator")
14011 (const_string "fmul")
14012 (match_operand:MODEF 3 "div_operator")
14013 (const_string "fdiv")
14014 ]
14015 (const_string "fop")))
14016 (set_attr "fp_int_src" "true")
14017 (set_attr "mode" "<SWI24:MODE>")])
14018
14019 (define_insn "*fop_<MODEF:mode>_3_i387"
14020 [(set (match_operand:MODEF 0 "register_operand" "=f")
14021 (match_operator:MODEF 3 "binary_fp_operator"
14022 [(match_operand:MODEF 1 "register_operand" "0")
14023 (float:MODEF
14024 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14025 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14026 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14027 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14028 || optimize_function_for_size_p (cfun))"
14029 "* return output_387_binary_op (insn, operands);"
14030 [(set (attr "type")
14031 (cond [(match_operand:MODEF 3 "mult_operator")
14032 (const_string "fmul")
14033 (match_operand:MODEF 3 "div_operator")
14034 (const_string "fdiv")
14035 ]
14036 (const_string "fop")))
14037 (set_attr "fp_int_src" "true")
14038 (set_attr "mode" "<MODE>")])
14039
14040 (define_insn "*fop_df_4_i387"
14041 [(set (match_operand:DF 0 "register_operand" "=f,f")
14042 (match_operator:DF 3 "binary_fp_operator"
14043 [(float_extend:DF
14044 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14045 (match_operand:DF 2 "register_operand" "0,f")]))]
14046 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14047 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14048 "* return output_387_binary_op (insn, operands);"
14049 [(set (attr "type")
14050 (cond [(match_operand:DF 3 "mult_operator")
14051 (const_string "fmul")
14052 (match_operand:DF 3 "div_operator")
14053 (const_string "fdiv")
14054 ]
14055 (const_string "fop")))
14056 (set_attr "mode" "SF")])
14057
14058 (define_insn "*fop_df_5_i387"
14059 [(set (match_operand:DF 0 "register_operand" "=f,f")
14060 (match_operator:DF 3 "binary_fp_operator"
14061 [(match_operand:DF 1 "register_operand" "0,f")
14062 (float_extend:DF
14063 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14064 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14065 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14066 "* return output_387_binary_op (insn, operands);"
14067 [(set (attr "type")
14068 (cond [(match_operand:DF 3 "mult_operator")
14069 (const_string "fmul")
14070 (match_operand:DF 3 "div_operator")
14071 (const_string "fdiv")
14072 ]
14073 (const_string "fop")))
14074 (set_attr "mode" "SF")])
14075
14076 (define_insn "*fop_df_6_i387"
14077 [(set (match_operand:DF 0 "register_operand" "=f,f")
14078 (match_operator:DF 3 "binary_fp_operator"
14079 [(float_extend:DF
14080 (match_operand:SF 1 "register_operand" "0,f"))
14081 (float_extend:DF
14082 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14083 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14084 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14085 "* return output_387_binary_op (insn, operands);"
14086 [(set (attr "type")
14087 (cond [(match_operand:DF 3 "mult_operator")
14088 (const_string "fmul")
14089 (match_operand:DF 3 "div_operator")
14090 (const_string "fdiv")
14091 ]
14092 (const_string "fop")))
14093 (set_attr "mode" "SF")])
14094
14095 (define_insn "*fop_xf_comm_i387"
14096 [(set (match_operand:XF 0 "register_operand" "=f")
14097 (match_operator:XF 3 "binary_fp_operator"
14098 [(match_operand:XF 1 "register_operand" "%0")
14099 (match_operand:XF 2 "register_operand" "f")]))]
14100 "TARGET_80387
14101 && COMMUTATIVE_ARITH_P (operands[3])"
14102 "* return output_387_binary_op (insn, operands);"
14103 [(set (attr "type")
14104 (if_then_else (match_operand:XF 3 "mult_operator")
14105 (const_string "fmul")
14106 (const_string "fop")))
14107 (set_attr "mode" "XF")])
14108
14109 (define_insn "*fop_xf_1_i387"
14110 [(set (match_operand:XF 0 "register_operand" "=f,f")
14111 (match_operator:XF 3 "binary_fp_operator"
14112 [(match_operand:XF 1 "register_operand" "0,f")
14113 (match_operand:XF 2 "register_operand" "f,0")]))]
14114 "TARGET_80387
14115 && !COMMUTATIVE_ARITH_P (operands[3])"
14116 "* return output_387_binary_op (insn, operands);"
14117 [(set (attr "type")
14118 (if_then_else (match_operand:XF 3 "div_operator")
14119 (const_string "fdiv")
14120 (const_string "fop")))
14121 (set_attr "mode" "XF")])
14122
14123 (define_insn "*fop_xf_2_i387"
14124 [(set (match_operand:XF 0 "register_operand" "=f")
14125 (match_operator:XF 3 "binary_fp_operator"
14126 [(float:XF
14127 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14128 (match_operand:XF 2 "register_operand" "0")]))]
14129 "TARGET_80387
14130 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14131 "* return output_387_binary_op (insn, operands);"
14132 [(set (attr "type")
14133 (cond [(match_operand:XF 3 "mult_operator")
14134 (const_string "fmul")
14135 (match_operand:XF 3 "div_operator")
14136 (const_string "fdiv")
14137 ]
14138 (const_string "fop")))
14139 (set_attr "fp_int_src" "true")
14140 (set_attr "mode" "<MODE>")])
14141
14142 (define_insn "*fop_xf_3_i387"
14143 [(set (match_operand:XF 0 "register_operand" "=f")
14144 (match_operator:XF 3 "binary_fp_operator"
14145 [(match_operand:XF 1 "register_operand" "0")
14146 (float:XF
14147 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14148 "TARGET_80387
14149 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14150 "* return output_387_binary_op (insn, operands);"
14151 [(set (attr "type")
14152 (cond [(match_operand:XF 3 "mult_operator")
14153 (const_string "fmul")
14154 (match_operand:XF 3 "div_operator")
14155 (const_string "fdiv")
14156 ]
14157 (const_string "fop")))
14158 (set_attr "fp_int_src" "true")
14159 (set_attr "mode" "<MODE>")])
14160
14161 (define_insn "*fop_xf_4_i387"
14162 [(set (match_operand:XF 0 "register_operand" "=f,f")
14163 (match_operator:XF 3 "binary_fp_operator"
14164 [(float_extend:XF
14165 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14166 (match_operand:XF 2 "register_operand" "0,f")]))]
14167 "TARGET_80387"
14168 "* return output_387_binary_op (insn, operands);"
14169 [(set (attr "type")
14170 (cond [(match_operand:XF 3 "mult_operator")
14171 (const_string "fmul")
14172 (match_operand:XF 3 "div_operator")
14173 (const_string "fdiv")
14174 ]
14175 (const_string "fop")))
14176 (set_attr "mode" "<MODE>")])
14177
14178 (define_insn "*fop_xf_5_i387"
14179 [(set (match_operand:XF 0 "register_operand" "=f,f")
14180 (match_operator:XF 3 "binary_fp_operator"
14181 [(match_operand:XF 1 "register_operand" "0,f")
14182 (float_extend:XF
14183 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14184 "TARGET_80387"
14185 "* return output_387_binary_op (insn, operands);"
14186 [(set (attr "type")
14187 (cond [(match_operand:XF 3 "mult_operator")
14188 (const_string "fmul")
14189 (match_operand:XF 3 "div_operator")
14190 (const_string "fdiv")
14191 ]
14192 (const_string "fop")))
14193 (set_attr "mode" "<MODE>")])
14194
14195 (define_insn "*fop_xf_6_i387"
14196 [(set (match_operand:XF 0 "register_operand" "=f,f")
14197 (match_operator:XF 3 "binary_fp_operator"
14198 [(float_extend:XF
14199 (match_operand:MODEF 1 "register_operand" "0,f"))
14200 (float_extend:XF
14201 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14202 "TARGET_80387"
14203 "* return output_387_binary_op (insn, operands);"
14204 [(set (attr "type")
14205 (cond [(match_operand:XF 3 "mult_operator")
14206 (const_string "fmul")
14207 (match_operand:XF 3 "div_operator")
14208 (const_string "fdiv")
14209 ]
14210 (const_string "fop")))
14211 (set_attr "mode" "<MODE>")])
14212 \f
14213 ;; FPU special functions.
14214
14215 ;; This pattern implements a no-op XFmode truncation for
14216 ;; all fancy i386 XFmode math functions.
14217
14218 (define_insn "truncxf<mode>2_i387_noop_unspec"
14219 [(set (match_operand:MODEF 0 "register_operand" "=f")
14220 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14221 UNSPEC_TRUNC_NOOP))]
14222 "TARGET_USE_FANCY_MATH_387"
14223 "* return output_387_reg_move (insn, operands);"
14224 [(set_attr "type" "fmov")
14225 (set_attr "mode" "<MODE>")])
14226
14227 (define_insn "sqrtxf2"
14228 [(set (match_operand:XF 0 "register_operand" "=f")
14229 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14230 "TARGET_USE_FANCY_MATH_387"
14231 "fsqrt"
14232 [(set_attr "type" "fpspc")
14233 (set_attr "mode" "XF")
14234 (set_attr "athlon_decode" "direct")
14235 (set_attr "amdfam10_decode" "direct")
14236 (set_attr "bdver1_decode" "direct")])
14237
14238 (define_insn "sqrt_extend<mode>xf2_i387"
14239 [(set (match_operand:XF 0 "register_operand" "=f")
14240 (sqrt:XF
14241 (float_extend:XF
14242 (match_operand:MODEF 1 "register_operand" "0"))))]
14243 "TARGET_USE_FANCY_MATH_387"
14244 "fsqrt"
14245 [(set_attr "type" "fpspc")
14246 (set_attr "mode" "XF")
14247 (set_attr "athlon_decode" "direct")
14248 (set_attr "amdfam10_decode" "direct")
14249 (set_attr "bdver1_decode" "direct")])
14250
14251 (define_insn "*rsqrtsf2_sse"
14252 [(set (match_operand:SF 0 "register_operand" "=x")
14253 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14254 UNSPEC_RSQRT))]
14255 "TARGET_SSE_MATH"
14256 "%vrsqrtss\t{%1, %d0|%d0, %1}"
14257 [(set_attr "type" "sse")
14258 (set_attr "atom_sse_attr" "rcp")
14259 (set_attr "btver2_sse_attr" "rcp")
14260 (set_attr "prefix" "maybe_vex")
14261 (set_attr "mode" "SF")])
14262
14263 (define_expand "rsqrtsf2"
14264 [(set (match_operand:SF 0 "register_operand")
14265 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14266 UNSPEC_RSQRT))]
14267 "TARGET_SSE_MATH"
14268 {
14269 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14270 DONE;
14271 })
14272
14273 (define_insn "*sqrt<mode>2_sse"
14274 [(set (match_operand:MODEF 0 "register_operand" "=v")
14275 (sqrt:MODEF
14276 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14277 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14278 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14279 [(set_attr "type" "sse")
14280 (set_attr "atom_sse_attr" "sqrt")
14281 (set_attr "btver2_sse_attr" "sqrt")
14282 (set_attr "prefix" "maybe_vex")
14283 (set_attr "mode" "<MODE>")
14284 (set_attr "athlon_decode" "*")
14285 (set_attr "amdfam10_decode" "*")
14286 (set_attr "bdver1_decode" "*")])
14287
14288 (define_expand "sqrt<mode>2"
14289 [(set (match_operand:MODEF 0 "register_operand")
14290 (sqrt:MODEF
14291 (match_operand:MODEF 1 "nonimmediate_operand")))]
14292 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14293 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14294 {
14295 if (<MODE>mode == SFmode
14296 && TARGET_SSE_MATH
14297 && TARGET_RECIP_SQRT
14298 && !optimize_function_for_size_p (cfun)
14299 && flag_finite_math_only && !flag_trapping_math
14300 && flag_unsafe_math_optimizations)
14301 {
14302 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14303 DONE;
14304 }
14305
14306 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14307 {
14308 rtx op0 = gen_reg_rtx (XFmode);
14309 rtx op1 = force_reg (<MODE>mode, operands[1]);
14310
14311 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14312 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14313 DONE;
14314 }
14315 })
14316
14317 (define_insn "fpremxf4_i387"
14318 [(set (match_operand:XF 0 "register_operand" "=f")
14319 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14320 (match_operand:XF 3 "register_operand" "1")]
14321 UNSPEC_FPREM_F))
14322 (set (match_operand:XF 1 "register_operand" "=u")
14323 (unspec:XF [(match_dup 2) (match_dup 3)]
14324 UNSPEC_FPREM_U))
14325 (set (reg:CCFP FPSR_REG)
14326 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14327 UNSPEC_C2_FLAG))]
14328 "TARGET_USE_FANCY_MATH_387
14329 && flag_finite_math_only"
14330 "fprem"
14331 [(set_attr "type" "fpspc")
14332 (set_attr "znver1_decode" "vector")
14333 (set_attr "mode" "XF")])
14334
14335 (define_expand "fmodxf3"
14336 [(use (match_operand:XF 0 "register_operand"))
14337 (use (match_operand:XF 1 "general_operand"))
14338 (use (match_operand:XF 2 "general_operand"))]
14339 "TARGET_USE_FANCY_MATH_387
14340 && flag_finite_math_only"
14341 {
14342 rtx_code_label *label = gen_label_rtx ();
14343
14344 rtx op1 = gen_reg_rtx (XFmode);
14345 rtx op2 = gen_reg_rtx (XFmode);
14346
14347 emit_move_insn (op2, operands[2]);
14348 emit_move_insn (op1, operands[1]);
14349
14350 emit_label (label);
14351 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14352 ix86_emit_fp_unordered_jump (label);
14353 LABEL_NUSES (label) = 1;
14354
14355 emit_move_insn (operands[0], op1);
14356 DONE;
14357 })
14358
14359 (define_expand "fmod<mode>3"
14360 [(use (match_operand:MODEF 0 "register_operand"))
14361 (use (match_operand:MODEF 1 "general_operand"))
14362 (use (match_operand:MODEF 2 "general_operand"))]
14363 "TARGET_USE_FANCY_MATH_387
14364 && flag_finite_math_only"
14365 {
14366 rtx (*gen_truncxf) (rtx, rtx);
14367
14368 rtx_code_label *label = gen_label_rtx ();
14369
14370 rtx op1 = gen_reg_rtx (XFmode);
14371 rtx op2 = gen_reg_rtx (XFmode);
14372
14373 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14374 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14375
14376 emit_label (label);
14377 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14378 ix86_emit_fp_unordered_jump (label);
14379 LABEL_NUSES (label) = 1;
14380
14381 /* Truncate the result properly for strict SSE math. */
14382 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14383 && !TARGET_MIX_SSE_I387)
14384 gen_truncxf = gen_truncxf<mode>2;
14385 else
14386 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14387
14388 emit_insn (gen_truncxf (operands[0], op1));
14389 DONE;
14390 })
14391
14392 (define_insn "fprem1xf4_i387"
14393 [(set (match_operand:XF 0 "register_operand" "=f")
14394 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14395 (match_operand:XF 3 "register_operand" "1")]
14396 UNSPEC_FPREM1_F))
14397 (set (match_operand:XF 1 "register_operand" "=u")
14398 (unspec:XF [(match_dup 2) (match_dup 3)]
14399 UNSPEC_FPREM1_U))
14400 (set (reg:CCFP FPSR_REG)
14401 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14402 UNSPEC_C2_FLAG))]
14403 "TARGET_USE_FANCY_MATH_387
14404 && flag_finite_math_only"
14405 "fprem1"
14406 [(set_attr "type" "fpspc")
14407 (set_attr "znver1_decode" "vector")
14408 (set_attr "mode" "XF")])
14409
14410 (define_expand "remainderxf3"
14411 [(use (match_operand:XF 0 "register_operand"))
14412 (use (match_operand:XF 1 "general_operand"))
14413 (use (match_operand:XF 2 "general_operand"))]
14414 "TARGET_USE_FANCY_MATH_387
14415 && flag_finite_math_only"
14416 {
14417 rtx_code_label *label = gen_label_rtx ();
14418
14419 rtx op1 = gen_reg_rtx (XFmode);
14420 rtx op2 = gen_reg_rtx (XFmode);
14421
14422 emit_move_insn (op2, operands[2]);
14423 emit_move_insn (op1, operands[1]);
14424
14425 emit_label (label);
14426 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14427 ix86_emit_fp_unordered_jump (label);
14428 LABEL_NUSES (label) = 1;
14429
14430 emit_move_insn (operands[0], op1);
14431 DONE;
14432 })
14433
14434 (define_expand "remainder<mode>3"
14435 [(use (match_operand:MODEF 0 "register_operand"))
14436 (use (match_operand:MODEF 1 "general_operand"))
14437 (use (match_operand:MODEF 2 "general_operand"))]
14438 "TARGET_USE_FANCY_MATH_387
14439 && flag_finite_math_only"
14440 {
14441 rtx (*gen_truncxf) (rtx, rtx);
14442
14443 rtx_code_label *label = gen_label_rtx ();
14444
14445 rtx op1 = gen_reg_rtx (XFmode);
14446 rtx op2 = gen_reg_rtx (XFmode);
14447
14448 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14449 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14450
14451 emit_label (label);
14452
14453 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14454 ix86_emit_fp_unordered_jump (label);
14455 LABEL_NUSES (label) = 1;
14456
14457 /* Truncate the result properly for strict SSE math. */
14458 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14459 && !TARGET_MIX_SSE_I387)
14460 gen_truncxf = gen_truncxf<mode>2;
14461 else
14462 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14463
14464 emit_insn (gen_truncxf (operands[0], op1));
14465 DONE;
14466 })
14467
14468 (define_int_iterator SINCOS
14469 [UNSPEC_SIN
14470 UNSPEC_COS])
14471
14472 (define_int_attr sincos
14473 [(UNSPEC_SIN "sin")
14474 (UNSPEC_COS "cos")])
14475
14476 (define_insn "*<sincos>xf2_i387"
14477 [(set (match_operand:XF 0 "register_operand" "=f")
14478 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14479 SINCOS))]
14480 "TARGET_USE_FANCY_MATH_387
14481 && flag_unsafe_math_optimizations"
14482 "f<sincos>"
14483 [(set_attr "type" "fpspc")
14484 (set_attr "znver1_decode" "vector")
14485 (set_attr "mode" "XF")])
14486
14487 (define_insn "*<sincos>_extend<mode>xf2_i387"
14488 [(set (match_operand:XF 0 "register_operand" "=f")
14489 (unspec:XF [(float_extend:XF
14490 (match_operand:MODEF 1 "register_operand" "0"))]
14491 SINCOS))]
14492 "TARGET_USE_FANCY_MATH_387
14493 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14494 || TARGET_MIX_SSE_I387)
14495 && flag_unsafe_math_optimizations"
14496 "f<sincos>"
14497 [(set_attr "type" "fpspc")
14498 (set_attr "znver1_decode" "vector")
14499 (set_attr "mode" "XF")])
14500
14501 ;; When sincos pattern is defined, sin and cos builtin functions will be
14502 ;; expanded to sincos pattern with one of its outputs left unused.
14503 ;; CSE pass will figure out if two sincos patterns can be combined,
14504 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14505 ;; depending on the unused output.
14506
14507 (define_insn "sincosxf3"
14508 [(set (match_operand:XF 0 "register_operand" "=f")
14509 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14510 UNSPEC_SINCOS_COS))
14511 (set (match_operand:XF 1 "register_operand" "=u")
14512 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14513 "TARGET_USE_FANCY_MATH_387
14514 && flag_unsafe_math_optimizations"
14515 "fsincos"
14516 [(set_attr "type" "fpspc")
14517 (set_attr "znver1_decode" "vector")
14518 (set_attr "mode" "XF")])
14519
14520 (define_split
14521 [(set (match_operand:XF 0 "register_operand")
14522 (unspec:XF [(match_operand:XF 2 "register_operand")]
14523 UNSPEC_SINCOS_COS))
14524 (set (match_operand:XF 1 "register_operand")
14525 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14526 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14527 && can_create_pseudo_p ()"
14528 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14529
14530 (define_split
14531 [(set (match_operand:XF 0 "register_operand")
14532 (unspec:XF [(match_operand:XF 2 "register_operand")]
14533 UNSPEC_SINCOS_COS))
14534 (set (match_operand:XF 1 "register_operand")
14535 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14536 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14537 && can_create_pseudo_p ()"
14538 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14539
14540 (define_insn "sincos_extend<mode>xf3_i387"
14541 [(set (match_operand:XF 0 "register_operand" "=f")
14542 (unspec:XF [(float_extend:XF
14543 (match_operand:MODEF 2 "register_operand" "0"))]
14544 UNSPEC_SINCOS_COS))
14545 (set (match_operand:XF 1 "register_operand" "=u")
14546 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14547 "TARGET_USE_FANCY_MATH_387
14548 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14549 || TARGET_MIX_SSE_I387)
14550 && flag_unsafe_math_optimizations"
14551 "fsincos"
14552 [(set_attr "type" "fpspc")
14553 (set_attr "znver1_decode" "vector")
14554 (set_attr "mode" "XF")])
14555
14556 (define_split
14557 [(set (match_operand:XF 0 "register_operand")
14558 (unspec:XF [(float_extend:XF
14559 (match_operand:MODEF 2 "register_operand"))]
14560 UNSPEC_SINCOS_COS))
14561 (set (match_operand:XF 1 "register_operand")
14562 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14563 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14564 && can_create_pseudo_p ()"
14565 [(set (match_dup 1)
14566 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14567
14568 (define_split
14569 [(set (match_operand:XF 0 "register_operand")
14570 (unspec:XF [(float_extend:XF
14571 (match_operand:MODEF 2 "register_operand"))]
14572 UNSPEC_SINCOS_COS))
14573 (set (match_operand:XF 1 "register_operand")
14574 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14575 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14576 && can_create_pseudo_p ()"
14577 [(set (match_dup 0)
14578 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14579
14580 (define_expand "sincos<mode>3"
14581 [(use (match_operand:MODEF 0 "register_operand"))
14582 (use (match_operand:MODEF 1 "register_operand"))
14583 (use (match_operand:MODEF 2 "register_operand"))]
14584 "TARGET_USE_FANCY_MATH_387
14585 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14586 || TARGET_MIX_SSE_I387)
14587 && flag_unsafe_math_optimizations"
14588 {
14589 rtx op0 = gen_reg_rtx (XFmode);
14590 rtx op1 = gen_reg_rtx (XFmode);
14591
14592 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14593 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14594 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14595 DONE;
14596 })
14597
14598 (define_insn "fptanxf4_i387"
14599 [(set (match_operand:XF 0 "register_operand" "=f")
14600 (match_operand:XF 3 "const_double_operand" "F"))
14601 (set (match_operand:XF 1 "register_operand" "=u")
14602 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14603 UNSPEC_TAN))]
14604 "TARGET_USE_FANCY_MATH_387
14605 && flag_unsafe_math_optimizations
14606 && standard_80387_constant_p (operands[3]) == 2"
14607 "fptan"
14608 [(set_attr "type" "fpspc")
14609 (set_attr "znver1_decode" "vector")
14610 (set_attr "mode" "XF")])
14611
14612 (define_insn "fptan_extend<mode>xf4_i387"
14613 [(set (match_operand:MODEF 0 "register_operand" "=f")
14614 (match_operand:MODEF 3 "const_double_operand" "F"))
14615 (set (match_operand:XF 1 "register_operand" "=u")
14616 (unspec:XF [(float_extend:XF
14617 (match_operand:MODEF 2 "register_operand" "0"))]
14618 UNSPEC_TAN))]
14619 "TARGET_USE_FANCY_MATH_387
14620 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14621 || TARGET_MIX_SSE_I387)
14622 && flag_unsafe_math_optimizations
14623 && standard_80387_constant_p (operands[3]) == 2"
14624 "fptan"
14625 [(set_attr "type" "fpspc")
14626 (set_attr "znver1_decode" "vector")
14627 (set_attr "mode" "XF")])
14628
14629 (define_expand "tanxf2"
14630 [(use (match_operand:XF 0 "register_operand"))
14631 (use (match_operand:XF 1 "register_operand"))]
14632 "TARGET_USE_FANCY_MATH_387
14633 && flag_unsafe_math_optimizations"
14634 {
14635 rtx one = gen_reg_rtx (XFmode);
14636 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14637
14638 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14639 DONE;
14640 })
14641
14642 (define_expand "tan<mode>2"
14643 [(use (match_operand:MODEF 0 "register_operand"))
14644 (use (match_operand:MODEF 1 "register_operand"))]
14645 "TARGET_USE_FANCY_MATH_387
14646 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14647 || TARGET_MIX_SSE_I387)
14648 && flag_unsafe_math_optimizations"
14649 {
14650 rtx op0 = gen_reg_rtx (XFmode);
14651
14652 rtx one = gen_reg_rtx (<MODE>mode);
14653 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14654
14655 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14656 operands[1], op2));
14657 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14658 DONE;
14659 })
14660
14661 (define_insn "*fpatanxf3_i387"
14662 [(set (match_operand:XF 0 "register_operand" "=f")
14663 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14664 (match_operand:XF 2 "register_operand" "u")]
14665 UNSPEC_FPATAN))
14666 (clobber (match_scratch:XF 3 "=2"))]
14667 "TARGET_USE_FANCY_MATH_387
14668 && flag_unsafe_math_optimizations"
14669 "fpatan"
14670 [(set_attr "type" "fpspc")
14671 (set_attr "znver1_decode" "vector")
14672 (set_attr "mode" "XF")])
14673
14674 (define_insn "fpatan_extend<mode>xf3_i387"
14675 [(set (match_operand:XF 0 "register_operand" "=f")
14676 (unspec:XF [(float_extend:XF
14677 (match_operand:MODEF 1 "register_operand" "0"))
14678 (float_extend:XF
14679 (match_operand:MODEF 2 "register_operand" "u"))]
14680 UNSPEC_FPATAN))
14681 (clobber (match_scratch:XF 3 "=2"))]
14682 "TARGET_USE_FANCY_MATH_387
14683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14684 || TARGET_MIX_SSE_I387)
14685 && flag_unsafe_math_optimizations"
14686 "fpatan"
14687 [(set_attr "type" "fpspc")
14688 (set_attr "znver1_decode" "vector")
14689 (set_attr "mode" "XF")])
14690
14691 (define_expand "atan2xf3"
14692 [(parallel [(set (match_operand:XF 0 "register_operand")
14693 (unspec:XF [(match_operand:XF 2 "register_operand")
14694 (match_operand:XF 1 "register_operand")]
14695 UNSPEC_FPATAN))
14696 (clobber (match_scratch:XF 3))])]
14697 "TARGET_USE_FANCY_MATH_387
14698 && flag_unsafe_math_optimizations")
14699
14700 (define_expand "atan2<mode>3"
14701 [(use (match_operand:MODEF 0 "register_operand"))
14702 (use (match_operand:MODEF 1 "register_operand"))
14703 (use (match_operand:MODEF 2 "register_operand"))]
14704 "TARGET_USE_FANCY_MATH_387
14705 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14706 || TARGET_MIX_SSE_I387)
14707 && flag_unsafe_math_optimizations"
14708 {
14709 rtx op0 = gen_reg_rtx (XFmode);
14710
14711 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14712 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14713 DONE;
14714 })
14715
14716 (define_expand "atanxf2"
14717 [(parallel [(set (match_operand:XF 0 "register_operand")
14718 (unspec:XF [(match_dup 2)
14719 (match_operand:XF 1 "register_operand")]
14720 UNSPEC_FPATAN))
14721 (clobber (match_scratch:XF 3))])]
14722 "TARGET_USE_FANCY_MATH_387
14723 && flag_unsafe_math_optimizations"
14724 {
14725 operands[2] = gen_reg_rtx (XFmode);
14726 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14727 })
14728
14729 (define_expand "atan<mode>2"
14730 [(use (match_operand:MODEF 0 "register_operand"))
14731 (use (match_operand:MODEF 1 "register_operand"))]
14732 "TARGET_USE_FANCY_MATH_387
14733 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14734 || TARGET_MIX_SSE_I387)
14735 && flag_unsafe_math_optimizations"
14736 {
14737 rtx op0 = gen_reg_rtx (XFmode);
14738
14739 rtx op2 = gen_reg_rtx (<MODE>mode);
14740 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14741
14742 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14744 DONE;
14745 })
14746
14747 (define_expand "asinxf2"
14748 [(set (match_dup 2)
14749 (mult:XF (match_operand:XF 1 "register_operand")
14750 (match_dup 1)))
14751 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14752 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14753 (parallel [(set (match_operand:XF 0 "register_operand")
14754 (unspec:XF [(match_dup 5) (match_dup 1)]
14755 UNSPEC_FPATAN))
14756 (clobber (match_scratch:XF 6))])]
14757 "TARGET_USE_FANCY_MATH_387
14758 && flag_unsafe_math_optimizations"
14759 {
14760 int i;
14761
14762 for (i = 2; i < 6; i++)
14763 operands[i] = gen_reg_rtx (XFmode);
14764
14765 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14766 })
14767
14768 (define_expand "asin<mode>2"
14769 [(use (match_operand:MODEF 0 "register_operand"))
14770 (use (match_operand:MODEF 1 "general_operand"))]
14771 "TARGET_USE_FANCY_MATH_387
14772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14773 || TARGET_MIX_SSE_I387)
14774 && flag_unsafe_math_optimizations"
14775 {
14776 rtx op0 = gen_reg_rtx (XFmode);
14777 rtx op1 = gen_reg_rtx (XFmode);
14778
14779 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14780 emit_insn (gen_asinxf2 (op0, op1));
14781 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14782 DONE;
14783 })
14784
14785 (define_expand "acosxf2"
14786 [(set (match_dup 2)
14787 (mult:XF (match_operand:XF 1 "register_operand")
14788 (match_dup 1)))
14789 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14790 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14791 (parallel [(set (match_operand:XF 0 "register_operand")
14792 (unspec:XF [(match_dup 1) (match_dup 5)]
14793 UNSPEC_FPATAN))
14794 (clobber (match_scratch:XF 6))])]
14795 "TARGET_USE_FANCY_MATH_387
14796 && flag_unsafe_math_optimizations"
14797 {
14798 int i;
14799
14800 for (i = 2; i < 6; i++)
14801 operands[i] = gen_reg_rtx (XFmode);
14802
14803 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14804 })
14805
14806 (define_expand "acos<mode>2"
14807 [(use (match_operand:MODEF 0 "register_operand"))
14808 (use (match_operand:MODEF 1 "general_operand"))]
14809 "TARGET_USE_FANCY_MATH_387
14810 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14811 || TARGET_MIX_SSE_I387)
14812 && flag_unsafe_math_optimizations"
14813 {
14814 rtx op0 = gen_reg_rtx (XFmode);
14815 rtx op1 = gen_reg_rtx (XFmode);
14816
14817 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14818 emit_insn (gen_acosxf2 (op0, op1));
14819 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14820 DONE;
14821 })
14822
14823 (define_insn "fyl2xxf3_i387"
14824 [(set (match_operand:XF 0 "register_operand" "=f")
14825 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14826 (match_operand:XF 2 "register_operand" "u")]
14827 UNSPEC_FYL2X))
14828 (clobber (match_scratch:XF 3 "=2"))]
14829 "TARGET_USE_FANCY_MATH_387
14830 && flag_unsafe_math_optimizations"
14831 "fyl2x"
14832 [(set_attr "type" "fpspc")
14833 (set_attr "znver1_decode" "vector")
14834 (set_attr "mode" "XF")])
14835
14836 (define_insn "fyl2x_extend<mode>xf3_i387"
14837 [(set (match_operand:XF 0 "register_operand" "=f")
14838 (unspec:XF [(float_extend:XF
14839 (match_operand:MODEF 1 "register_operand" "0"))
14840 (match_operand:XF 2 "register_operand" "u")]
14841 UNSPEC_FYL2X))
14842 (clobber (match_scratch:XF 3 "=2"))]
14843 "TARGET_USE_FANCY_MATH_387
14844 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14845 || TARGET_MIX_SSE_I387)
14846 && flag_unsafe_math_optimizations"
14847 "fyl2x"
14848 [(set_attr "type" "fpspc")
14849 (set_attr "znver1_decode" "vector")
14850 (set_attr "mode" "XF")])
14851
14852 (define_expand "logxf2"
14853 [(parallel [(set (match_operand:XF 0 "register_operand")
14854 (unspec:XF [(match_operand:XF 1 "register_operand")
14855 (match_dup 2)] UNSPEC_FYL2X))
14856 (clobber (match_scratch:XF 3))])]
14857 "TARGET_USE_FANCY_MATH_387
14858 && flag_unsafe_math_optimizations"
14859 {
14860 operands[2] = gen_reg_rtx (XFmode);
14861 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14862 })
14863
14864 (define_expand "log<mode>2"
14865 [(use (match_operand:MODEF 0 "register_operand"))
14866 (use (match_operand:MODEF 1 "register_operand"))]
14867 "TARGET_USE_FANCY_MATH_387
14868 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14869 || TARGET_MIX_SSE_I387)
14870 && flag_unsafe_math_optimizations"
14871 {
14872 rtx op0 = gen_reg_rtx (XFmode);
14873
14874 rtx op2 = gen_reg_rtx (XFmode);
14875 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14876
14877 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14878 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14879 DONE;
14880 })
14881
14882 (define_expand "log10xf2"
14883 [(parallel [(set (match_operand:XF 0 "register_operand")
14884 (unspec:XF [(match_operand:XF 1 "register_operand")
14885 (match_dup 2)] UNSPEC_FYL2X))
14886 (clobber (match_scratch:XF 3))])]
14887 "TARGET_USE_FANCY_MATH_387
14888 && flag_unsafe_math_optimizations"
14889 {
14890 operands[2] = gen_reg_rtx (XFmode);
14891 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14892 })
14893
14894 (define_expand "log10<mode>2"
14895 [(use (match_operand:MODEF 0 "register_operand"))
14896 (use (match_operand:MODEF 1 "register_operand"))]
14897 "TARGET_USE_FANCY_MATH_387
14898 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14899 || TARGET_MIX_SSE_I387)
14900 && flag_unsafe_math_optimizations"
14901 {
14902 rtx op0 = gen_reg_rtx (XFmode);
14903
14904 rtx op2 = gen_reg_rtx (XFmode);
14905 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14906
14907 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14908 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14909 DONE;
14910 })
14911
14912 (define_expand "log2xf2"
14913 [(parallel [(set (match_operand:XF 0 "register_operand")
14914 (unspec:XF [(match_operand:XF 1 "register_operand")
14915 (match_dup 2)] UNSPEC_FYL2X))
14916 (clobber (match_scratch:XF 3))])]
14917 "TARGET_USE_FANCY_MATH_387
14918 && flag_unsafe_math_optimizations"
14919 {
14920 operands[2] = gen_reg_rtx (XFmode);
14921 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14922 })
14923
14924 (define_expand "log2<mode>2"
14925 [(use (match_operand:MODEF 0 "register_operand"))
14926 (use (match_operand:MODEF 1 "register_operand"))]
14927 "TARGET_USE_FANCY_MATH_387
14928 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14929 || TARGET_MIX_SSE_I387)
14930 && flag_unsafe_math_optimizations"
14931 {
14932 rtx op0 = gen_reg_rtx (XFmode);
14933
14934 rtx op2 = gen_reg_rtx (XFmode);
14935 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14936
14937 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14938 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14939 DONE;
14940 })
14941
14942 (define_insn "fyl2xp1xf3_i387"
14943 [(set (match_operand:XF 0 "register_operand" "=f")
14944 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14945 (match_operand:XF 2 "register_operand" "u")]
14946 UNSPEC_FYL2XP1))
14947 (clobber (match_scratch:XF 3 "=2"))]
14948 "TARGET_USE_FANCY_MATH_387
14949 && flag_unsafe_math_optimizations"
14950 "fyl2xp1"
14951 [(set_attr "type" "fpspc")
14952 (set_attr "znver1_decode" "vector")
14953 (set_attr "mode" "XF")])
14954
14955 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14956 [(set (match_operand:XF 0 "register_operand" "=f")
14957 (unspec:XF [(float_extend:XF
14958 (match_operand:MODEF 1 "register_operand" "0"))
14959 (match_operand:XF 2 "register_operand" "u")]
14960 UNSPEC_FYL2XP1))
14961 (clobber (match_scratch:XF 3 "=2"))]
14962 "TARGET_USE_FANCY_MATH_387
14963 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14964 || TARGET_MIX_SSE_I387)
14965 && flag_unsafe_math_optimizations"
14966 "fyl2xp1"
14967 [(set_attr "type" "fpspc")
14968 (set_attr "znver1_decode" "vector")
14969 (set_attr "mode" "XF")])
14970
14971 (define_expand "log1pxf2"
14972 [(use (match_operand:XF 0 "register_operand"))
14973 (use (match_operand:XF 1 "register_operand"))]
14974 "TARGET_USE_FANCY_MATH_387
14975 && flag_unsafe_math_optimizations"
14976 {
14977 ix86_emit_i387_log1p (operands[0], operands[1]);
14978 DONE;
14979 })
14980
14981 (define_expand "log1p<mode>2"
14982 [(use (match_operand:MODEF 0 "register_operand"))
14983 (use (match_operand:MODEF 1 "register_operand"))]
14984 "TARGET_USE_FANCY_MATH_387
14985 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14986 || TARGET_MIX_SSE_I387)
14987 && flag_unsafe_math_optimizations"
14988 {
14989 rtx op0;
14990
14991 op0 = gen_reg_rtx (XFmode);
14992
14993 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14994
14995 ix86_emit_i387_log1p (op0, operands[1]);
14996 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14997 DONE;
14998 })
14999
15000 (define_insn "fxtractxf3_i387"
15001 [(set (match_operand:XF 0 "register_operand" "=f")
15002 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15003 UNSPEC_XTRACT_FRACT))
15004 (set (match_operand:XF 1 "register_operand" "=u")
15005 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15006 "TARGET_USE_FANCY_MATH_387
15007 && flag_unsafe_math_optimizations"
15008 "fxtract"
15009 [(set_attr "type" "fpspc")
15010 (set_attr "znver1_decode" "vector")
15011 (set_attr "mode" "XF")])
15012
15013 (define_insn "fxtract_extend<mode>xf3_i387"
15014 [(set (match_operand:XF 0 "register_operand" "=f")
15015 (unspec:XF [(float_extend:XF
15016 (match_operand:MODEF 2 "register_operand" "0"))]
15017 UNSPEC_XTRACT_FRACT))
15018 (set (match_operand:XF 1 "register_operand" "=u")
15019 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15020 "TARGET_USE_FANCY_MATH_387
15021 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15022 || TARGET_MIX_SSE_I387)
15023 && flag_unsafe_math_optimizations"
15024 "fxtract"
15025 [(set_attr "type" "fpspc")
15026 (set_attr "znver1_decode" "vector")
15027 (set_attr "mode" "XF")])
15028
15029 (define_expand "logbxf2"
15030 [(parallel [(set (match_dup 2)
15031 (unspec:XF [(match_operand:XF 1 "register_operand")]
15032 UNSPEC_XTRACT_FRACT))
15033 (set (match_operand:XF 0 "register_operand")
15034 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15035 "TARGET_USE_FANCY_MATH_387
15036 && flag_unsafe_math_optimizations"
15037 "operands[2] = gen_reg_rtx (XFmode);")
15038
15039 (define_expand "logb<mode>2"
15040 [(use (match_operand:MODEF 0 "register_operand"))
15041 (use (match_operand:MODEF 1 "register_operand"))]
15042 "TARGET_USE_FANCY_MATH_387
15043 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15044 || TARGET_MIX_SSE_I387)
15045 && flag_unsafe_math_optimizations"
15046 {
15047 rtx op0 = gen_reg_rtx (XFmode);
15048 rtx op1 = gen_reg_rtx (XFmode);
15049
15050 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15051 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15052 DONE;
15053 })
15054
15055 (define_expand "ilogbxf2"
15056 [(use (match_operand:SI 0 "register_operand"))
15057 (use (match_operand:XF 1 "register_operand"))]
15058 "TARGET_USE_FANCY_MATH_387
15059 && flag_unsafe_math_optimizations"
15060 {
15061 rtx op0, op1;
15062
15063 if (optimize_insn_for_size_p ())
15064 FAIL;
15065
15066 op0 = gen_reg_rtx (XFmode);
15067 op1 = gen_reg_rtx (XFmode);
15068
15069 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15070 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15071 DONE;
15072 })
15073
15074 (define_expand "ilogb<mode>2"
15075 [(use (match_operand:SI 0 "register_operand"))
15076 (use (match_operand:MODEF 1 "register_operand"))]
15077 "TARGET_USE_FANCY_MATH_387
15078 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15079 || TARGET_MIX_SSE_I387)
15080 && flag_unsafe_math_optimizations"
15081 {
15082 rtx op0, op1;
15083
15084 if (optimize_insn_for_size_p ())
15085 FAIL;
15086
15087 op0 = gen_reg_rtx (XFmode);
15088 op1 = gen_reg_rtx (XFmode);
15089
15090 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15091 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15092 DONE;
15093 })
15094
15095 (define_insn "*f2xm1xf2_i387"
15096 [(set (match_operand:XF 0 "register_operand" "=f")
15097 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15098 UNSPEC_F2XM1))]
15099 "TARGET_USE_FANCY_MATH_387
15100 && flag_unsafe_math_optimizations"
15101 "f2xm1"
15102 [(set_attr "type" "fpspc")
15103 (set_attr "znver1_decode" "vector")
15104 (set_attr "mode" "XF")])
15105
15106 (define_insn "fscalexf4_i387"
15107 [(set (match_operand:XF 0 "register_operand" "=f")
15108 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15109 (match_operand:XF 3 "register_operand" "1")]
15110 UNSPEC_FSCALE_FRACT))
15111 (set (match_operand:XF 1 "register_operand" "=u")
15112 (unspec:XF [(match_dup 2) (match_dup 3)]
15113 UNSPEC_FSCALE_EXP))]
15114 "TARGET_USE_FANCY_MATH_387
15115 && flag_unsafe_math_optimizations"
15116 "fscale"
15117 [(set_attr "type" "fpspc")
15118 (set_attr "znver1_decode" "vector")
15119 (set_attr "mode" "XF")])
15120
15121 (define_expand "expNcorexf3"
15122 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15123 (match_operand:XF 2 "register_operand")))
15124 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15125 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15126 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15127 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15128 (parallel [(set (match_operand:XF 0 "register_operand")
15129 (unspec:XF [(match_dup 8) (match_dup 4)]
15130 UNSPEC_FSCALE_FRACT))
15131 (set (match_dup 9)
15132 (unspec:XF [(match_dup 8) (match_dup 4)]
15133 UNSPEC_FSCALE_EXP))])]
15134 "TARGET_USE_FANCY_MATH_387
15135 && flag_unsafe_math_optimizations"
15136 {
15137 int i;
15138
15139 for (i = 3; i < 10; i++)
15140 operands[i] = gen_reg_rtx (XFmode);
15141
15142 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15143 })
15144
15145 (define_expand "expxf2"
15146 [(use (match_operand:XF 0 "register_operand"))
15147 (use (match_operand:XF 1 "register_operand"))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && flag_unsafe_math_optimizations"
15150 {
15151 rtx op2;
15152
15153 op2 = gen_reg_rtx (XFmode);
15154 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15155
15156 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15157 DONE;
15158 })
15159
15160 (define_expand "exp<mode>2"
15161 [(use (match_operand:MODEF 0 "register_operand"))
15162 (use (match_operand:MODEF 1 "general_operand"))]
15163 "TARGET_USE_FANCY_MATH_387
15164 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15165 || TARGET_MIX_SSE_I387)
15166 && flag_unsafe_math_optimizations"
15167 {
15168 rtx op0, op1;
15169
15170 op0 = gen_reg_rtx (XFmode);
15171 op1 = gen_reg_rtx (XFmode);
15172
15173 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15174 emit_insn (gen_expxf2 (op0, op1));
15175 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15176 DONE;
15177 })
15178
15179 (define_expand "exp10xf2"
15180 [(use (match_operand:XF 0 "register_operand"))
15181 (use (match_operand:XF 1 "register_operand"))]
15182 "TARGET_USE_FANCY_MATH_387
15183 && flag_unsafe_math_optimizations"
15184 {
15185 rtx op2;
15186
15187 op2 = gen_reg_rtx (XFmode);
15188 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15189
15190 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15191 DONE;
15192 })
15193
15194 (define_expand "exp10<mode>2"
15195 [(use (match_operand:MODEF 0 "register_operand"))
15196 (use (match_operand:MODEF 1 "general_operand"))]
15197 "TARGET_USE_FANCY_MATH_387
15198 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15199 || TARGET_MIX_SSE_I387)
15200 && flag_unsafe_math_optimizations"
15201 {
15202 rtx op0, op1;
15203
15204 op0 = gen_reg_rtx (XFmode);
15205 op1 = gen_reg_rtx (XFmode);
15206
15207 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15208 emit_insn (gen_exp10xf2 (op0, op1));
15209 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15210 DONE;
15211 })
15212
15213 (define_expand "exp2xf2"
15214 [(use (match_operand:XF 0 "register_operand"))
15215 (use (match_operand:XF 1 "register_operand"))]
15216 "TARGET_USE_FANCY_MATH_387
15217 && flag_unsafe_math_optimizations"
15218 {
15219 rtx op2;
15220
15221 op2 = gen_reg_rtx (XFmode);
15222 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15223
15224 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15225 DONE;
15226 })
15227
15228 (define_expand "exp2<mode>2"
15229 [(use (match_operand:MODEF 0 "register_operand"))
15230 (use (match_operand:MODEF 1 "general_operand"))]
15231 "TARGET_USE_FANCY_MATH_387
15232 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15233 || TARGET_MIX_SSE_I387)
15234 && flag_unsafe_math_optimizations"
15235 {
15236 rtx op0, op1;
15237
15238 op0 = gen_reg_rtx (XFmode);
15239 op1 = gen_reg_rtx (XFmode);
15240
15241 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15242 emit_insn (gen_exp2xf2 (op0, op1));
15243 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15244 DONE;
15245 })
15246
15247 (define_expand "expm1xf2"
15248 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15249 (match_dup 2)))
15250 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15251 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15252 (set (match_dup 9) (float_extend:XF (match_dup 13)))
15253 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15254 (parallel [(set (match_dup 7)
15255 (unspec:XF [(match_dup 6) (match_dup 4)]
15256 UNSPEC_FSCALE_FRACT))
15257 (set (match_dup 8)
15258 (unspec:XF [(match_dup 6) (match_dup 4)]
15259 UNSPEC_FSCALE_EXP))])
15260 (parallel [(set (match_dup 10)
15261 (unspec:XF [(match_dup 9) (match_dup 8)]
15262 UNSPEC_FSCALE_FRACT))
15263 (set (match_dup 11)
15264 (unspec:XF [(match_dup 9) (match_dup 8)]
15265 UNSPEC_FSCALE_EXP))])
15266 (set (match_dup 12) (minus:XF (match_dup 10)
15267 (float_extend:XF (match_dup 13))))
15268 (set (match_operand:XF 0 "register_operand")
15269 (plus:XF (match_dup 12) (match_dup 7)))]
15270 "TARGET_USE_FANCY_MATH_387
15271 && flag_unsafe_math_optimizations"
15272 {
15273 int i;
15274
15275 for (i = 2; i < 13; i++)
15276 operands[i] = gen_reg_rtx (XFmode);
15277
15278 operands[13]
15279 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15280
15281 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15282 })
15283
15284 (define_expand "expm1<mode>2"
15285 [(use (match_operand:MODEF 0 "register_operand"))
15286 (use (match_operand:MODEF 1 "general_operand"))]
15287 "TARGET_USE_FANCY_MATH_387
15288 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15289 || TARGET_MIX_SSE_I387)
15290 && flag_unsafe_math_optimizations"
15291 {
15292 rtx op0, op1;
15293
15294 op0 = gen_reg_rtx (XFmode);
15295 op1 = gen_reg_rtx (XFmode);
15296
15297 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15298 emit_insn (gen_expm1xf2 (op0, op1));
15299 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15300 DONE;
15301 })
15302
15303 (define_expand "ldexpxf3"
15304 [(match_operand:XF 0 "register_operand")
15305 (match_operand:XF 1 "register_operand")
15306 (match_operand:SI 2 "register_operand")]
15307 "TARGET_USE_FANCY_MATH_387
15308 && flag_unsafe_math_optimizations"
15309 {
15310 rtx tmp1, tmp2;
15311
15312 tmp1 = gen_reg_rtx (XFmode);
15313 tmp2 = gen_reg_rtx (XFmode);
15314
15315 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15316 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15317 operands[1], tmp1));
15318 DONE;
15319 })
15320
15321 (define_expand "ldexp<mode>3"
15322 [(use (match_operand:MODEF 0 "register_operand"))
15323 (use (match_operand:MODEF 1 "general_operand"))
15324 (use (match_operand:SI 2 "register_operand"))]
15325 "TARGET_USE_FANCY_MATH_387
15326 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15327 || TARGET_MIX_SSE_I387)
15328 && flag_unsafe_math_optimizations"
15329 {
15330 rtx op0, op1;
15331
15332 op0 = gen_reg_rtx (XFmode);
15333 op1 = gen_reg_rtx (XFmode);
15334
15335 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15336 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15337 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15338 DONE;
15339 })
15340
15341 (define_expand "scalbxf3"
15342 [(parallel [(set (match_operand:XF 0 " register_operand")
15343 (unspec:XF [(match_operand:XF 1 "register_operand")
15344 (match_operand:XF 2 "register_operand")]
15345 UNSPEC_FSCALE_FRACT))
15346 (set (match_dup 3)
15347 (unspec:XF [(match_dup 1) (match_dup 2)]
15348 UNSPEC_FSCALE_EXP))])]
15349 "TARGET_USE_FANCY_MATH_387
15350 && flag_unsafe_math_optimizations"
15351 {
15352 operands[3] = gen_reg_rtx (XFmode);
15353 })
15354
15355 (define_expand "scalb<mode>3"
15356 [(use (match_operand:MODEF 0 "register_operand"))
15357 (use (match_operand:MODEF 1 "general_operand"))
15358 (use (match_operand:MODEF 2 "general_operand"))]
15359 "TARGET_USE_FANCY_MATH_387
15360 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15361 || TARGET_MIX_SSE_I387)
15362 && flag_unsafe_math_optimizations"
15363 {
15364 rtx op0, op1, op2;
15365
15366 op0 = gen_reg_rtx (XFmode);
15367 op1 = gen_reg_rtx (XFmode);
15368 op2 = gen_reg_rtx (XFmode);
15369
15370 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15371 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15372 emit_insn (gen_scalbxf3 (op0, op1, op2));
15373 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15374 DONE;
15375 })
15376
15377 (define_expand "significandxf2"
15378 [(parallel [(set (match_operand:XF 0 "register_operand")
15379 (unspec:XF [(match_operand:XF 1 "register_operand")]
15380 UNSPEC_XTRACT_FRACT))
15381 (set (match_dup 2)
15382 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15383 "TARGET_USE_FANCY_MATH_387
15384 && flag_unsafe_math_optimizations"
15385 "operands[2] = gen_reg_rtx (XFmode);")
15386
15387 (define_expand "significand<mode>2"
15388 [(use (match_operand:MODEF 0 "register_operand"))
15389 (use (match_operand:MODEF 1 "register_operand"))]
15390 "TARGET_USE_FANCY_MATH_387
15391 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15392 || TARGET_MIX_SSE_I387)
15393 && flag_unsafe_math_optimizations"
15394 {
15395 rtx op0 = gen_reg_rtx (XFmode);
15396 rtx op1 = gen_reg_rtx (XFmode);
15397
15398 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15399 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15400 DONE;
15401 })
15402 \f
15403
15404 (define_insn "sse4_1_round<mode>2"
15405 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
15406 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
15407 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
15408 UNSPEC_ROUND))]
15409 "TARGET_ROUND"
15410 "@
15411 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
15412 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15413 [(set_attr "type" "ssecvt")
15414 (set_attr "prefix_extra" "1,*")
15415 (set_attr "length_immediate" "*,1")
15416 (set_attr "prefix" "maybe_vex,evex")
15417 (set_attr "isa" "noavx512f,avx512f")
15418 (set_attr "mode" "<MODE>")])
15419
15420 (define_insn "rintxf2"
15421 [(set (match_operand:XF 0 "register_operand" "=f")
15422 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15423 UNSPEC_FRNDINT))]
15424 "TARGET_USE_FANCY_MATH_387"
15425 "frndint"
15426 [(set_attr "type" "fpspc")
15427 (set_attr "znver1_decode" "vector")
15428 (set_attr "mode" "XF")])
15429
15430 (define_insn "rint<mode>2_frndint"
15431 [(set (match_operand:MODEF 0 "register_operand" "=f")
15432 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
15433 UNSPEC_FRNDINT))]
15434 "TARGET_USE_FANCY_MATH_387"
15435 "frndint"
15436 [(set_attr "type" "fpspc")
15437 (set_attr "znver1_decode" "vector")
15438 (set_attr "mode" "<MODE>")])
15439
15440 (define_expand "rint<mode>2"
15441 [(use (match_operand:MODEF 0 "register_operand"))
15442 (use (match_operand:MODEF 1 "register_operand"))]
15443 "(TARGET_USE_FANCY_MATH_387
15444 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15445 || TARGET_MIX_SSE_I387))
15446 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15447 {
15448 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15449 {
15450 if (TARGET_ROUND)
15451 emit_insn (gen_sse4_1_round<mode>2
15452 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15453 else
15454 ix86_expand_rint (operands[0], operands[1]);
15455 }
15456 else
15457 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
15458 DONE;
15459 })
15460
15461 (define_expand "round<mode>2"
15462 [(match_operand:X87MODEF 0 "register_operand")
15463 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15464 "(TARGET_USE_FANCY_MATH_387
15465 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15466 || TARGET_MIX_SSE_I387)
15467 && flag_unsafe_math_optimizations)
15468 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15469 && !flag_trapping_math && !flag_rounding_math)"
15470 {
15471 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15472 && !flag_trapping_math && !flag_rounding_math)
15473 {
15474 if (TARGET_ROUND)
15475 {
15476 operands[1] = force_reg (<MODE>mode, operands[1]);
15477 ix86_expand_round_sse4 (operands[0], operands[1]);
15478 }
15479 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15480 ix86_expand_round (operands[0], operands[1]);
15481 else
15482 ix86_expand_rounddf_32 (operands[0], operands[1]);
15483 }
15484 else
15485 {
15486 operands[1] = force_reg (<MODE>mode, operands[1]);
15487 ix86_emit_i387_round (operands[0], operands[1]);
15488 }
15489 DONE;
15490 })
15491
15492 (define_insn_and_split "*fistdi2_1"
15493 [(set (match_operand:DI 0 "nonimmediate_operand")
15494 (unspec:DI [(match_operand:XF 1 "register_operand")]
15495 UNSPEC_FIST))]
15496 "TARGET_USE_FANCY_MATH_387
15497 && can_create_pseudo_p ()"
15498 "#"
15499 "&& 1"
15500 [(const_int 0)]
15501 {
15502 if (memory_operand (operands[0], VOIDmode))
15503 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15504 else
15505 {
15506 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15507 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15508 operands[2]));
15509 }
15510 DONE;
15511 }
15512 [(set_attr "type" "fpspc")
15513 (set_attr "mode" "DI")])
15514
15515 (define_insn "fistdi2"
15516 [(set (match_operand:DI 0 "memory_operand" "=m")
15517 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15518 UNSPEC_FIST))
15519 (clobber (match_scratch:XF 2 "=&1f"))]
15520 "TARGET_USE_FANCY_MATH_387"
15521 "* return output_fix_trunc (insn, operands, false);"
15522 [(set_attr "type" "fpspc")
15523 (set_attr "mode" "DI")])
15524
15525 (define_insn "fistdi2_with_temp"
15526 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15527 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15528 UNSPEC_FIST))
15529 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15530 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15531 "TARGET_USE_FANCY_MATH_387"
15532 "#"
15533 [(set_attr "type" "fpspc")
15534 (set_attr "mode" "DI")])
15535
15536 (define_split
15537 [(set (match_operand:DI 0 "register_operand")
15538 (unspec:DI [(match_operand:XF 1 "register_operand")]
15539 UNSPEC_FIST))
15540 (clobber (match_operand:DI 2 "memory_operand"))
15541 (clobber (match_scratch 3))]
15542 "reload_completed"
15543 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15544 (clobber (match_dup 3))])
15545 (set (match_dup 0) (match_dup 2))])
15546
15547 (define_split
15548 [(set (match_operand:DI 0 "memory_operand")
15549 (unspec:DI [(match_operand:XF 1 "register_operand")]
15550 UNSPEC_FIST))
15551 (clobber (match_operand:DI 2 "memory_operand"))
15552 (clobber (match_scratch 3))]
15553 "reload_completed"
15554 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15555 (clobber (match_dup 3))])])
15556
15557 (define_insn_and_split "*fist<mode>2_1"
15558 [(set (match_operand:SWI24 0 "register_operand")
15559 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15560 UNSPEC_FIST))]
15561 "TARGET_USE_FANCY_MATH_387
15562 && can_create_pseudo_p ()"
15563 "#"
15564 "&& 1"
15565 [(const_int 0)]
15566 {
15567 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15568 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15569 operands[2]));
15570 DONE;
15571 }
15572 [(set_attr "type" "fpspc")
15573 (set_attr "mode" "<MODE>")])
15574
15575 (define_insn "fist<mode>2"
15576 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15577 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15578 UNSPEC_FIST))]
15579 "TARGET_USE_FANCY_MATH_387"
15580 "* return output_fix_trunc (insn, operands, false);"
15581 [(set_attr "type" "fpspc")
15582 (set_attr "mode" "<MODE>")])
15583
15584 (define_insn "fist<mode>2_with_temp"
15585 [(set (match_operand:SWI24 0 "register_operand" "=r")
15586 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15587 UNSPEC_FIST))
15588 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15589 "TARGET_USE_FANCY_MATH_387"
15590 "#"
15591 [(set_attr "type" "fpspc")
15592 (set_attr "mode" "<MODE>")])
15593
15594 (define_split
15595 [(set (match_operand:SWI24 0 "register_operand")
15596 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15597 UNSPEC_FIST))
15598 (clobber (match_operand:SWI24 2 "memory_operand"))]
15599 "reload_completed"
15600 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15601 (set (match_dup 0) (match_dup 2))])
15602
15603 (define_split
15604 [(set (match_operand:SWI24 0 "memory_operand")
15605 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15606 UNSPEC_FIST))
15607 (clobber (match_operand:SWI24 2 "memory_operand"))]
15608 "reload_completed"
15609 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15610
15611 (define_expand "lrintxf<mode>2"
15612 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15613 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15614 UNSPEC_FIST))]
15615 "TARGET_USE_FANCY_MATH_387")
15616
15617 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15618 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15619 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15620 UNSPEC_FIX_NOTRUNC))]
15621 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15622
15623 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15624 [(match_operand:SWI248x 0 "nonimmediate_operand")
15625 (match_operand:X87MODEF 1 "register_operand")]
15626 "(TARGET_USE_FANCY_MATH_387
15627 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15628 || TARGET_MIX_SSE_I387)
15629 && flag_unsafe_math_optimizations)
15630 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15631 && <SWI248x:MODE>mode != HImode
15632 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15633 && !flag_trapping_math && !flag_rounding_math)"
15634 {
15635 if (optimize_insn_for_size_p ())
15636 FAIL;
15637
15638 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15639 && <SWI248x:MODE>mode != HImode
15640 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15641 && !flag_trapping_math && !flag_rounding_math)
15642 ix86_expand_lround (operands[0], operands[1]);
15643 else
15644 ix86_emit_i387_round (operands[0], operands[1]);
15645 DONE;
15646 })
15647
15648 (define_int_iterator FRNDINT_ROUNDING
15649 [UNSPEC_FRNDINT_FLOOR
15650 UNSPEC_FRNDINT_CEIL
15651 UNSPEC_FRNDINT_TRUNC])
15652
15653 (define_int_iterator FIST_ROUNDING
15654 [UNSPEC_FIST_FLOOR
15655 UNSPEC_FIST_CEIL])
15656
15657 ;; Base name for define_insn
15658 (define_int_attr rounding_insn
15659 [(UNSPEC_FRNDINT_FLOOR "floor")
15660 (UNSPEC_FRNDINT_CEIL "ceil")
15661 (UNSPEC_FRNDINT_TRUNC "btrunc")
15662 (UNSPEC_FIST_FLOOR "floor")
15663 (UNSPEC_FIST_CEIL "ceil")])
15664
15665 (define_int_attr rounding
15666 [(UNSPEC_FRNDINT_FLOOR "floor")
15667 (UNSPEC_FRNDINT_CEIL "ceil")
15668 (UNSPEC_FRNDINT_TRUNC "trunc")
15669 (UNSPEC_FIST_FLOOR "floor")
15670 (UNSPEC_FIST_CEIL "ceil")])
15671
15672 (define_int_attr ROUNDING
15673 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15674 (UNSPEC_FRNDINT_CEIL "CEIL")
15675 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15676 (UNSPEC_FIST_FLOOR "FLOOR")
15677 (UNSPEC_FIST_CEIL "CEIL")])
15678
15679 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15680 (define_insn_and_split "frndint<mode>2_<rounding>"
15681 [(set (match_operand:X87MODEF 0 "register_operand")
15682 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
15683 FRNDINT_ROUNDING))
15684 (clobber (reg:CC FLAGS_REG))]
15685 "TARGET_USE_FANCY_MATH_387
15686 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
15687 && can_create_pseudo_p ()"
15688 "#"
15689 "&& 1"
15690 [(const_int 0)]
15691 {
15692 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15693
15694 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15695 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15696
15697 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
15698 operands[2], operands[3]));
15699 DONE;
15700 }
15701 [(set_attr "type" "frndint")
15702 (set_attr "i387_cw" "<rounding>")
15703 (set_attr "mode" "<MODE>")])
15704
15705 (define_insn "frndint<mode>2_<rounding>_i387"
15706 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15707 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
15708 FRNDINT_ROUNDING))
15709 (use (match_operand:HI 2 "memory_operand" "m"))
15710 (use (match_operand:HI 3 "memory_operand" "m"))]
15711 "TARGET_USE_FANCY_MATH_387
15712 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
15713 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15714 [(set_attr "type" "frndint")
15715 (set_attr "i387_cw" "<rounding>")
15716 (set_attr "mode" "<MODE>")])
15717
15718 (define_expand "<rounding_insn>xf2"
15719 [(parallel [(set (match_operand:XF 0 "register_operand")
15720 (unspec:XF [(match_operand:XF 1 "register_operand")]
15721 FRNDINT_ROUNDING))
15722 (clobber (reg:CC FLAGS_REG))])]
15723 "TARGET_USE_FANCY_MATH_387
15724 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
15725
15726 (define_expand "<rounding_insn><mode>2"
15727 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15728 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15729 FRNDINT_ROUNDING))
15730 (clobber (reg:CC FLAGS_REG))])]
15731 "(TARGET_USE_FANCY_MATH_387
15732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15733 || TARGET_MIX_SSE_I387)
15734 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
15735 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15736 && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))"
15737 {
15738 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15739 && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))
15740 {
15741 if (TARGET_ROUND)
15742 emit_insn (gen_sse4_1_round<mode>2
15743 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
15744 | ROUND_NO_EXC)));
15745 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15746 {
15747 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15748 ix86_expand_floorceil (operands[0], operands[1], true);
15749 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15750 ix86_expand_floorceil (operands[0], operands[1], false);
15751 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15752 ix86_expand_trunc (operands[0], operands[1]);
15753 else
15754 gcc_unreachable ();
15755 }
15756 else
15757 {
15758 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15759 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15760 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15761 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15762 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15763 ix86_expand_truncdf_32 (operands[0], operands[1]);
15764 else
15765 gcc_unreachable ();
15766 }
15767 }
15768 else
15769 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
15770 DONE;
15771 })
15772
15773 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15774 (define_insn_and_split "frndintxf2_mask_pm"
15775 [(set (match_operand:XF 0 "register_operand")
15776 (unspec:XF [(match_operand:XF 1 "register_operand")]
15777 UNSPEC_FRNDINT_MASK_PM))
15778 (clobber (reg:CC FLAGS_REG))]
15779 "TARGET_USE_FANCY_MATH_387
15780 && flag_unsafe_math_optimizations
15781 && can_create_pseudo_p ()"
15782 "#"
15783 "&& 1"
15784 [(const_int 0)]
15785 {
15786 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15787
15788 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15789 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15790
15791 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15792 operands[2], operands[3]));
15793 DONE;
15794 }
15795 [(set_attr "type" "frndint")
15796 (set_attr "i387_cw" "mask_pm")
15797 (set_attr "mode" "XF")])
15798
15799 (define_insn "frndintxf2_mask_pm_i387"
15800 [(set (match_operand:XF 0 "register_operand" "=f")
15801 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15802 UNSPEC_FRNDINT_MASK_PM))
15803 (use (match_operand:HI 2 "memory_operand" "m"))
15804 (use (match_operand:HI 3 "memory_operand" "m"))]
15805 "TARGET_USE_FANCY_MATH_387
15806 && flag_unsafe_math_optimizations"
15807 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15808 [(set_attr "type" "frndint")
15809 (set_attr "i387_cw" "mask_pm")
15810 (set_attr "mode" "XF")])
15811
15812 (define_expand "nearbyintxf2"
15813 [(parallel [(set (match_operand:XF 0 "register_operand")
15814 (unspec:XF [(match_operand:XF 1 "register_operand")]
15815 UNSPEC_FRNDINT_MASK_PM))
15816 (clobber (reg:CC FLAGS_REG))])]
15817 "TARGET_USE_FANCY_MATH_387
15818 && flag_unsafe_math_optimizations")
15819
15820 (define_expand "nearbyint<mode>2"
15821 [(use (match_operand:MODEF 0 "register_operand"))
15822 (use (match_operand:MODEF 1 "register_operand"))]
15823 "TARGET_USE_FANCY_MATH_387
15824 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15825 || TARGET_MIX_SSE_I387)
15826 && flag_unsafe_math_optimizations"
15827 {
15828 rtx op0 = gen_reg_rtx (XFmode);
15829 rtx op1 = gen_reg_rtx (XFmode);
15830
15831 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15832 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15833
15834 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15835 DONE;
15836 })
15837
15838 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15839 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15840 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15841 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15842 FIST_ROUNDING))
15843 (clobber (reg:CC FLAGS_REG))]
15844 "TARGET_USE_FANCY_MATH_387
15845 && flag_unsafe_math_optimizations
15846 && can_create_pseudo_p ()"
15847 "#"
15848 "&& 1"
15849 [(const_int 0)]
15850 {
15851 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15852
15853 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15854 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15855 if (memory_operand (operands[0], VOIDmode))
15856 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15857 operands[2], operands[3]));
15858 else
15859 {
15860 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15861 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15862 (operands[0], operands[1], operands[2],
15863 operands[3], operands[4]));
15864 }
15865 DONE;
15866 }
15867 [(set_attr "type" "fistp")
15868 (set_attr "i387_cw" "<rounding>")
15869 (set_attr "mode" "<MODE>")])
15870
15871 (define_insn "fistdi2_<rounding>"
15872 [(set (match_operand:DI 0 "memory_operand" "=m")
15873 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15874 FIST_ROUNDING))
15875 (use (match_operand:HI 2 "memory_operand" "m"))
15876 (use (match_operand:HI 3 "memory_operand" "m"))
15877 (clobber (match_scratch:XF 4 "=&1f"))]
15878 "TARGET_USE_FANCY_MATH_387
15879 && flag_unsafe_math_optimizations"
15880 "* return output_fix_trunc (insn, operands, false);"
15881 [(set_attr "type" "fistp")
15882 (set_attr "i387_cw" "<rounding>")
15883 (set_attr "mode" "DI")])
15884
15885 (define_insn "fistdi2_<rounding>_with_temp"
15886 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15887 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15888 FIST_ROUNDING))
15889 (use (match_operand:HI 2 "memory_operand" "m,m"))
15890 (use (match_operand:HI 3 "memory_operand" "m,m"))
15891 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15892 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15893 "TARGET_USE_FANCY_MATH_387
15894 && flag_unsafe_math_optimizations"
15895 "#"
15896 [(set_attr "type" "fistp")
15897 (set_attr "i387_cw" "<rounding>")
15898 (set_attr "mode" "DI")])
15899
15900 (define_split
15901 [(set (match_operand:DI 0 "register_operand")
15902 (unspec:DI [(match_operand:XF 1 "register_operand")]
15903 FIST_ROUNDING))
15904 (use (match_operand:HI 2 "memory_operand"))
15905 (use (match_operand:HI 3 "memory_operand"))
15906 (clobber (match_operand:DI 4 "memory_operand"))
15907 (clobber (match_scratch 5))]
15908 "reload_completed"
15909 [(parallel [(set (match_dup 4)
15910 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15911 (use (match_dup 2))
15912 (use (match_dup 3))
15913 (clobber (match_dup 5))])
15914 (set (match_dup 0) (match_dup 4))])
15915
15916 (define_split
15917 [(set (match_operand:DI 0 "memory_operand")
15918 (unspec:DI [(match_operand:XF 1 "register_operand")]
15919 FIST_ROUNDING))
15920 (use (match_operand:HI 2 "memory_operand"))
15921 (use (match_operand:HI 3 "memory_operand"))
15922 (clobber (match_operand:DI 4 "memory_operand"))
15923 (clobber (match_scratch 5))]
15924 "reload_completed"
15925 [(parallel [(set (match_dup 0)
15926 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15927 (use (match_dup 2))
15928 (use (match_dup 3))
15929 (clobber (match_dup 5))])])
15930
15931 (define_insn "fist<mode>2_<rounding>"
15932 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15933 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15934 FIST_ROUNDING))
15935 (use (match_operand:HI 2 "memory_operand" "m"))
15936 (use (match_operand:HI 3 "memory_operand" "m"))]
15937 "TARGET_USE_FANCY_MATH_387
15938 && flag_unsafe_math_optimizations"
15939 "* return output_fix_trunc (insn, operands, false);"
15940 [(set_attr "type" "fistp")
15941 (set_attr "i387_cw" "<rounding>")
15942 (set_attr "mode" "<MODE>")])
15943
15944 (define_insn "fist<mode>2_<rounding>_with_temp"
15945 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15946 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15947 FIST_ROUNDING))
15948 (use (match_operand:HI 2 "memory_operand" "m,m"))
15949 (use (match_operand:HI 3 "memory_operand" "m,m"))
15950 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15951 "TARGET_USE_FANCY_MATH_387
15952 && flag_unsafe_math_optimizations"
15953 "#"
15954 [(set_attr "type" "fistp")
15955 (set_attr "i387_cw" "<rounding>")
15956 (set_attr "mode" "<MODE>")])
15957
15958 (define_split
15959 [(set (match_operand:SWI24 0 "register_operand")
15960 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15961 FIST_ROUNDING))
15962 (use (match_operand:HI 2 "memory_operand"))
15963 (use (match_operand:HI 3 "memory_operand"))
15964 (clobber (match_operand:SWI24 4 "memory_operand"))]
15965 "reload_completed"
15966 [(parallel [(set (match_dup 4)
15967 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15968 (use (match_dup 2))
15969 (use (match_dup 3))])
15970 (set (match_dup 0) (match_dup 4))])
15971
15972 (define_split
15973 [(set (match_operand:SWI24 0 "memory_operand")
15974 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15975 FIST_ROUNDING))
15976 (use (match_operand:HI 2 "memory_operand"))
15977 (use (match_operand:HI 3 "memory_operand"))
15978 (clobber (match_operand:SWI24 4 "memory_operand"))]
15979 "reload_completed"
15980 [(parallel [(set (match_dup 0)
15981 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15982 (use (match_dup 2))
15983 (use (match_dup 3))])])
15984
15985 (define_expand "l<rounding_insn>xf<mode>2"
15986 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15987 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15988 FIST_ROUNDING))
15989 (clobber (reg:CC FLAGS_REG))])]
15990 "TARGET_USE_FANCY_MATH_387
15991 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15992 && flag_unsafe_math_optimizations")
15993
15994 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15995 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15996 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15997 FIST_ROUNDING))
15998 (clobber (reg:CC FLAGS_REG))])]
15999 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16000 && !flag_trapping_math"
16001 {
16002 if (TARGET_64BIT && optimize_insn_for_size_p ())
16003 FAIL;
16004
16005 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16006 ix86_expand_lfloorceil (operands[0], operands[1], true);
16007 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16008 ix86_expand_lfloorceil (operands[0], operands[1], false);
16009 else
16010 gcc_unreachable ();
16011
16012 DONE;
16013 })
16014
16015 (define_insn "fxam<mode>2_i387"
16016 [(set (match_operand:HI 0 "register_operand" "=a")
16017 (unspec:HI
16018 [(match_operand:X87MODEF 1 "register_operand" "f")]
16019 UNSPEC_FXAM))]
16020 "TARGET_USE_FANCY_MATH_387"
16021 "fxam\n\tfnstsw\t%0"
16022 [(set_attr "type" "multi")
16023 (set_attr "length" "4")
16024 (set_attr "unit" "i387")
16025 (set_attr "mode" "<MODE>")])
16026
16027 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16028 [(set (match_operand:HI 0 "register_operand")
16029 (unspec:HI
16030 [(match_operand:MODEF 1 "memory_operand")]
16031 UNSPEC_FXAM_MEM))]
16032 "TARGET_USE_FANCY_MATH_387
16033 && can_create_pseudo_p ()"
16034 "#"
16035 "&& 1"
16036 [(set (match_dup 2)(match_dup 1))
16037 (set (match_dup 0)
16038 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16039 {
16040 operands[2] = gen_reg_rtx (<MODE>mode);
16041
16042 MEM_VOLATILE_P (operands[1]) = 1;
16043 }
16044 [(set_attr "type" "multi")
16045 (set_attr "unit" "i387")
16046 (set_attr "mode" "<MODE>")])
16047
16048 (define_expand "isinfxf2"
16049 [(use (match_operand:SI 0 "register_operand"))
16050 (use (match_operand:XF 1 "register_operand"))]
16051 "TARGET_USE_FANCY_MATH_387
16052 && ix86_libc_has_function (function_c99_misc)"
16053 {
16054 rtx mask = GEN_INT (0x45);
16055 rtx val = GEN_INT (0x05);
16056
16057 rtx scratch = gen_reg_rtx (HImode);
16058 rtx res = gen_reg_rtx (QImode);
16059
16060 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16061
16062 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16063 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16064 ix86_expand_setcc (res, EQ,
16065 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16066 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16067 DONE;
16068 })
16069
16070 (define_expand "isinf<mode>2"
16071 [(use (match_operand:SI 0 "register_operand"))
16072 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16073 "TARGET_USE_FANCY_MATH_387
16074 && ix86_libc_has_function (function_c99_misc)
16075 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16076 {
16077 rtx mask = GEN_INT (0x45);
16078 rtx val = GEN_INT (0x05);
16079
16080 rtx scratch = gen_reg_rtx (HImode);
16081 rtx res = gen_reg_rtx (QImode);
16082
16083 /* Remove excess precision by forcing value through memory. */
16084 if (memory_operand (operands[1], VOIDmode))
16085 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16086 else
16087 {
16088 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16089
16090 emit_move_insn (temp, operands[1]);
16091 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16092 }
16093
16094 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16095 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16096 ix86_expand_setcc (res, EQ,
16097 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16098 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16099 DONE;
16100 })
16101
16102 (define_expand "signbittf2"
16103 [(use (match_operand:SI 0 "register_operand"))
16104 (use (match_operand:TF 1 "register_operand"))]
16105 "TARGET_SSE"
16106 {
16107 if (TARGET_SSE4_1)
16108 {
16109 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16110 rtx scratch = gen_reg_rtx (QImode);
16111
16112 emit_insn (gen_ptesttf2 (operands[1], mask));
16113 ix86_expand_setcc (scratch, NE,
16114 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16115
16116 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16117 }
16118 else
16119 {
16120 emit_insn (gen_sse_movmskps (operands[0],
16121 gen_lowpart (V4SFmode, operands[1])));
16122 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16123 }
16124 DONE;
16125 })
16126
16127 (define_expand "signbitxf2"
16128 [(use (match_operand:SI 0 "register_operand"))
16129 (use (match_operand:XF 1 "register_operand"))]
16130 "TARGET_USE_FANCY_MATH_387"
16131 {
16132 rtx scratch = gen_reg_rtx (HImode);
16133
16134 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16135 emit_insn (gen_andsi3 (operands[0],
16136 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16137 DONE;
16138 })
16139
16140 (define_insn "movmsk_df"
16141 [(set (match_operand:SI 0 "register_operand" "=r")
16142 (unspec:SI
16143 [(match_operand:DF 1 "register_operand" "x")]
16144 UNSPEC_MOVMSK))]
16145 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16146 "%vmovmskpd\t{%1, %0|%0, %1}"
16147 [(set_attr "type" "ssemov")
16148 (set_attr "prefix" "maybe_vex")
16149 (set_attr "mode" "DF")])
16150
16151 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16152 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16153 (define_expand "signbitdf2"
16154 [(use (match_operand:SI 0 "register_operand"))
16155 (use (match_operand:DF 1 "register_operand"))]
16156 "TARGET_USE_FANCY_MATH_387
16157 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16158 {
16159 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16160 {
16161 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16162 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16163 }
16164 else
16165 {
16166 rtx scratch = gen_reg_rtx (HImode);
16167
16168 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16169 emit_insn (gen_andsi3 (operands[0],
16170 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16171 }
16172 DONE;
16173 })
16174
16175 (define_expand "signbitsf2"
16176 [(use (match_operand:SI 0 "register_operand"))
16177 (use (match_operand:SF 1 "register_operand"))]
16178 "TARGET_USE_FANCY_MATH_387
16179 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16180 {
16181 rtx scratch = gen_reg_rtx (HImode);
16182
16183 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16184 emit_insn (gen_andsi3 (operands[0],
16185 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16186 DONE;
16187 })
16188 \f
16189 ;; Block operation instructions
16190
16191 (define_insn "cld"
16192 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16193 ""
16194 "cld"
16195 [(set_attr "length" "1")
16196 (set_attr "length_immediate" "0")
16197 (set_attr "modrm" "0")])
16198
16199 (define_expand "movmem<mode>"
16200 [(use (match_operand:BLK 0 "memory_operand"))
16201 (use (match_operand:BLK 1 "memory_operand"))
16202 (use (match_operand:SWI48 2 "nonmemory_operand"))
16203 (use (match_operand:SWI48 3 "const_int_operand"))
16204 (use (match_operand:SI 4 "const_int_operand"))
16205 (use (match_operand:SI 5 "const_int_operand"))
16206 (use (match_operand:SI 6 ""))
16207 (use (match_operand:SI 7 ""))
16208 (use (match_operand:SI 8 ""))]
16209 ""
16210 {
16211 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16212 operands[2], NULL, operands[3],
16213 operands[4], operands[5],
16214 operands[6], operands[7],
16215 operands[8], false))
16216 DONE;
16217 else
16218 FAIL;
16219 })
16220
16221 ;; Most CPUs don't like single string operations
16222 ;; Handle this case here to simplify previous expander.
16223
16224 (define_expand "strmov"
16225 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16226 (set (match_operand 1 "memory_operand") (match_dup 4))
16227 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16228 (clobber (reg:CC FLAGS_REG))])
16229 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16230 (clobber (reg:CC FLAGS_REG))])]
16231 ""
16232 {
16233 /* Can't use this for non-default address spaces. */
16234 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16235 FAIL;
16236
16237 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16238
16239 /* If .md ever supports :P for Pmode, these can be directly
16240 in the pattern above. */
16241 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16242 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16243
16244 /* Can't use this if the user has appropriated esi or edi. */
16245 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16246 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16247 {
16248 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16249 operands[2], operands[3],
16250 operands[5], operands[6]));
16251 DONE;
16252 }
16253
16254 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16255 })
16256
16257 (define_expand "strmov_singleop"
16258 [(parallel [(set (match_operand 1 "memory_operand")
16259 (match_operand 3 "memory_operand"))
16260 (set (match_operand 0 "register_operand")
16261 (match_operand 4))
16262 (set (match_operand 2 "register_operand")
16263 (match_operand 5))])]
16264 ""
16265 {
16266 if (TARGET_CLD)
16267 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16268 })
16269
16270 (define_insn "*strmovdi_rex_1"
16271 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16272 (mem:DI (match_operand:P 3 "register_operand" "1")))
16273 (set (match_operand:P 0 "register_operand" "=D")
16274 (plus:P (match_dup 2)
16275 (const_int 8)))
16276 (set (match_operand:P 1 "register_operand" "=S")
16277 (plus:P (match_dup 3)
16278 (const_int 8)))]
16279 "TARGET_64BIT
16280 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16281 && ix86_check_no_addr_space (insn)"
16282 "%^movsq"
16283 [(set_attr "type" "str")
16284 (set_attr "memory" "both")
16285 (set_attr "mode" "DI")])
16286
16287 (define_insn "*strmovsi_1"
16288 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16289 (mem:SI (match_operand:P 3 "register_operand" "1")))
16290 (set (match_operand:P 0 "register_operand" "=D")
16291 (plus:P (match_dup 2)
16292 (const_int 4)))
16293 (set (match_operand:P 1 "register_operand" "=S")
16294 (plus:P (match_dup 3)
16295 (const_int 4)))]
16296 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16297 && ix86_check_no_addr_space (insn)"
16298 "%^movs{l|d}"
16299 [(set_attr "type" "str")
16300 (set_attr "memory" "both")
16301 (set_attr "mode" "SI")])
16302
16303 (define_insn "*strmovhi_1"
16304 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16305 (mem:HI (match_operand:P 3 "register_operand" "1")))
16306 (set (match_operand:P 0 "register_operand" "=D")
16307 (plus:P (match_dup 2)
16308 (const_int 2)))
16309 (set (match_operand:P 1 "register_operand" "=S")
16310 (plus:P (match_dup 3)
16311 (const_int 2)))]
16312 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16313 && ix86_check_no_addr_space (insn)"
16314 "%^movsw"
16315 [(set_attr "type" "str")
16316 (set_attr "memory" "both")
16317 (set_attr "mode" "HI")])
16318
16319 (define_insn "*strmovqi_1"
16320 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16321 (mem:QI (match_operand:P 3 "register_operand" "1")))
16322 (set (match_operand:P 0 "register_operand" "=D")
16323 (plus:P (match_dup 2)
16324 (const_int 1)))
16325 (set (match_operand:P 1 "register_operand" "=S")
16326 (plus:P (match_dup 3)
16327 (const_int 1)))]
16328 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16329 && ix86_check_no_addr_space (insn)"
16330 "%^movsb"
16331 [(set_attr "type" "str")
16332 (set_attr "memory" "both")
16333 (set (attr "prefix_rex")
16334 (if_then_else
16335 (match_test "<P:MODE>mode == DImode")
16336 (const_string "0")
16337 (const_string "*")))
16338 (set_attr "mode" "QI")])
16339
16340 (define_expand "rep_mov"
16341 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16342 (set (match_operand 0 "register_operand")
16343 (match_operand 5))
16344 (set (match_operand 2 "register_operand")
16345 (match_operand 6))
16346 (set (match_operand 1 "memory_operand")
16347 (match_operand 3 "memory_operand"))
16348 (use (match_dup 4))])]
16349 ""
16350 {
16351 if (TARGET_CLD)
16352 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16353 })
16354
16355 (define_insn "*rep_movdi_rex64"
16356 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16357 (set (match_operand:P 0 "register_operand" "=D")
16358 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16359 (const_int 3))
16360 (match_operand:P 3 "register_operand" "0")))
16361 (set (match_operand:P 1 "register_operand" "=S")
16362 (plus:P (ashift:P (match_dup 5) (const_int 3))
16363 (match_operand:P 4 "register_operand" "1")))
16364 (set (mem:BLK (match_dup 3))
16365 (mem:BLK (match_dup 4)))
16366 (use (match_dup 5))]
16367 "TARGET_64BIT
16368 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16369 && ix86_check_no_addr_space (insn)"
16370 "%^rep{%;} movsq"
16371 [(set_attr "type" "str")
16372 (set_attr "prefix_rep" "1")
16373 (set_attr "memory" "both")
16374 (set_attr "mode" "DI")])
16375
16376 (define_insn "*rep_movsi"
16377 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16378 (set (match_operand:P 0 "register_operand" "=D")
16379 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16380 (const_int 2))
16381 (match_operand:P 3 "register_operand" "0")))
16382 (set (match_operand:P 1 "register_operand" "=S")
16383 (plus:P (ashift:P (match_dup 5) (const_int 2))
16384 (match_operand:P 4 "register_operand" "1")))
16385 (set (mem:BLK (match_dup 3))
16386 (mem:BLK (match_dup 4)))
16387 (use (match_dup 5))]
16388 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16389 && ix86_check_no_addr_space (insn)"
16390 "%^rep{%;} movs{l|d}"
16391 [(set_attr "type" "str")
16392 (set_attr "prefix_rep" "1")
16393 (set_attr "memory" "both")
16394 (set_attr "mode" "SI")])
16395
16396 (define_insn "*rep_movqi"
16397 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16398 (set (match_operand:P 0 "register_operand" "=D")
16399 (plus:P (match_operand:P 3 "register_operand" "0")
16400 (match_operand:P 5 "register_operand" "2")))
16401 (set (match_operand:P 1 "register_operand" "=S")
16402 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16403 (set (mem:BLK (match_dup 3))
16404 (mem:BLK (match_dup 4)))
16405 (use (match_dup 5))]
16406 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16407 && ix86_check_no_addr_space (insn)"
16408 "%^rep{%;} movsb"
16409 [(set_attr "type" "str")
16410 (set_attr "prefix_rep" "1")
16411 (set_attr "memory" "both")
16412 (set_attr "mode" "QI")])
16413
16414 (define_expand "setmem<mode>"
16415 [(use (match_operand:BLK 0 "memory_operand"))
16416 (use (match_operand:SWI48 1 "nonmemory_operand"))
16417 (use (match_operand:QI 2 "nonmemory_operand"))
16418 (use (match_operand 3 "const_int_operand"))
16419 (use (match_operand:SI 4 "const_int_operand"))
16420 (use (match_operand:SI 5 "const_int_operand"))
16421 (use (match_operand:SI 6 ""))
16422 (use (match_operand:SI 7 ""))
16423 (use (match_operand:SI 8 ""))]
16424 ""
16425 {
16426 if (ix86_expand_set_or_movmem (operands[0], NULL,
16427 operands[1], operands[2],
16428 operands[3], operands[4],
16429 operands[5], operands[6],
16430 operands[7], operands[8], true))
16431 DONE;
16432 else
16433 FAIL;
16434 })
16435
16436 ;; Most CPUs don't like single string operations
16437 ;; Handle this case here to simplify previous expander.
16438
16439 (define_expand "strset"
16440 [(set (match_operand 1 "memory_operand")
16441 (match_operand 2 "register_operand"))
16442 (parallel [(set (match_operand 0 "register_operand")
16443 (match_dup 3))
16444 (clobber (reg:CC FLAGS_REG))])]
16445 ""
16446 {
16447 /* Can't use this for non-default address spaces. */
16448 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16449 FAIL;
16450
16451 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16452 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16453
16454 /* If .md ever supports :P for Pmode, this can be directly
16455 in the pattern above. */
16456 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16457 GEN_INT (GET_MODE_SIZE (GET_MODE
16458 (operands[2]))));
16459 /* Can't use this if the user has appropriated eax or edi. */
16460 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16461 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16462 {
16463 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16464 operands[3]));
16465 DONE;
16466 }
16467 })
16468
16469 (define_expand "strset_singleop"
16470 [(parallel [(set (match_operand 1 "memory_operand")
16471 (match_operand 2 "register_operand"))
16472 (set (match_operand 0 "register_operand")
16473 (match_operand 3))
16474 (unspec [(const_int 0)] UNSPEC_STOS)])]
16475 ""
16476 {
16477 if (TARGET_CLD)
16478 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16479 })
16480
16481 (define_insn "*strsetdi_rex_1"
16482 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16483 (match_operand:DI 2 "register_operand" "a"))
16484 (set (match_operand:P 0 "register_operand" "=D")
16485 (plus:P (match_dup 1)
16486 (const_int 8)))
16487 (unspec [(const_int 0)] UNSPEC_STOS)]
16488 "TARGET_64BIT
16489 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16490 && ix86_check_no_addr_space (insn)"
16491 "%^stosq"
16492 [(set_attr "type" "str")
16493 (set_attr "memory" "store")
16494 (set_attr "mode" "DI")])
16495
16496 (define_insn "*strsetsi_1"
16497 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16498 (match_operand:SI 2 "register_operand" "a"))
16499 (set (match_operand:P 0 "register_operand" "=D")
16500 (plus:P (match_dup 1)
16501 (const_int 4)))
16502 (unspec [(const_int 0)] UNSPEC_STOS)]
16503 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16504 && ix86_check_no_addr_space (insn)"
16505 "%^stos{l|d}"
16506 [(set_attr "type" "str")
16507 (set_attr "memory" "store")
16508 (set_attr "mode" "SI")])
16509
16510 (define_insn "*strsethi_1"
16511 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16512 (match_operand:HI 2 "register_operand" "a"))
16513 (set (match_operand:P 0 "register_operand" "=D")
16514 (plus:P (match_dup 1)
16515 (const_int 2)))
16516 (unspec [(const_int 0)] UNSPEC_STOS)]
16517 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16518 && ix86_check_no_addr_space (insn)"
16519 "%^stosw"
16520 [(set_attr "type" "str")
16521 (set_attr "memory" "store")
16522 (set_attr "mode" "HI")])
16523
16524 (define_insn "*strsetqi_1"
16525 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16526 (match_operand:QI 2 "register_operand" "a"))
16527 (set (match_operand:P 0 "register_operand" "=D")
16528 (plus:P (match_dup 1)
16529 (const_int 1)))
16530 (unspec [(const_int 0)] UNSPEC_STOS)]
16531 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16532 && ix86_check_no_addr_space (insn)"
16533 "%^stosb"
16534 [(set_attr "type" "str")
16535 (set_attr "memory" "store")
16536 (set (attr "prefix_rex")
16537 (if_then_else
16538 (match_test "<P:MODE>mode == DImode")
16539 (const_string "0")
16540 (const_string "*")))
16541 (set_attr "mode" "QI")])
16542
16543 (define_expand "rep_stos"
16544 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16545 (set (match_operand 0 "register_operand")
16546 (match_operand 4))
16547 (set (match_operand 2 "memory_operand") (const_int 0))
16548 (use (match_operand 3 "register_operand"))
16549 (use (match_dup 1))])]
16550 ""
16551 {
16552 if (TARGET_CLD)
16553 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16554 })
16555
16556 (define_insn "*rep_stosdi_rex64"
16557 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16558 (set (match_operand:P 0 "register_operand" "=D")
16559 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16560 (const_int 3))
16561 (match_operand:P 3 "register_operand" "0")))
16562 (set (mem:BLK (match_dup 3))
16563 (const_int 0))
16564 (use (match_operand:DI 2 "register_operand" "a"))
16565 (use (match_dup 4))]
16566 "TARGET_64BIT
16567 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16568 && ix86_check_no_addr_space (insn)"
16569 "%^rep{%;} stosq"
16570 [(set_attr "type" "str")
16571 (set_attr "prefix_rep" "1")
16572 (set_attr "memory" "store")
16573 (set_attr "mode" "DI")])
16574
16575 (define_insn "*rep_stossi"
16576 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16577 (set (match_operand:P 0 "register_operand" "=D")
16578 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16579 (const_int 2))
16580 (match_operand:P 3 "register_operand" "0")))
16581 (set (mem:BLK (match_dup 3))
16582 (const_int 0))
16583 (use (match_operand:SI 2 "register_operand" "a"))
16584 (use (match_dup 4))]
16585 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16586 && ix86_check_no_addr_space (insn)"
16587 "%^rep{%;} stos{l|d}"
16588 [(set_attr "type" "str")
16589 (set_attr "prefix_rep" "1")
16590 (set_attr "memory" "store")
16591 (set_attr "mode" "SI")])
16592
16593 (define_insn "*rep_stosqi"
16594 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16595 (set (match_operand:P 0 "register_operand" "=D")
16596 (plus:P (match_operand:P 3 "register_operand" "0")
16597 (match_operand:P 4 "register_operand" "1")))
16598 (set (mem:BLK (match_dup 3))
16599 (const_int 0))
16600 (use (match_operand:QI 2 "register_operand" "a"))
16601 (use (match_dup 4))]
16602 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16603 && ix86_check_no_addr_space (insn)"
16604 "%^rep{%;} stosb"
16605 [(set_attr "type" "str")
16606 (set_attr "prefix_rep" "1")
16607 (set_attr "memory" "store")
16608 (set (attr "prefix_rex")
16609 (if_then_else
16610 (match_test "<P:MODE>mode == DImode")
16611 (const_string "0")
16612 (const_string "*")))
16613 (set_attr "mode" "QI")])
16614
16615 (define_expand "cmpstrnsi"
16616 [(set (match_operand:SI 0 "register_operand")
16617 (compare:SI (match_operand:BLK 1 "general_operand")
16618 (match_operand:BLK 2 "general_operand")))
16619 (use (match_operand 3 "general_operand"))
16620 (use (match_operand 4 "immediate_operand"))]
16621 ""
16622 {
16623 rtx addr1, addr2, out, outlow, count, countreg, align;
16624
16625 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16626 FAIL;
16627
16628 /* Can't use this if the user has appropriated ecx, esi or edi. */
16629 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16630 FAIL;
16631
16632 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
16633 will have rewritten the length arg to be the minimum of the const string
16634 length and the actual length arg. If both strings are the same and
16635 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
16636 will incorrectly base the results on chars past the 0 byte. */
16637 tree t1 = MEM_EXPR (operands[1]);
16638 tree t2 = MEM_EXPR (operands[2]);
16639 if (!((t1 && TREE_CODE (t1) == MEM_REF
16640 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
16641 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
16642 || (t2 && TREE_CODE (t2) == MEM_REF
16643 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
16644 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
16645 FAIL;
16646
16647 out = operands[0];
16648 if (!REG_P (out))
16649 out = gen_reg_rtx (SImode);
16650
16651 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16652 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16653 if (addr1 != XEXP (operands[1], 0))
16654 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16655 if (addr2 != XEXP (operands[2], 0))
16656 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16657
16658 count = operands[3];
16659 countreg = ix86_zero_extend_to_Pmode (count);
16660
16661 /* %%% Iff we are testing strict equality, we can use known alignment
16662 to good advantage. This may be possible with combine, particularly
16663 once cc0 is dead. */
16664 align = operands[4];
16665
16666 if (CONST_INT_P (count))
16667 {
16668 if (INTVAL (count) == 0)
16669 {
16670 emit_move_insn (operands[0], const0_rtx);
16671 DONE;
16672 }
16673 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16674 operands[1], operands[2]));
16675 }
16676 else
16677 {
16678 rtx (*gen_cmp) (rtx, rtx);
16679
16680 gen_cmp = (TARGET_64BIT
16681 ? gen_cmpdi_1 : gen_cmpsi_1);
16682
16683 emit_insn (gen_cmp (countreg, countreg));
16684 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16685 operands[1], operands[2]));
16686 }
16687
16688 outlow = gen_lowpart (QImode, out);
16689 emit_insn (gen_cmpintqi (outlow));
16690 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16691
16692 if (operands[0] != out)
16693 emit_move_insn (operands[0], out);
16694
16695 DONE;
16696 })
16697
16698 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16699
16700 (define_expand "cmpintqi"
16701 [(set (match_dup 1)
16702 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16703 (set (match_dup 2)
16704 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16705 (parallel [(set (match_operand:QI 0 "register_operand")
16706 (minus:QI (match_dup 1)
16707 (match_dup 2)))
16708 (clobber (reg:CC FLAGS_REG))])]
16709 ""
16710 {
16711 operands[1] = gen_reg_rtx (QImode);
16712 operands[2] = gen_reg_rtx (QImode);
16713 })
16714
16715 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16716 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16717
16718 (define_expand "cmpstrnqi_nz_1"
16719 [(parallel [(set (reg:CC FLAGS_REG)
16720 (compare:CC (match_operand 4 "memory_operand")
16721 (match_operand 5 "memory_operand")))
16722 (use (match_operand 2 "register_operand"))
16723 (use (match_operand:SI 3 "immediate_operand"))
16724 (clobber (match_operand 0 "register_operand"))
16725 (clobber (match_operand 1 "register_operand"))
16726 (clobber (match_dup 2))])]
16727 ""
16728 {
16729 if (TARGET_CLD)
16730 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16731 })
16732
16733 (define_insn "*cmpstrnqi_nz_1"
16734 [(set (reg:CC FLAGS_REG)
16735 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16736 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16737 (use (match_operand:P 6 "register_operand" "2"))
16738 (use (match_operand:SI 3 "immediate_operand" "i"))
16739 (clobber (match_operand:P 0 "register_operand" "=S"))
16740 (clobber (match_operand:P 1 "register_operand" "=D"))
16741 (clobber (match_operand:P 2 "register_operand" "=c"))]
16742 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16743 && ix86_check_no_addr_space (insn)"
16744 "%^repz{%;} cmpsb"
16745 [(set_attr "type" "str")
16746 (set_attr "mode" "QI")
16747 (set (attr "prefix_rex")
16748 (if_then_else
16749 (match_test "<P:MODE>mode == DImode")
16750 (const_string "0")
16751 (const_string "*")))
16752 (set_attr "prefix_rep" "1")])
16753
16754 ;; The same, but the count is not known to not be zero.
16755
16756 (define_expand "cmpstrnqi_1"
16757 [(parallel [(set (reg:CC FLAGS_REG)
16758 (if_then_else:CC (ne (match_operand 2 "register_operand")
16759 (const_int 0))
16760 (compare:CC (match_operand 4 "memory_operand")
16761 (match_operand 5 "memory_operand"))
16762 (const_int 0)))
16763 (use (match_operand:SI 3 "immediate_operand"))
16764 (use (reg:CC FLAGS_REG))
16765 (clobber (match_operand 0 "register_operand"))
16766 (clobber (match_operand 1 "register_operand"))
16767 (clobber (match_dup 2))])]
16768 ""
16769 {
16770 if (TARGET_CLD)
16771 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16772 })
16773
16774 (define_insn "*cmpstrnqi_1"
16775 [(set (reg:CC FLAGS_REG)
16776 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16777 (const_int 0))
16778 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16779 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16780 (const_int 0)))
16781 (use (match_operand:SI 3 "immediate_operand" "i"))
16782 (use (reg:CC FLAGS_REG))
16783 (clobber (match_operand:P 0 "register_operand" "=S"))
16784 (clobber (match_operand:P 1 "register_operand" "=D"))
16785 (clobber (match_operand:P 2 "register_operand" "=c"))]
16786 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16787 && ix86_check_no_addr_space (insn)"
16788 "%^repz{%;} cmpsb"
16789 [(set_attr "type" "str")
16790 (set_attr "mode" "QI")
16791 (set (attr "prefix_rex")
16792 (if_then_else
16793 (match_test "<P:MODE>mode == DImode")
16794 (const_string "0")
16795 (const_string "*")))
16796 (set_attr "prefix_rep" "1")])
16797
16798 (define_expand "strlen<mode>"
16799 [(set (match_operand:P 0 "register_operand")
16800 (unspec:P [(match_operand:BLK 1 "general_operand")
16801 (match_operand:QI 2 "immediate_operand")
16802 (match_operand 3 "immediate_operand")]
16803 UNSPEC_SCAS))]
16804 ""
16805 {
16806 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16807 DONE;
16808 else
16809 FAIL;
16810 })
16811
16812 (define_expand "strlenqi_1"
16813 [(parallel [(set (match_operand 0 "register_operand")
16814 (match_operand 2))
16815 (clobber (match_operand 1 "register_operand"))
16816 (clobber (reg:CC FLAGS_REG))])]
16817 ""
16818 {
16819 if (TARGET_CLD)
16820 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16821 })
16822
16823 (define_insn "*strlenqi_1"
16824 [(set (match_operand:P 0 "register_operand" "=&c")
16825 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16826 (match_operand:QI 2 "register_operand" "a")
16827 (match_operand:P 3 "immediate_operand" "i")
16828 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16829 (clobber (match_operand:P 1 "register_operand" "=D"))
16830 (clobber (reg:CC FLAGS_REG))]
16831 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16832 && ix86_check_no_addr_space (insn)"
16833 "%^repnz{%;} scasb"
16834 [(set_attr "type" "str")
16835 (set_attr "mode" "QI")
16836 (set (attr "prefix_rex")
16837 (if_then_else
16838 (match_test "<P:MODE>mode == DImode")
16839 (const_string "0")
16840 (const_string "*")))
16841 (set_attr "prefix_rep" "1")])
16842
16843 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16844 ;; handled in combine, but it is not currently up to the task.
16845 ;; When used for their truth value, the cmpstrn* expanders generate
16846 ;; code like this:
16847 ;;
16848 ;; repz cmpsb
16849 ;; seta %al
16850 ;; setb %dl
16851 ;; cmpb %al, %dl
16852 ;; jcc label
16853 ;;
16854 ;; The intermediate three instructions are unnecessary.
16855
16856 ;; This one handles cmpstrn*_nz_1...
16857 (define_peephole2
16858 [(parallel[
16859 (set (reg:CC FLAGS_REG)
16860 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16861 (mem:BLK (match_operand 5 "register_operand"))))
16862 (use (match_operand 6 "register_operand"))
16863 (use (match_operand:SI 3 "immediate_operand"))
16864 (clobber (match_operand 0 "register_operand"))
16865 (clobber (match_operand 1 "register_operand"))
16866 (clobber (match_operand 2 "register_operand"))])
16867 (set (match_operand:QI 7 "register_operand")
16868 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16869 (set (match_operand:QI 8 "register_operand")
16870 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16871 (set (reg FLAGS_REG)
16872 (compare (match_dup 7) (match_dup 8)))
16873 ]
16874 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16875 [(parallel[
16876 (set (reg:CC FLAGS_REG)
16877 (compare:CC (mem:BLK (match_dup 4))
16878 (mem:BLK (match_dup 5))))
16879 (use (match_dup 6))
16880 (use (match_dup 3))
16881 (clobber (match_dup 0))
16882 (clobber (match_dup 1))
16883 (clobber (match_dup 2))])])
16884
16885 ;; ...and this one handles cmpstrn*_1.
16886 (define_peephole2
16887 [(parallel[
16888 (set (reg:CC FLAGS_REG)
16889 (if_then_else:CC (ne (match_operand 6 "register_operand")
16890 (const_int 0))
16891 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16892 (mem:BLK (match_operand 5 "register_operand")))
16893 (const_int 0)))
16894 (use (match_operand:SI 3 "immediate_operand"))
16895 (use (reg:CC FLAGS_REG))
16896 (clobber (match_operand 0 "register_operand"))
16897 (clobber (match_operand 1 "register_operand"))
16898 (clobber (match_operand 2 "register_operand"))])
16899 (set (match_operand:QI 7 "register_operand")
16900 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16901 (set (match_operand:QI 8 "register_operand")
16902 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16903 (set (reg FLAGS_REG)
16904 (compare (match_dup 7) (match_dup 8)))
16905 ]
16906 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16907 [(parallel[
16908 (set (reg:CC FLAGS_REG)
16909 (if_then_else:CC (ne (match_dup 6)
16910 (const_int 0))
16911 (compare:CC (mem:BLK (match_dup 4))
16912 (mem:BLK (match_dup 5)))
16913 (const_int 0)))
16914 (use (match_dup 3))
16915 (use (reg:CC FLAGS_REG))
16916 (clobber (match_dup 0))
16917 (clobber (match_dup 1))
16918 (clobber (match_dup 2))])])
16919 \f
16920 ;; Conditional move instructions.
16921
16922 (define_expand "mov<mode>cc"
16923 [(set (match_operand:SWIM 0 "register_operand")
16924 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16925 (match_operand:SWIM 2 "<general_operand>")
16926 (match_operand:SWIM 3 "<general_operand>")))]
16927 ""
16928 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16929
16930 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16931 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16932 ;; So just document what we're doing explicitly.
16933
16934 (define_expand "x86_mov<mode>cc_0_m1"
16935 [(parallel
16936 [(set (match_operand:SWI48 0 "register_operand")
16937 (if_then_else:SWI48
16938 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16939 [(match_operand 1 "flags_reg_operand")
16940 (const_int 0)])
16941 (const_int -1)
16942 (const_int 0)))
16943 (clobber (reg:CC FLAGS_REG))])])
16944
16945 (define_insn "*x86_mov<mode>cc_0_m1"
16946 [(set (match_operand:SWI48 0 "register_operand" "=r")
16947 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16948 [(reg FLAGS_REG) (const_int 0)])
16949 (const_int -1)
16950 (const_int 0)))
16951 (clobber (reg:CC FLAGS_REG))]
16952 ""
16953 "sbb{<imodesuffix>}\t%0, %0"
16954 ; Since we don't have the proper number of operands for an alu insn,
16955 ; fill in all the blanks.
16956 [(set_attr "type" "alu")
16957 (set_attr "modrm_class" "op0")
16958 (set_attr "use_carry" "1")
16959 (set_attr "pent_pair" "pu")
16960 (set_attr "memory" "none")
16961 (set_attr "imm_disp" "false")
16962 (set_attr "mode" "<MODE>")
16963 (set_attr "length_immediate" "0")])
16964
16965 (define_insn "*x86_mov<mode>cc_0_m1_se"
16966 [(set (match_operand:SWI48 0 "register_operand" "=r")
16967 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16968 [(reg FLAGS_REG) (const_int 0)])
16969 (const_int 1)
16970 (const_int 0)))
16971 (clobber (reg:CC FLAGS_REG))]
16972 ""
16973 "sbb{<imodesuffix>}\t%0, %0"
16974 [(set_attr "type" "alu")
16975 (set_attr "modrm_class" "op0")
16976 (set_attr "use_carry" "1")
16977 (set_attr "pent_pair" "pu")
16978 (set_attr "memory" "none")
16979 (set_attr "imm_disp" "false")
16980 (set_attr "mode" "<MODE>")
16981 (set_attr "length_immediate" "0")])
16982
16983 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16984 [(set (match_operand:SWI48 0 "register_operand" "=r")
16985 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16986 [(reg FLAGS_REG) (const_int 0)])))
16987 (clobber (reg:CC FLAGS_REG))]
16988 ""
16989 "sbb{<imodesuffix>}\t%0, %0"
16990 [(set_attr "type" "alu")
16991 (set_attr "modrm_class" "op0")
16992 (set_attr "use_carry" "1")
16993 (set_attr "pent_pair" "pu")
16994 (set_attr "memory" "none")
16995 (set_attr "imm_disp" "false")
16996 (set_attr "mode" "<MODE>")
16997 (set_attr "length_immediate" "0")])
16998
16999 (define_insn "*mov<mode>cc_noc"
17000 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17001 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17002 [(reg FLAGS_REG) (const_int 0)])
17003 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17004 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17005 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17006 "@
17007 cmov%O2%C1\t{%2, %0|%0, %2}
17008 cmov%O2%c1\t{%3, %0|%0, %3}"
17009 [(set_attr "type" "icmov")
17010 (set_attr "mode" "<MODE>")])
17011
17012 (define_insn "*movsicc_noc_zext"
17013 [(set (match_operand:DI 0 "register_operand" "=r,r")
17014 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17015 [(reg FLAGS_REG) (const_int 0)])
17016 (zero_extend:DI
17017 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17018 (zero_extend:DI
17019 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17020 "TARGET_64BIT
17021 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17022 "@
17023 cmov%O2%C1\t{%2, %k0|%k0, %2}
17024 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17025 [(set_attr "type" "icmov")
17026 (set_attr "mode" "SI")])
17027
17028 ;; Don't do conditional moves with memory inputs. This splitter helps
17029 ;; register starved x86_32 by forcing inputs into registers before reload.
17030 (define_split
17031 [(set (match_operand:SWI248 0 "register_operand")
17032 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17033 [(reg FLAGS_REG) (const_int 0)])
17034 (match_operand:SWI248 2 "nonimmediate_operand")
17035 (match_operand:SWI248 3 "nonimmediate_operand")))]
17036 "!TARGET_64BIT && TARGET_CMOVE
17037 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17038 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17039 && can_create_pseudo_p ()
17040 && optimize_insn_for_speed_p ()"
17041 [(set (match_dup 0)
17042 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17043 {
17044 if (MEM_P (operands[2]))
17045 operands[2] = force_reg (<MODE>mode, operands[2]);
17046 if (MEM_P (operands[3]))
17047 operands[3] = force_reg (<MODE>mode, operands[3]);
17048 })
17049
17050 (define_insn "*movqicc_noc"
17051 [(set (match_operand:QI 0 "register_operand" "=r,r")
17052 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17053 [(reg FLAGS_REG) (const_int 0)])
17054 (match_operand:QI 2 "register_operand" "r,0")
17055 (match_operand:QI 3 "register_operand" "0,r")))]
17056 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17057 "#"
17058 [(set_attr "type" "icmov")
17059 (set_attr "mode" "QI")])
17060
17061 (define_split
17062 [(set (match_operand:SWI12 0 "register_operand")
17063 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17064 [(reg FLAGS_REG) (const_int 0)])
17065 (match_operand:SWI12 2 "register_operand")
17066 (match_operand:SWI12 3 "register_operand")))]
17067 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17068 && reload_completed"
17069 [(set (match_dup 0)
17070 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17071 {
17072 operands[0] = gen_lowpart (SImode, operands[0]);
17073 operands[2] = gen_lowpart (SImode, operands[2]);
17074 operands[3] = gen_lowpart (SImode, operands[3]);
17075 })
17076
17077 ;; Don't do conditional moves with memory inputs
17078 (define_peephole2
17079 [(match_scratch:SWI248 4 "r")
17080 (set (match_operand:SWI248 0 "register_operand")
17081 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17082 [(reg FLAGS_REG) (const_int 0)])
17083 (match_operand:SWI248 2 "nonimmediate_operand")
17084 (match_operand:SWI248 3 "nonimmediate_operand")))]
17085 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17086 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17087 && optimize_insn_for_speed_p ()"
17088 [(set (match_dup 4) (match_dup 5))
17089 (set (match_dup 0)
17090 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17091 {
17092 if (MEM_P (operands[2]))
17093 {
17094 operands[5] = operands[2];
17095 operands[2] = operands[4];
17096 }
17097 else if (MEM_P (operands[3]))
17098 {
17099 operands[5] = operands[3];
17100 operands[3] = operands[4];
17101 }
17102 else
17103 gcc_unreachable ();
17104 })
17105
17106 (define_peephole2
17107 [(match_scratch:SI 4 "r")
17108 (set (match_operand:DI 0 "register_operand")
17109 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17110 [(reg FLAGS_REG) (const_int 0)])
17111 (zero_extend:DI
17112 (match_operand:SI 2 "nonimmediate_operand"))
17113 (zero_extend:DI
17114 (match_operand:SI 3 "nonimmediate_operand"))))]
17115 "TARGET_64BIT
17116 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17117 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17118 && optimize_insn_for_speed_p ()"
17119 [(set (match_dup 4) (match_dup 5))
17120 (set (match_dup 0)
17121 (if_then_else:DI (match_dup 1)
17122 (zero_extend:DI (match_dup 2))
17123 (zero_extend:DI (match_dup 3))))]
17124 {
17125 if (MEM_P (operands[2]))
17126 {
17127 operands[5] = operands[2];
17128 operands[2] = operands[4];
17129 }
17130 else if (MEM_P (operands[3]))
17131 {
17132 operands[5] = operands[3];
17133 operands[3] = operands[4];
17134 }
17135 else
17136 gcc_unreachable ();
17137 })
17138
17139 (define_expand "mov<mode>cc"
17140 [(set (match_operand:X87MODEF 0 "register_operand")
17141 (if_then_else:X87MODEF
17142 (match_operand 1 "comparison_operator")
17143 (match_operand:X87MODEF 2 "register_operand")
17144 (match_operand:X87MODEF 3 "register_operand")))]
17145 "(TARGET_80387 && TARGET_CMOVE)
17146 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17147 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17148
17149 (define_insn "*movxfcc_1"
17150 [(set (match_operand:XF 0 "register_operand" "=f,f")
17151 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17152 [(reg FLAGS_REG) (const_int 0)])
17153 (match_operand:XF 2 "register_operand" "f,0")
17154 (match_operand:XF 3 "register_operand" "0,f")))]
17155 "TARGET_80387 && TARGET_CMOVE"
17156 "@
17157 fcmov%F1\t{%2, %0|%0, %2}
17158 fcmov%f1\t{%3, %0|%0, %3}"
17159 [(set_attr "type" "fcmov")
17160 (set_attr "mode" "XF")])
17161
17162 (define_insn "*movdfcc_1"
17163 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17164 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17165 [(reg FLAGS_REG) (const_int 0)])
17166 (match_operand:DF 2 "nonimmediate_operand"
17167 "f ,0,rm,0 ,rm,0")
17168 (match_operand:DF 3 "nonimmediate_operand"
17169 "0 ,f,0 ,rm,0, rm")))]
17170 "TARGET_80387 && TARGET_CMOVE
17171 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17172 "@
17173 fcmov%F1\t{%2, %0|%0, %2}
17174 fcmov%f1\t{%3, %0|%0, %3}
17175 #
17176 #
17177 cmov%O2%C1\t{%2, %0|%0, %2}
17178 cmov%O2%c1\t{%3, %0|%0, %3}"
17179 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17180 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17181 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17182
17183 (define_split
17184 [(set (match_operand:DF 0 "general_reg_operand")
17185 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17186 [(reg FLAGS_REG) (const_int 0)])
17187 (match_operand:DF 2 "nonimmediate_operand")
17188 (match_operand:DF 3 "nonimmediate_operand")))]
17189 "!TARGET_64BIT && reload_completed"
17190 [(set (match_dup 2)
17191 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17192 (set (match_dup 3)
17193 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17194 {
17195 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17196 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17197 })
17198
17199 (define_insn "*movsfcc_1_387"
17200 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17201 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17202 [(reg FLAGS_REG) (const_int 0)])
17203 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17204 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17205 "TARGET_80387 && TARGET_CMOVE
17206 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17207 "@
17208 fcmov%F1\t{%2, %0|%0, %2}
17209 fcmov%f1\t{%3, %0|%0, %3}
17210 cmov%O2%C1\t{%2, %0|%0, %2}
17211 cmov%O2%c1\t{%3, %0|%0, %3}"
17212 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17213 (set_attr "mode" "SF,SF,SI,SI")])
17214
17215 ;; Don't do conditional moves with memory inputs. This splitter helps
17216 ;; register starved x86_32 by forcing inputs into registers before reload.
17217 (define_split
17218 [(set (match_operand:MODEF 0 "register_operand")
17219 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17220 [(reg FLAGS_REG) (const_int 0)])
17221 (match_operand:MODEF 2 "nonimmediate_operand")
17222 (match_operand:MODEF 3 "nonimmediate_operand")))]
17223 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17224 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17225 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17226 && can_create_pseudo_p ()
17227 && optimize_insn_for_speed_p ()"
17228 [(set (match_dup 0)
17229 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17230 {
17231 if (MEM_P (operands[2]))
17232 operands[2] = force_reg (<MODE>mode, operands[2]);
17233 if (MEM_P (operands[3]))
17234 operands[3] = force_reg (<MODE>mode, operands[3]);
17235 })
17236
17237 ;; Don't do conditional moves with memory inputs
17238 (define_peephole2
17239 [(match_scratch:MODEF 4 "r")
17240 (set (match_operand:MODEF 0 "general_reg_operand")
17241 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17242 [(reg FLAGS_REG) (const_int 0)])
17243 (match_operand:MODEF 2 "nonimmediate_operand")
17244 (match_operand:MODEF 3 "nonimmediate_operand")))]
17245 "(<MODE>mode != DFmode || TARGET_64BIT)
17246 && TARGET_80387 && TARGET_CMOVE
17247 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17248 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17249 && optimize_insn_for_speed_p ()"
17250 [(set (match_dup 4) (match_dup 5))
17251 (set (match_dup 0)
17252 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17253 {
17254 if (MEM_P (operands[2]))
17255 {
17256 operands[5] = operands[2];
17257 operands[2] = operands[4];
17258 }
17259 else if (MEM_P (operands[3]))
17260 {
17261 operands[5] = operands[3];
17262 operands[3] = operands[4];
17263 }
17264 else
17265 gcc_unreachable ();
17266 })
17267
17268 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17269 ;; the scalar versions to have only XMM registers as operands.
17270
17271 ;; XOP conditional move
17272 (define_insn "*xop_pcmov_<mode>"
17273 [(set (match_operand:MODEF 0 "register_operand" "=x")
17274 (if_then_else:MODEF
17275 (match_operand:MODEF 1 "register_operand" "x")
17276 (match_operand:MODEF 2 "register_operand" "x")
17277 (match_operand:MODEF 3 "register_operand" "x")))]
17278 "TARGET_XOP"
17279 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17280 [(set_attr "type" "sse4arg")])
17281
17282 ;; These versions of the min/max patterns are intentionally ignorant of
17283 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17284 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17285 ;; are undefined in this condition, we're certain this is correct.
17286
17287 (define_insn "<code><mode>3"
17288 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17289 (smaxmin:MODEF
17290 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17291 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17292 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17293 "@
17294 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17295 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17296 [(set_attr "isa" "noavx,avx")
17297 (set_attr "prefix" "orig,vex")
17298 (set_attr "type" "sseadd")
17299 (set_attr "mode" "<MODE>")])
17300
17301 ;; These versions of the min/max patterns implement exactly the operations
17302 ;; min = (op1 < op2 ? op1 : op2)
17303 ;; max = (!(op1 < op2) ? op1 : op2)
17304 ;; Their operands are not commutative, and thus they may be used in the
17305 ;; presence of -0.0 and NaN.
17306
17307 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17308 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17309 (unspec:MODEF
17310 [(match_operand:MODEF 1 "register_operand" "0,v")
17311 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17312 IEEE_MAXMIN))]
17313 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17314 "@
17315 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17316 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17317 [(set_attr "isa" "noavx,avx")
17318 (set_attr "prefix" "orig,maybe_evex")
17319 (set_attr "type" "sseadd")
17320 (set_attr "mode" "<MODE>")])
17321
17322 ;; Make two stack loads independent:
17323 ;; fld aa fld aa
17324 ;; fld %st(0) -> fld bb
17325 ;; fmul bb fmul %st(1), %st
17326 ;;
17327 ;; Actually we only match the last two instructions for simplicity.
17328
17329 (define_peephole2
17330 [(set (match_operand 0 "fp_register_operand")
17331 (match_operand 1 "fp_register_operand"))
17332 (set (match_dup 0)
17333 (match_operator 2 "binary_fp_operator"
17334 [(match_dup 0)
17335 (match_operand 3 "memory_operand")]))]
17336 "REGNO (operands[0]) != REGNO (operands[1])"
17337 [(set (match_dup 0) (match_dup 3))
17338 (set (match_dup 0)
17339 (match_op_dup 2
17340 [(match_dup 5) (match_dup 4)]))]
17341 {
17342 operands[4] = operands[0];
17343 operands[5] = operands[1];
17344
17345 /* The % modifier is not operational anymore in peephole2's, so we have to
17346 swap the operands manually in the case of addition and multiplication. */
17347 if (COMMUTATIVE_ARITH_P (operands[2]))
17348 std::swap (operands[4], operands[5]);
17349 })
17350
17351 (define_peephole2
17352 [(set (match_operand 0 "fp_register_operand")
17353 (match_operand 1 "fp_register_operand"))
17354 (set (match_dup 0)
17355 (match_operator 2 "binary_fp_operator"
17356 [(match_operand 3 "memory_operand")
17357 (match_dup 0)]))]
17358 "REGNO (operands[0]) != REGNO (operands[1])"
17359 [(set (match_dup 0) (match_dup 3))
17360 (set (match_dup 0)
17361 (match_op_dup 2
17362 [(match_dup 4) (match_dup 5)]))]
17363 {
17364 operands[4] = operands[0];
17365 operands[5] = operands[1];
17366
17367 /* The % modifier is not operational anymore in peephole2's, so we have to
17368 swap the operands manually in the case of addition and multiplication. */
17369 if (COMMUTATIVE_ARITH_P (operands[2]))
17370 std::swap (operands[4], operands[5]);
17371 })
17372
17373 ;; Conditional addition patterns
17374 (define_expand "add<mode>cc"
17375 [(match_operand:SWI 0 "register_operand")
17376 (match_operand 1 "ordered_comparison_operator")
17377 (match_operand:SWI 2 "register_operand")
17378 (match_operand:SWI 3 "const_int_operand")]
17379 ""
17380 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17381 \f
17382 ;; Misc patterns (?)
17383
17384 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17385 ;; Otherwise there will be nothing to keep
17386 ;;
17387 ;; [(set (reg ebp) (reg esp))]
17388 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17389 ;; (clobber (eflags)]
17390 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17391 ;;
17392 ;; in proper program order.
17393
17394 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17395 [(set (match_operand:P 0 "register_operand" "=r,r")
17396 (plus:P (match_operand:P 1 "register_operand" "0,r")
17397 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17398 (clobber (reg:CC FLAGS_REG))
17399 (clobber (mem:BLK (scratch)))]
17400 ""
17401 {
17402 switch (get_attr_type (insn))
17403 {
17404 case TYPE_IMOV:
17405 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17406
17407 case TYPE_ALU:
17408 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17409 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17410 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17411
17412 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17413
17414 default:
17415 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17416 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17417 }
17418 }
17419 [(set (attr "type")
17420 (cond [(and (eq_attr "alternative" "0")
17421 (not (match_test "TARGET_OPT_AGU")))
17422 (const_string "alu")
17423 (match_operand:<MODE> 2 "const0_operand")
17424 (const_string "imov")
17425 ]
17426 (const_string "lea")))
17427 (set (attr "length_immediate")
17428 (cond [(eq_attr "type" "imov")
17429 (const_string "0")
17430 (and (eq_attr "type" "alu")
17431 (match_operand 2 "const128_operand"))
17432 (const_string "1")
17433 ]
17434 (const_string "*")))
17435 (set_attr "mode" "<MODE>")])
17436
17437 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17438 [(set (match_operand:P 0 "register_operand" "=r")
17439 (minus:P (match_operand:P 1 "register_operand" "0")
17440 (match_operand:P 2 "register_operand" "r")))
17441 (clobber (reg:CC FLAGS_REG))
17442 (clobber (mem:BLK (scratch)))]
17443 ""
17444 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17445 [(set_attr "type" "alu")
17446 (set_attr "mode" "<MODE>")])
17447
17448 (define_insn "allocate_stack_worker_probe_<mode>"
17449 [(set (match_operand:P 0 "register_operand" "=a")
17450 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17451 UNSPECV_STACK_PROBE))
17452 (clobber (reg:CC FLAGS_REG))]
17453 "ix86_target_stack_probe ()"
17454 "call\t___chkstk_ms"
17455 [(set_attr "type" "multi")
17456 (set_attr "length" "5")])
17457
17458 (define_expand "allocate_stack"
17459 [(match_operand 0 "register_operand")
17460 (match_operand 1 "general_operand")]
17461 "ix86_target_stack_probe ()"
17462 {
17463 rtx x;
17464
17465 #ifndef CHECK_STACK_LIMIT
17466 #define CHECK_STACK_LIMIT 0
17467 #endif
17468
17469 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17470 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17471 x = operands[1];
17472 else
17473 {
17474 rtx (*insn) (rtx, rtx);
17475
17476 x = copy_to_mode_reg (Pmode, operands[1]);
17477
17478 insn = (TARGET_64BIT
17479 ? gen_allocate_stack_worker_probe_di
17480 : gen_allocate_stack_worker_probe_si);
17481
17482 emit_insn (insn (x, x));
17483 }
17484
17485 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17486 stack_pointer_rtx, 0, OPTAB_DIRECT);
17487
17488 if (x != stack_pointer_rtx)
17489 emit_move_insn (stack_pointer_rtx, x);
17490
17491 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17492 DONE;
17493 })
17494
17495 (define_expand "probe_stack"
17496 [(match_operand 0 "memory_operand")]
17497 ""
17498 {
17499 rtx (*insn) (rtx, rtx)
17500 = (GET_MODE (operands[0]) == DImode
17501 ? gen_probe_stack_di : gen_probe_stack_si);
17502
17503 emit_insn (insn (operands[0], const0_rtx));
17504 DONE;
17505 })
17506
17507 ;; Use OR for stack probes, this is shorter.
17508 (define_insn "probe_stack_<mode>"
17509 [(set (match_operand:W 0 "memory_operand" "=m")
17510 (unspec:W [(match_operand:W 1 "const0_operand")]
17511 UNSPEC_PROBE_STACK))
17512 (clobber (reg:CC FLAGS_REG))]
17513 ""
17514 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17515 [(set_attr "type" "alu1")
17516 (set_attr "mode" "<MODE>")
17517 (set_attr "length_immediate" "1")])
17518
17519 (define_insn "adjust_stack_and_probe<mode>"
17520 [(set (match_operand:P 0 "register_operand" "=r")
17521 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17522 UNSPECV_PROBE_STACK_RANGE))
17523 (set (reg:P SP_REG)
17524 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17525 (clobber (reg:CC FLAGS_REG))
17526 (clobber (mem:BLK (scratch)))]
17527 ""
17528 "* return output_adjust_stack_and_probe (operands[0]);"
17529 [(set_attr "type" "multi")])
17530
17531 (define_insn "probe_stack_range<mode>"
17532 [(set (match_operand:P 0 "register_operand" "=r")
17533 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17534 (match_operand:P 2 "const_int_operand" "n")]
17535 UNSPECV_PROBE_STACK_RANGE))
17536 (clobber (reg:CC FLAGS_REG))]
17537 ""
17538 "* return output_probe_stack_range (operands[0], operands[2]);"
17539 [(set_attr "type" "multi")])
17540
17541 (define_expand "builtin_setjmp_receiver"
17542 [(label_ref (match_operand 0))]
17543 "!TARGET_64BIT && flag_pic"
17544 {
17545 #if TARGET_MACHO
17546 if (TARGET_MACHO)
17547 {
17548 rtx xops[3];
17549 rtx_code_label *label_rtx = gen_label_rtx ();
17550 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17551 xops[0] = xops[1] = pic_offset_table_rtx;
17552 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17553 ix86_expand_binary_operator (MINUS, SImode, xops);
17554 }
17555 else
17556 #endif
17557 emit_insn (gen_set_got (pic_offset_table_rtx));
17558 DONE;
17559 })
17560
17561 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17562 ;; Do not split instructions with mask registers.
17563 (define_split
17564 [(set (match_operand 0 "general_reg_operand")
17565 (match_operator 3 "promotable_binary_operator"
17566 [(match_operand 1 "general_reg_operand")
17567 (match_operand 2 "aligned_operand")]))
17568 (clobber (reg:CC FLAGS_REG))]
17569 "! TARGET_PARTIAL_REG_STALL && reload_completed
17570 && ((GET_MODE (operands[0]) == HImode
17571 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17572 /* ??? next two lines just !satisfies_constraint_K (...) */
17573 || !CONST_INT_P (operands[2])
17574 || satisfies_constraint_K (operands[2])))
17575 || (GET_MODE (operands[0]) == QImode
17576 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17577 [(parallel [(set (match_dup 0)
17578 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17579 (clobber (reg:CC FLAGS_REG))])]
17580 {
17581 operands[0] = gen_lowpart (SImode, operands[0]);
17582 operands[1] = gen_lowpart (SImode, operands[1]);
17583 if (GET_CODE (operands[3]) != ASHIFT)
17584 operands[2] = gen_lowpart (SImode, operands[2]);
17585 operands[3] = shallow_copy_rtx (operands[3]);
17586 PUT_MODE (operands[3], SImode);
17587 })
17588
17589 ; Promote the QImode tests, as i386 has encoding of the AND
17590 ; instruction with 32-bit sign-extended immediate and thus the
17591 ; instruction size is unchanged, except in the %eax case for
17592 ; which it is increased by one byte, hence the ! optimize_size.
17593 (define_split
17594 [(set (match_operand 0 "flags_reg_operand")
17595 (match_operator 2 "compare_operator"
17596 [(and (match_operand 3 "aligned_operand")
17597 (match_operand 4 "const_int_operand"))
17598 (const_int 0)]))
17599 (set (match_operand 1 "register_operand")
17600 (and (match_dup 3) (match_dup 4)))]
17601 "! TARGET_PARTIAL_REG_STALL && reload_completed
17602 && optimize_insn_for_speed_p ()
17603 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17604 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17605 /* Ensure that the operand will remain sign-extended immediate. */
17606 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17607 [(parallel [(set (match_dup 0)
17608 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17609 (const_int 0)]))
17610 (set (match_dup 1)
17611 (and:SI (match_dup 3) (match_dup 4)))])]
17612 {
17613 operands[4]
17614 = gen_int_mode (INTVAL (operands[4])
17615 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17616 operands[1] = gen_lowpart (SImode, operands[1]);
17617 operands[3] = gen_lowpart (SImode, operands[3]);
17618 })
17619
17620 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17621 ; the TEST instruction with 32-bit sign-extended immediate and thus
17622 ; the instruction size would at least double, which is not what we
17623 ; want even with ! optimize_size.
17624 (define_split
17625 [(set (match_operand 0 "flags_reg_operand")
17626 (match_operator 1 "compare_operator"
17627 [(and (match_operand:HI 2 "aligned_operand")
17628 (match_operand:HI 3 "const_int_operand"))
17629 (const_int 0)]))]
17630 "! TARGET_PARTIAL_REG_STALL && reload_completed
17631 && ! TARGET_FAST_PREFIX
17632 && optimize_insn_for_speed_p ()
17633 /* Ensure that the operand will remain sign-extended immediate. */
17634 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17635 [(set (match_dup 0)
17636 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17637 (const_int 0)]))]
17638 {
17639 operands[3]
17640 = gen_int_mode (INTVAL (operands[3])
17641 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17642 operands[2] = gen_lowpart (SImode, operands[2]);
17643 })
17644
17645 (define_split
17646 [(set (match_operand 0 "register_operand")
17647 (neg (match_operand 1 "register_operand")))
17648 (clobber (reg:CC FLAGS_REG))]
17649 "! TARGET_PARTIAL_REG_STALL && reload_completed
17650 && (GET_MODE (operands[0]) == HImode
17651 || (GET_MODE (operands[0]) == QImode
17652 && (TARGET_PROMOTE_QImode
17653 || optimize_insn_for_size_p ())))"
17654 [(parallel [(set (match_dup 0)
17655 (neg:SI (match_dup 1)))
17656 (clobber (reg:CC FLAGS_REG))])]
17657 {
17658 operands[0] = gen_lowpart (SImode, operands[0]);
17659 operands[1] = gen_lowpart (SImode, operands[1]);
17660 })
17661
17662 ;; Do not split instructions with mask regs.
17663 (define_split
17664 [(set (match_operand 0 "general_reg_operand")
17665 (not (match_operand 1 "general_reg_operand")))]
17666 "! TARGET_PARTIAL_REG_STALL && reload_completed
17667 && (GET_MODE (operands[0]) == HImode
17668 || (GET_MODE (operands[0]) == QImode
17669 && (TARGET_PROMOTE_QImode
17670 || optimize_insn_for_size_p ())))"
17671 [(set (match_dup 0)
17672 (not:SI (match_dup 1)))]
17673 {
17674 operands[0] = gen_lowpart (SImode, operands[0]);
17675 operands[1] = gen_lowpart (SImode, operands[1]);
17676 })
17677 \f
17678 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17679 ;; transform a complex memory operation into two memory to register operations.
17680
17681 ;; Don't push memory operands
17682 (define_peephole2
17683 [(set (match_operand:SWI 0 "push_operand")
17684 (match_operand:SWI 1 "memory_operand"))
17685 (match_scratch:SWI 2 "<r>")]
17686 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17687 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17688 [(set (match_dup 2) (match_dup 1))
17689 (set (match_dup 0) (match_dup 2))])
17690
17691 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17692 ;; SImode pushes.
17693 (define_peephole2
17694 [(set (match_operand:SF 0 "push_operand")
17695 (match_operand:SF 1 "memory_operand"))
17696 (match_scratch:SF 2 "r")]
17697 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17698 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17699 [(set (match_dup 2) (match_dup 1))
17700 (set (match_dup 0) (match_dup 2))])
17701
17702 ;; Don't move an immediate directly to memory when the instruction
17703 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17704 (define_peephole2
17705 [(match_scratch:SWI124 1 "<r>")
17706 (set (match_operand:SWI124 0 "memory_operand")
17707 (const_int 0))]
17708 "optimize_insn_for_speed_p ()
17709 && ((<MODE>mode == HImode
17710 && TARGET_LCP_STALL)
17711 || (!TARGET_USE_MOV0
17712 && TARGET_SPLIT_LONG_MOVES
17713 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17714 && peep2_regno_dead_p (0, FLAGS_REG)"
17715 [(parallel [(set (match_dup 2) (const_int 0))
17716 (clobber (reg:CC FLAGS_REG))])
17717 (set (match_dup 0) (match_dup 1))]
17718 "operands[2] = gen_lowpart (SImode, operands[1]);")
17719
17720 (define_peephole2
17721 [(match_scratch:SWI124 2 "<r>")
17722 (set (match_operand:SWI124 0 "memory_operand")
17723 (match_operand:SWI124 1 "immediate_operand"))]
17724 "optimize_insn_for_speed_p ()
17725 && ((<MODE>mode == HImode
17726 && TARGET_LCP_STALL)
17727 || (TARGET_SPLIT_LONG_MOVES
17728 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17729 [(set (match_dup 2) (match_dup 1))
17730 (set (match_dup 0) (match_dup 2))])
17731
17732 ;; Don't compare memory with zero, load and use a test instead.
17733 (define_peephole2
17734 [(set (match_operand 0 "flags_reg_operand")
17735 (match_operator 1 "compare_operator"
17736 [(match_operand:SI 2 "memory_operand")
17737 (const_int 0)]))
17738 (match_scratch:SI 3 "r")]
17739 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17740 [(set (match_dup 3) (match_dup 2))
17741 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17742
17743 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17744 ;; Don't split NOTs with a displacement operand, because resulting XOR
17745 ;; will not be pairable anyway.
17746 ;;
17747 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17748 ;; represented using a modRM byte. The XOR replacement is long decoded,
17749 ;; so this split helps here as well.
17750 ;;
17751 ;; Note: Can't do this as a regular split because we can't get proper
17752 ;; lifetime information then.
17753
17754 (define_peephole2
17755 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17756 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17757 "optimize_insn_for_speed_p ()
17758 && ((TARGET_NOT_UNPAIRABLE
17759 && (!MEM_P (operands[0])
17760 || !memory_displacement_operand (operands[0], <MODE>mode)))
17761 || (TARGET_NOT_VECTORMODE
17762 && long_memory_operand (operands[0], <MODE>mode)))
17763 && peep2_regno_dead_p (0, FLAGS_REG)"
17764 [(parallel [(set (match_dup 0)
17765 (xor:SWI124 (match_dup 1) (const_int -1)))
17766 (clobber (reg:CC FLAGS_REG))])])
17767
17768 ;; Non pairable "test imm, reg" instructions can be translated to
17769 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17770 ;; byte opcode instead of two, have a short form for byte operands),
17771 ;; so do it for other CPUs as well. Given that the value was dead,
17772 ;; this should not create any new dependencies. Pass on the sub-word
17773 ;; versions if we're concerned about partial register stalls.
17774
17775 (define_peephole2
17776 [(set (match_operand 0 "flags_reg_operand")
17777 (match_operator 1 "compare_operator"
17778 [(and:SI (match_operand:SI 2 "register_operand")
17779 (match_operand:SI 3 "immediate_operand"))
17780 (const_int 0)]))]
17781 "ix86_match_ccmode (insn, CCNOmode)
17782 && (REGNO (operands[2]) != AX_REG
17783 || satisfies_constraint_K (operands[3]))
17784 && peep2_reg_dead_p (1, operands[2])"
17785 [(parallel
17786 [(set (match_dup 0)
17787 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17788 (const_int 0)]))
17789 (set (match_dup 2)
17790 (and:SI (match_dup 2) (match_dup 3)))])])
17791
17792 ;; We don't need to handle HImode case, because it will be promoted to SImode
17793 ;; on ! TARGET_PARTIAL_REG_STALL
17794
17795 (define_peephole2
17796 [(set (match_operand 0 "flags_reg_operand")
17797 (match_operator 1 "compare_operator"
17798 [(and:QI (match_operand:QI 2 "register_operand")
17799 (match_operand:QI 3 "immediate_operand"))
17800 (const_int 0)]))]
17801 "! TARGET_PARTIAL_REG_STALL
17802 && ix86_match_ccmode (insn, CCNOmode)
17803 && REGNO (operands[2]) != AX_REG
17804 && peep2_reg_dead_p (1, operands[2])"
17805 [(parallel
17806 [(set (match_dup 0)
17807 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17808 (const_int 0)]))
17809 (set (match_dup 2)
17810 (and:QI (match_dup 2) (match_dup 3)))])])
17811
17812 (define_peephole2
17813 [(set (match_operand 0 "flags_reg_operand")
17814 (match_operator 1 "compare_operator"
17815 [(and:QI
17816 (subreg:QI
17817 (zero_extract:SI (match_operand 2 "QIreg_operand")
17818 (const_int 8)
17819 (const_int 8)) 0)
17820 (match_operand 3 "const_int_operand"))
17821 (const_int 0)]))]
17822 "! TARGET_PARTIAL_REG_STALL
17823 && ix86_match_ccmode (insn, CCNOmode)
17824 && REGNO (operands[2]) != AX_REG
17825 && peep2_reg_dead_p (1, operands[2])"
17826 [(parallel
17827 [(set (match_dup 0)
17828 (match_op_dup 1
17829 [(and:QI
17830 (subreg:QI
17831 (zero_extract:SI (match_dup 2)
17832 (const_int 8)
17833 (const_int 8)) 0)
17834 (match_dup 3))
17835 (const_int 0)]))
17836 (set (zero_extract:SI (match_dup 2)
17837 (const_int 8)
17838 (const_int 8))
17839 (subreg:SI
17840 (and:QI
17841 (subreg:QI
17842 (zero_extract:SI (match_dup 2)
17843 (const_int 8)
17844 (const_int 8)) 0)
17845 (match_dup 3)) 0))])])
17846
17847 ;; Don't do logical operations with memory inputs.
17848 (define_peephole2
17849 [(match_scratch:SWI 2 "<r>")
17850 (parallel [(set (match_operand:SWI 0 "register_operand")
17851 (match_operator:SWI 3 "arith_or_logical_operator"
17852 [(match_dup 0)
17853 (match_operand:SWI 1 "memory_operand")]))
17854 (clobber (reg:CC FLAGS_REG))])]
17855 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17856 [(set (match_dup 2) (match_dup 1))
17857 (parallel [(set (match_dup 0)
17858 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17859 (clobber (reg:CC FLAGS_REG))])])
17860
17861 (define_peephole2
17862 [(match_scratch:SWI 2 "<r>")
17863 (parallel [(set (match_operand:SWI 0 "register_operand")
17864 (match_operator:SWI 3 "arith_or_logical_operator"
17865 [(match_operand:SWI 1 "memory_operand")
17866 (match_dup 0)]))
17867 (clobber (reg:CC FLAGS_REG))])]
17868 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17869 [(set (match_dup 2) (match_dup 1))
17870 (parallel [(set (match_dup 0)
17871 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17872 (clobber (reg:CC FLAGS_REG))])])
17873
17874 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
17875 ;; the memory address refers to the destination of the load!
17876
17877 (define_peephole2
17878 [(set (match_operand:SWI 0 "general_reg_operand")
17879 (match_operand:SWI 1 "general_reg_operand"))
17880 (parallel [(set (match_dup 0)
17881 (match_operator:SWI 3 "commutative_operator"
17882 [(match_dup 0)
17883 (match_operand:SWI 2 "memory_operand")]))
17884 (clobber (reg:CC FLAGS_REG))])]
17885 "REGNO (operands[0]) != REGNO (operands[1])
17886 && (<MODE>mode != QImode
17887 || any_QIreg_operand (operands[1], QImode))"
17888 [(set (match_dup 0) (match_dup 4))
17889 (parallel [(set (match_dup 0)
17890 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17891 (clobber (reg:CC FLAGS_REG))])]
17892 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
17893
17894 (define_peephole2
17895 [(set (match_operand 0 "mmx_reg_operand")
17896 (match_operand 1 "mmx_reg_operand"))
17897 (set (match_dup 0)
17898 (match_operator 3 "commutative_operator"
17899 [(match_dup 0)
17900 (match_operand 2 "memory_operand")]))]
17901 "REGNO (operands[0]) != REGNO (operands[1])"
17902 [(set (match_dup 0) (match_dup 2))
17903 (set (match_dup 0)
17904 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17905
17906 (define_peephole2
17907 [(set (match_operand 0 "sse_reg_operand")
17908 (match_operand 1 "sse_reg_operand"))
17909 (set (match_dup 0)
17910 (match_operator 3 "commutative_operator"
17911 [(match_dup 0)
17912 (match_operand 2 "memory_operand")]))]
17913 "REGNO (operands[0]) != REGNO (operands[1])"
17914 [(set (match_dup 0) (match_dup 2))
17915 (set (match_dup 0)
17916 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17917
17918 ; Don't do logical operations with memory outputs
17919 ;
17920 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17921 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17922 ; the same decoder scheduling characteristics as the original.
17923
17924 (define_peephole2
17925 [(match_scratch:SWI 2 "<r>")
17926 (parallel [(set (match_operand:SWI 0 "memory_operand")
17927 (match_operator:SWI 3 "arith_or_logical_operator"
17928 [(match_dup 0)
17929 (match_operand:SWI 1 "<nonmemory_operand>")]))
17930 (clobber (reg:CC FLAGS_REG))])]
17931 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
17932 [(set (match_dup 2) (match_dup 0))
17933 (parallel [(set (match_dup 2)
17934 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17935 (clobber (reg:CC FLAGS_REG))])
17936 (set (match_dup 0) (match_dup 2))])
17937
17938 (define_peephole2
17939 [(match_scratch:SWI 2 "<r>")
17940 (parallel [(set (match_operand:SWI 0 "memory_operand")
17941 (match_operator:SWI 3 "arith_or_logical_operator"
17942 [(match_operand:SWI 1 "<nonmemory_operand>")
17943 (match_dup 0)]))
17944 (clobber (reg:CC FLAGS_REG))])]
17945 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
17946 [(set (match_dup 2) (match_dup 0))
17947 (parallel [(set (match_dup 2)
17948 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17949 (clobber (reg:CC FLAGS_REG))])
17950 (set (match_dup 0) (match_dup 2))])
17951
17952 ;; Attempt to use arith or logical operations with memory outputs with
17953 ;; setting of flags.
17954 (define_peephole2
17955 [(set (match_operand:SWI 0 "register_operand")
17956 (match_operand:SWI 1 "memory_operand"))
17957 (parallel [(set (match_dup 0)
17958 (match_operator:SWI 3 "plusminuslogic_operator"
17959 [(match_dup 0)
17960 (match_operand:SWI 2 "<nonmemory_operand>")]))
17961 (clobber (reg:CC FLAGS_REG))])
17962 (set (match_dup 1) (match_dup 0))
17963 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17964 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17965 && peep2_reg_dead_p (4, operands[0])
17966 && !reg_overlap_mentioned_p (operands[0], operands[1])
17967 && !reg_overlap_mentioned_p (operands[0], operands[2])
17968 && (<MODE>mode != QImode
17969 || immediate_operand (operands[2], QImode)
17970 || any_QIreg_operand (operands[2], QImode))
17971 && ix86_match_ccmode (peep2_next_insn (3),
17972 (GET_CODE (operands[3]) == PLUS
17973 || GET_CODE (operands[3]) == MINUS)
17974 ? CCGOCmode : CCNOmode)"
17975 [(parallel [(set (match_dup 4) (match_dup 6))
17976 (set (match_dup 1) (match_dup 5))])]
17977 {
17978 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17979 operands[5]
17980 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
17981 copy_rtx (operands[1]),
17982 operands[2]);
17983 operands[6]
17984 = gen_rtx_COMPARE (GET_MODE (operands[4]),
17985 copy_rtx (operands[5]),
17986 const0_rtx);
17987 })
17988
17989 ;; Likewise for instances where we have a lea pattern.
17990 (define_peephole2
17991 [(set (match_operand:SWI 0 "register_operand")
17992 (match_operand:SWI 1 "memory_operand"))
17993 (set (match_operand:SWI 3 "register_operand")
17994 (plus:SWI (match_dup 0)
17995 (match_operand:SWI 2 "<nonmemory_operand>")))
17996 (set (match_dup 1) (match_dup 3))
17997 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
17998 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17999 && peep2_reg_dead_p (4, operands[3])
18000 && (rtx_equal_p (operands[0], operands[3])
18001 || peep2_reg_dead_p (2, operands[0]))
18002 && !reg_overlap_mentioned_p (operands[0], operands[1])
18003 && !reg_overlap_mentioned_p (operands[3], operands[1])
18004 && !reg_overlap_mentioned_p (operands[0], operands[2])
18005 && (<MODE>mode != QImode
18006 || immediate_operand (operands[2], QImode)
18007 || any_QIreg_operand (operands[2], QImode))
18008 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18009 [(parallel [(set (match_dup 4) (match_dup 6))
18010 (set (match_dup 1) (match_dup 5))])]
18011 {
18012 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18013 operands[5]
18014 = gen_rtx_PLUS (<MODE>mode,
18015 copy_rtx (operands[1]),
18016 operands[2]);
18017 operands[6]
18018 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18019 copy_rtx (operands[5]),
18020 const0_rtx);
18021 })
18022
18023 (define_peephole2
18024 [(parallel [(set (match_operand:SWI 0 "register_operand")
18025 (match_operator:SWI 2 "plusminuslogic_operator"
18026 [(match_dup 0)
18027 (match_operand:SWI 1 "memory_operand")]))
18028 (clobber (reg:CC FLAGS_REG))])
18029 (set (match_dup 1) (match_dup 0))
18030 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18031 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18032 && GET_CODE (operands[2]) != MINUS
18033 && peep2_reg_dead_p (3, operands[0])
18034 && !reg_overlap_mentioned_p (operands[0], operands[1])
18035 && ix86_match_ccmode (peep2_next_insn (2),
18036 GET_CODE (operands[2]) == PLUS
18037 ? CCGOCmode : CCNOmode)"
18038 [(parallel [(set (match_dup 3) (match_dup 5))
18039 (set (match_dup 1) (match_dup 4))])]
18040 {
18041 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18042 operands[4]
18043 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18044 copy_rtx (operands[1]),
18045 operands[0]);
18046 operands[5]
18047 = gen_rtx_COMPARE (GET_MODE (operands[3]),
18048 copy_rtx (operands[4]),
18049 const0_rtx);
18050 })
18051
18052 (define_peephole2
18053 [(set (match_operand:SWI12 0 "register_operand")
18054 (match_operand:SWI12 1 "memory_operand"))
18055 (parallel [(set (match_operand:SI 4 "register_operand")
18056 (match_operator:SI 3 "plusminuslogic_operator"
18057 [(match_dup 4)
18058 (match_operand:SI 2 "nonmemory_operand")]))
18059 (clobber (reg:CC FLAGS_REG))])
18060 (set (match_dup 1) (match_dup 0))
18061 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18062 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18063 && REGNO (operands[0]) == REGNO (operands[4])
18064 && peep2_reg_dead_p (4, operands[0])
18065 && (<MODE>mode != QImode
18066 || immediate_operand (operands[2], SImode)
18067 || any_QIreg_operand (operands[2], SImode))
18068 && !reg_overlap_mentioned_p (operands[0], operands[1])
18069 && !reg_overlap_mentioned_p (operands[0], operands[2])
18070 && ix86_match_ccmode (peep2_next_insn (3),
18071 (GET_CODE (operands[3]) == PLUS
18072 || GET_CODE (operands[3]) == MINUS)
18073 ? CCGOCmode : CCNOmode)"
18074 [(parallel [(set (match_dup 4) (match_dup 6))
18075 (set (match_dup 1) (match_dup 5))])]
18076 {
18077 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18078 operands[5]
18079 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18080 copy_rtx (operands[1]),
18081 gen_lowpart (<MODE>mode, operands[2]));
18082 operands[6]
18083 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18084 copy_rtx (operands[5]),
18085 const0_rtx);
18086 })
18087
18088 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18089 (define_peephole2
18090 [(set (match_operand 0 "general_reg_operand")
18091 (match_operand 1 "const0_operand"))]
18092 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18093 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18094 && peep2_regno_dead_p (0, FLAGS_REG)"
18095 [(parallel [(set (match_dup 0) (const_int 0))
18096 (clobber (reg:CC FLAGS_REG))])]
18097 "operands[0] = gen_lowpart (word_mode, operands[0]);")
18098
18099 (define_peephole2
18100 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18101 (const_int 0))]
18102 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18103 && peep2_regno_dead_p (0, FLAGS_REG)"
18104 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18105 (clobber (reg:CC FLAGS_REG))])])
18106
18107 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18108 (define_peephole2
18109 [(set (match_operand:SWI248 0 "general_reg_operand")
18110 (const_int -1))]
18111 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18112 && peep2_regno_dead_p (0, FLAGS_REG)"
18113 [(parallel [(set (match_dup 0) (const_int -1))
18114 (clobber (reg:CC FLAGS_REG))])]
18115 {
18116 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18117 operands[0] = gen_lowpart (SImode, operands[0]);
18118 })
18119
18120 ;; Attempt to convert simple lea to add/shift.
18121 ;; These can be created by move expanders.
18122 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18123 ;; relevant lea instructions were already split.
18124
18125 (define_peephole2
18126 [(set (match_operand:SWI48 0 "register_operand")
18127 (plus:SWI48 (match_dup 0)
18128 (match_operand:SWI48 1 "<nonmemory_operand>")))]
18129 "!TARGET_OPT_AGU
18130 && peep2_regno_dead_p (0, FLAGS_REG)"
18131 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18132 (clobber (reg:CC FLAGS_REG))])])
18133
18134 (define_peephole2
18135 [(set (match_operand:SWI48 0 "register_operand")
18136 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18137 (match_dup 0)))]
18138 "!TARGET_OPT_AGU
18139 && peep2_regno_dead_p (0, FLAGS_REG)"
18140 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18141 (clobber (reg:CC FLAGS_REG))])])
18142
18143 (define_peephole2
18144 [(set (match_operand:DI 0 "register_operand")
18145 (zero_extend:DI
18146 (plus:SI (match_operand:SI 1 "register_operand")
18147 (match_operand:SI 2 "nonmemory_operand"))))]
18148 "TARGET_64BIT && !TARGET_OPT_AGU
18149 && REGNO (operands[0]) == REGNO (operands[1])
18150 && peep2_regno_dead_p (0, FLAGS_REG)"
18151 [(parallel [(set (match_dup 0)
18152 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18153 (clobber (reg:CC FLAGS_REG))])])
18154
18155 (define_peephole2
18156 [(set (match_operand:DI 0 "register_operand")
18157 (zero_extend:DI
18158 (plus:SI (match_operand:SI 1 "nonmemory_operand")
18159 (match_operand:SI 2 "register_operand"))))]
18160 "TARGET_64BIT && !TARGET_OPT_AGU
18161 && REGNO (operands[0]) == REGNO (operands[2])
18162 && peep2_regno_dead_p (0, FLAGS_REG)"
18163 [(parallel [(set (match_dup 0)
18164 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18165 (clobber (reg:CC FLAGS_REG))])])
18166
18167 (define_peephole2
18168 [(set (match_operand:SWI48 0 "register_operand")
18169 (mult:SWI48 (match_dup 0)
18170 (match_operand:SWI48 1 "const_int_operand")))]
18171 "pow2p_hwi (INTVAL (operands[1]))
18172 && peep2_regno_dead_p (0, FLAGS_REG)"
18173 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18174 (clobber (reg:CC FLAGS_REG))])]
18175 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18176
18177 (define_peephole2
18178 [(set (match_operand:DI 0 "register_operand")
18179 (zero_extend:DI
18180 (mult:SI (match_operand:SI 1 "register_operand")
18181 (match_operand:SI 2 "const_int_operand"))))]
18182 "TARGET_64BIT
18183 && pow2p_hwi (INTVAL (operands[2]))
18184 && REGNO (operands[0]) == REGNO (operands[1])
18185 && peep2_regno_dead_p (0, FLAGS_REG)"
18186 [(parallel [(set (match_dup 0)
18187 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18188 (clobber (reg:CC FLAGS_REG))])]
18189 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18190
18191 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18192 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18193 ;; On many CPUs it is also faster, since special hardware to avoid esp
18194 ;; dependencies is present.
18195
18196 ;; While some of these conversions may be done using splitters, we use
18197 ;; peepholes in order to allow combine_stack_adjustments pass to see
18198 ;; nonobfuscated RTL.
18199
18200 ;; Convert prologue esp subtractions to push.
18201 ;; We need register to push. In order to keep verify_flow_info happy we have
18202 ;; two choices
18203 ;; - use scratch and clobber it in order to avoid dependencies
18204 ;; - use already live register
18205 ;; We can't use the second way right now, since there is no reliable way how to
18206 ;; verify that given register is live. First choice will also most likely in
18207 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18208 ;; call clobbered registers are dead. We may want to use base pointer as an
18209 ;; alternative when no register is available later.
18210
18211 (define_peephole2
18212 [(match_scratch:W 1 "r")
18213 (parallel [(set (reg:P SP_REG)
18214 (plus:P (reg:P SP_REG)
18215 (match_operand:P 0 "const_int_operand")))
18216 (clobber (reg:CC FLAGS_REG))
18217 (clobber (mem:BLK (scratch)))])]
18218 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18219 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18220 && !ix86_using_red_zone ()"
18221 [(clobber (match_dup 1))
18222 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18223 (clobber (mem:BLK (scratch)))])])
18224
18225 (define_peephole2
18226 [(match_scratch:W 1 "r")
18227 (parallel [(set (reg:P SP_REG)
18228 (plus:P (reg:P SP_REG)
18229 (match_operand:P 0 "const_int_operand")))
18230 (clobber (reg:CC FLAGS_REG))
18231 (clobber (mem:BLK (scratch)))])]
18232 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18233 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18234 && !ix86_using_red_zone ()"
18235 [(clobber (match_dup 1))
18236 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18237 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18238 (clobber (mem:BLK (scratch)))])])
18239
18240 ;; Convert esp subtractions to push.
18241 (define_peephole2
18242 [(match_scratch:W 1 "r")
18243 (parallel [(set (reg:P SP_REG)
18244 (plus:P (reg:P SP_REG)
18245 (match_operand:P 0 "const_int_operand")))
18246 (clobber (reg:CC FLAGS_REG))])]
18247 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18248 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18249 && !ix86_using_red_zone ()"
18250 [(clobber (match_dup 1))
18251 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18252
18253 (define_peephole2
18254 [(match_scratch:W 1 "r")
18255 (parallel [(set (reg:P SP_REG)
18256 (plus:P (reg:P SP_REG)
18257 (match_operand:P 0 "const_int_operand")))
18258 (clobber (reg:CC FLAGS_REG))])]
18259 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18260 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18261 && !ix86_using_red_zone ()"
18262 [(clobber (match_dup 1))
18263 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18264 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18265
18266 ;; Convert epilogue deallocator to pop.
18267 (define_peephole2
18268 [(match_scratch:W 1 "r")
18269 (parallel [(set (reg:P SP_REG)
18270 (plus:P (reg:P SP_REG)
18271 (match_operand:P 0 "const_int_operand")))
18272 (clobber (reg:CC FLAGS_REG))
18273 (clobber (mem:BLK (scratch)))])]
18274 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18275 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18276 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18277 (clobber (mem:BLK (scratch)))])])
18278
18279 ;; Two pops case is tricky, since pop causes dependency
18280 ;; on destination register. We use two registers if available.
18281 (define_peephole2
18282 [(match_scratch:W 1 "r")
18283 (match_scratch:W 2 "r")
18284 (parallel [(set (reg:P SP_REG)
18285 (plus:P (reg:P SP_REG)
18286 (match_operand:P 0 "const_int_operand")))
18287 (clobber (reg:CC FLAGS_REG))
18288 (clobber (mem:BLK (scratch)))])]
18289 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18290 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18291 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18292 (clobber (mem:BLK (scratch)))])
18293 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18294
18295 (define_peephole2
18296 [(match_scratch:W 1 "r")
18297 (parallel [(set (reg:P SP_REG)
18298 (plus:P (reg:P SP_REG)
18299 (match_operand:P 0 "const_int_operand")))
18300 (clobber (reg:CC FLAGS_REG))
18301 (clobber (mem:BLK (scratch)))])]
18302 "optimize_insn_for_size_p ()
18303 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18304 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18305 (clobber (mem:BLK (scratch)))])
18306 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18307
18308 ;; Convert esp additions to pop.
18309 (define_peephole2
18310 [(match_scratch:W 1 "r")
18311 (parallel [(set (reg:P SP_REG)
18312 (plus:P (reg:P SP_REG)
18313 (match_operand:P 0 "const_int_operand")))
18314 (clobber (reg:CC FLAGS_REG))])]
18315 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18316 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18317
18318 ;; Two pops case is tricky, since pop causes dependency
18319 ;; on destination register. We use two registers if available.
18320 (define_peephole2
18321 [(match_scratch:W 1 "r")
18322 (match_scratch:W 2 "r")
18323 (parallel [(set (reg:P SP_REG)
18324 (plus:P (reg:P SP_REG)
18325 (match_operand:P 0 "const_int_operand")))
18326 (clobber (reg:CC FLAGS_REG))])]
18327 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18328 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18329 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18330
18331 (define_peephole2
18332 [(match_scratch:W 1 "r")
18333 (parallel [(set (reg:P SP_REG)
18334 (plus:P (reg:P SP_REG)
18335 (match_operand:P 0 "const_int_operand")))
18336 (clobber (reg:CC FLAGS_REG))])]
18337 "optimize_insn_for_size_p ()
18338 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18339 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18340 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18341 \f
18342 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18343 ;; required and register dies. Similarly for 128 to -128.
18344 (define_peephole2
18345 [(set (match_operand 0 "flags_reg_operand")
18346 (match_operator 1 "compare_operator"
18347 [(match_operand 2 "register_operand")
18348 (match_operand 3 "const_int_operand")]))]
18349 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18350 && incdec_operand (operands[3], GET_MODE (operands[3])))
18351 || (!TARGET_FUSE_CMP_AND_BRANCH
18352 && INTVAL (operands[3]) == 128))
18353 && ix86_match_ccmode (insn, CCGCmode)
18354 && peep2_reg_dead_p (1, operands[2])"
18355 [(parallel [(set (match_dup 0)
18356 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18357 (clobber (match_dup 2))])])
18358 \f
18359 ;; Convert imul by three, five and nine into lea
18360 (define_peephole2
18361 [(parallel
18362 [(set (match_operand:SWI48 0 "register_operand")
18363 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18364 (match_operand:SWI48 2 "const359_operand")))
18365 (clobber (reg:CC FLAGS_REG))])]
18366 "!TARGET_PARTIAL_REG_STALL
18367 || <MODE>mode == SImode
18368 || optimize_function_for_size_p (cfun)"
18369 [(set (match_dup 0)
18370 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18371 (match_dup 1)))]
18372 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18373
18374 (define_peephole2
18375 [(parallel
18376 [(set (match_operand:SWI48 0 "register_operand")
18377 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18378 (match_operand:SWI48 2 "const359_operand")))
18379 (clobber (reg:CC FLAGS_REG))])]
18380 "optimize_insn_for_speed_p ()
18381 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18382 [(set (match_dup 0) (match_dup 1))
18383 (set (match_dup 0)
18384 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18385 (match_dup 0)))]
18386 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18387
18388 ;; imul $32bit_imm, mem, reg is vector decoded, while
18389 ;; imul $32bit_imm, reg, reg is direct decoded.
18390 (define_peephole2
18391 [(match_scratch:SWI48 3 "r")
18392 (parallel [(set (match_operand:SWI48 0 "register_operand")
18393 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18394 (match_operand:SWI48 2 "immediate_operand")))
18395 (clobber (reg:CC FLAGS_REG))])]
18396 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18397 && !satisfies_constraint_K (operands[2])"
18398 [(set (match_dup 3) (match_dup 1))
18399 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18400 (clobber (reg:CC FLAGS_REG))])])
18401
18402 (define_peephole2
18403 [(match_scratch:SI 3 "r")
18404 (parallel [(set (match_operand:DI 0 "register_operand")
18405 (zero_extend:DI
18406 (mult:SI (match_operand:SI 1 "memory_operand")
18407 (match_operand:SI 2 "immediate_operand"))))
18408 (clobber (reg:CC FLAGS_REG))])]
18409 "TARGET_64BIT
18410 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18411 && !satisfies_constraint_K (operands[2])"
18412 [(set (match_dup 3) (match_dup 1))
18413 (parallel [(set (match_dup 0)
18414 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18415 (clobber (reg:CC FLAGS_REG))])])
18416
18417 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18418 ;; Convert it into imul reg, reg
18419 ;; It would be better to force assembler to encode instruction using long
18420 ;; immediate, but there is apparently no way to do so.
18421 (define_peephole2
18422 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18423 (mult:SWI248
18424 (match_operand:SWI248 1 "nonimmediate_operand")
18425 (match_operand:SWI248 2 "const_int_operand")))
18426 (clobber (reg:CC FLAGS_REG))])
18427 (match_scratch:SWI248 3 "r")]
18428 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18429 && satisfies_constraint_K (operands[2])"
18430 [(set (match_dup 3) (match_dup 2))
18431 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18432 (clobber (reg:CC FLAGS_REG))])]
18433 {
18434 if (!rtx_equal_p (operands[0], operands[1]))
18435 emit_move_insn (operands[0], operands[1]);
18436 })
18437
18438 ;; After splitting up read-modify operations, array accesses with memory
18439 ;; operands might end up in form:
18440 ;; sall $2, %eax
18441 ;; movl 4(%esp), %edx
18442 ;; addl %edx, %eax
18443 ;; instead of pre-splitting:
18444 ;; sall $2, %eax
18445 ;; addl 4(%esp), %eax
18446 ;; Turn it into:
18447 ;; movl 4(%esp), %edx
18448 ;; leal (%edx,%eax,4), %eax
18449
18450 (define_peephole2
18451 [(match_scratch:W 5 "r")
18452 (parallel [(set (match_operand 0 "register_operand")
18453 (ashift (match_operand 1 "register_operand")
18454 (match_operand 2 "const_int_operand")))
18455 (clobber (reg:CC FLAGS_REG))])
18456 (parallel [(set (match_operand 3 "register_operand")
18457 (plus (match_dup 0)
18458 (match_operand 4 "x86_64_general_operand")))
18459 (clobber (reg:CC FLAGS_REG))])]
18460 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18461 /* Validate MODE for lea. */
18462 && ((!TARGET_PARTIAL_REG_STALL
18463 && (GET_MODE (operands[0]) == QImode
18464 || GET_MODE (operands[0]) == HImode))
18465 || GET_MODE (operands[0]) == SImode
18466 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18467 && (rtx_equal_p (operands[0], operands[3])
18468 || peep2_reg_dead_p (2, operands[0]))
18469 /* We reorder load and the shift. */
18470 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18471 [(set (match_dup 5) (match_dup 4))
18472 (set (match_dup 0) (match_dup 1))]
18473 {
18474 machine_mode op1mode = GET_MODE (operands[1]);
18475 machine_mode mode = op1mode == DImode ? DImode : SImode;
18476 int scale = 1 << INTVAL (operands[2]);
18477 rtx index = gen_lowpart (word_mode, operands[1]);
18478 rtx base = gen_lowpart (word_mode, operands[5]);
18479 rtx dest = gen_lowpart (mode, operands[3]);
18480
18481 operands[1] = gen_rtx_PLUS (word_mode, base,
18482 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18483 if (mode != word_mode)
18484 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18485
18486 operands[5] = base;
18487 if (op1mode != word_mode)
18488 operands[5] = gen_lowpart (op1mode, operands[5]);
18489
18490 operands[0] = dest;
18491 })
18492 \f
18493 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18494 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18495 ;; caught for use by garbage collectors and the like. Using an insn that
18496 ;; maps to SIGILL makes it more likely the program will rightfully die.
18497 ;; Keeping with tradition, "6" is in honor of #UD.
18498 (define_insn "trap"
18499 [(trap_if (const_int 1) (const_int 6))]
18500 ""
18501 {
18502 #ifdef HAVE_AS_IX86_UD2
18503 return "ud2";
18504 #else
18505 return ASM_SHORT "0x0b0f";
18506 #endif
18507 }
18508 [(set_attr "length" "2")])
18509
18510 (define_expand "prefetch"
18511 [(prefetch (match_operand 0 "address_operand")
18512 (match_operand:SI 1 "const_int_operand")
18513 (match_operand:SI 2 "const_int_operand"))]
18514 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18515 {
18516 bool write = INTVAL (operands[1]) != 0;
18517 int locality = INTVAL (operands[2]);
18518
18519 gcc_assert (IN_RANGE (locality, 0, 3));
18520
18521 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18522 supported by SSE counterpart (non-SSE2 athlon machines) or the
18523 SSE prefetch is not available (K6 machines). Otherwise use SSE
18524 prefetch as it allows specifying of locality. */
18525
18526 if (write)
18527 {
18528 if (TARGET_PREFETCHWT1)
18529 operands[2] = GEN_INT (MAX (locality, 2));
18530 else if (TARGET_PRFCHW)
18531 operands[2] = GEN_INT (3);
18532 else if (TARGET_3DNOW && !TARGET_SSE2)
18533 operands[2] = GEN_INT (3);
18534 else if (TARGET_PREFETCH_SSE)
18535 operands[1] = const0_rtx;
18536 else
18537 {
18538 gcc_assert (TARGET_3DNOW);
18539 operands[2] = GEN_INT (3);
18540 }
18541 }
18542 else
18543 {
18544 if (TARGET_PREFETCH_SSE)
18545 ;
18546 else
18547 {
18548 gcc_assert (TARGET_3DNOW);
18549 operands[2] = GEN_INT (3);
18550 }
18551 }
18552 })
18553
18554 (define_insn "*prefetch_sse"
18555 [(prefetch (match_operand 0 "address_operand" "p")
18556 (const_int 0)
18557 (match_operand:SI 1 "const_int_operand"))]
18558 "TARGET_PREFETCH_SSE"
18559 {
18560 static const char * const patterns[4] = {
18561 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18562 };
18563
18564 int locality = INTVAL (operands[1]);
18565 gcc_assert (IN_RANGE (locality, 0, 3));
18566
18567 return patterns[locality];
18568 }
18569 [(set_attr "type" "sse")
18570 (set_attr "atom_sse_attr" "prefetch")
18571 (set (attr "length_address")
18572 (symbol_ref "memory_address_length (operands[0], false)"))
18573 (set_attr "memory" "none")])
18574
18575 (define_insn "*prefetch_3dnow"
18576 [(prefetch (match_operand 0 "address_operand" "p")
18577 (match_operand:SI 1 "const_int_operand" "n")
18578 (const_int 3))]
18579 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18580 {
18581 if (INTVAL (operands[1]) == 0)
18582 return "prefetch\t%a0";
18583 else
18584 return "prefetchw\t%a0";
18585 }
18586 [(set_attr "type" "mmx")
18587 (set (attr "length_address")
18588 (symbol_ref "memory_address_length (operands[0], false)"))
18589 (set_attr "memory" "none")])
18590
18591 (define_insn "*prefetch_prefetchwt1"
18592 [(prefetch (match_operand 0 "address_operand" "p")
18593 (const_int 1)
18594 (const_int 2))]
18595 "TARGET_PREFETCHWT1"
18596 "prefetchwt1\t%a0";
18597 [(set_attr "type" "sse")
18598 (set (attr "length_address")
18599 (symbol_ref "memory_address_length (operands[0], false)"))
18600 (set_attr "memory" "none")])
18601
18602 (define_expand "stack_protect_set"
18603 [(match_operand 0 "memory_operand")
18604 (match_operand 1 "memory_operand")]
18605 "TARGET_SSP_TLS_GUARD"
18606 {
18607 rtx (*insn)(rtx, rtx);
18608
18609 #ifdef TARGET_THREAD_SSP_OFFSET
18610 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18611 insn = (TARGET_LP64
18612 ? gen_stack_tls_protect_set_di
18613 : gen_stack_tls_protect_set_si);
18614 #else
18615 insn = (TARGET_LP64
18616 ? gen_stack_protect_set_di
18617 : gen_stack_protect_set_si);
18618 #endif
18619
18620 emit_insn (insn (operands[0], operands[1]));
18621 DONE;
18622 })
18623
18624 (define_insn "stack_protect_set_<mode>"
18625 [(set (match_operand:PTR 0 "memory_operand" "=m")
18626 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18627 UNSPEC_SP_SET))
18628 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18629 (clobber (reg:CC FLAGS_REG))]
18630 "TARGET_SSP_TLS_GUARD"
18631 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18632 [(set_attr "type" "multi")])
18633
18634 (define_insn "stack_tls_protect_set_<mode>"
18635 [(set (match_operand:PTR 0 "memory_operand" "=m")
18636 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18637 UNSPEC_SP_TLS_SET))
18638 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18639 (clobber (reg:CC FLAGS_REG))]
18640 ""
18641 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18642 [(set_attr "type" "multi")])
18643
18644 (define_expand "stack_protect_test"
18645 [(match_operand 0 "memory_operand")
18646 (match_operand 1 "memory_operand")
18647 (match_operand 2)]
18648 "TARGET_SSP_TLS_GUARD"
18649 {
18650 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18651
18652 rtx (*insn)(rtx, rtx, rtx);
18653
18654 #ifdef TARGET_THREAD_SSP_OFFSET
18655 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18656 insn = (TARGET_LP64
18657 ? gen_stack_tls_protect_test_di
18658 : gen_stack_tls_protect_test_si);
18659 #else
18660 insn = (TARGET_LP64
18661 ? gen_stack_protect_test_di
18662 : gen_stack_protect_test_si);
18663 #endif
18664
18665 emit_insn (insn (flags, operands[0], operands[1]));
18666
18667 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18668 flags, const0_rtx, operands[2]));
18669 DONE;
18670 })
18671
18672 (define_insn "stack_protect_test_<mode>"
18673 [(set (match_operand:CCZ 0 "flags_reg_operand")
18674 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18675 (match_operand:PTR 2 "memory_operand" "m")]
18676 UNSPEC_SP_TEST))
18677 (clobber (match_scratch:PTR 3 "=&r"))]
18678 "TARGET_SSP_TLS_GUARD"
18679 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18680 [(set_attr "type" "multi")])
18681
18682 (define_insn "stack_tls_protect_test_<mode>"
18683 [(set (match_operand:CCZ 0 "flags_reg_operand")
18684 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18685 (match_operand:PTR 2 "const_int_operand" "i")]
18686 UNSPEC_SP_TLS_TEST))
18687 (clobber (match_scratch:PTR 3 "=r"))]
18688 ""
18689 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18690 [(set_attr "type" "multi")])
18691
18692 (define_insn "sse4_2_crc32<mode>"
18693 [(set (match_operand:SI 0 "register_operand" "=r")
18694 (unspec:SI
18695 [(match_operand:SI 1 "register_operand" "0")
18696 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18697 UNSPEC_CRC32))]
18698 "TARGET_SSE4_2 || TARGET_CRC32"
18699 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18700 [(set_attr "type" "sselog1")
18701 (set_attr "prefix_rep" "1")
18702 (set_attr "prefix_extra" "1")
18703 (set (attr "prefix_data16")
18704 (if_then_else (match_operand:HI 2)
18705 (const_string "1")
18706 (const_string "*")))
18707 (set (attr "prefix_rex")
18708 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18709 (const_string "1")
18710 (const_string "*")))
18711 (set_attr "mode" "SI")])
18712
18713 (define_insn "sse4_2_crc32di"
18714 [(set (match_operand:DI 0 "register_operand" "=r")
18715 (unspec:DI
18716 [(match_operand:DI 1 "register_operand" "0")
18717 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18718 UNSPEC_CRC32))]
18719 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18720 "crc32{q}\t{%2, %0|%0, %2}"
18721 [(set_attr "type" "sselog1")
18722 (set_attr "prefix_rep" "1")
18723 (set_attr "prefix_extra" "1")
18724 (set_attr "mode" "DI")])
18725
18726 (define_insn "rdpmc"
18727 [(set (match_operand:DI 0 "register_operand" "=A")
18728 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18729 UNSPECV_RDPMC))]
18730 "!TARGET_64BIT"
18731 "rdpmc"
18732 [(set_attr "type" "other")
18733 (set_attr "length" "2")])
18734
18735 (define_insn "rdpmc_rex64"
18736 [(set (match_operand:DI 0 "register_operand" "=a")
18737 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18738 UNSPECV_RDPMC))
18739 (set (match_operand:DI 1 "register_operand" "=d")
18740 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18741 "TARGET_64BIT"
18742 "rdpmc"
18743 [(set_attr "type" "other")
18744 (set_attr "length" "2")])
18745
18746 (define_insn "rdtsc"
18747 [(set (match_operand:DI 0 "register_operand" "=A")
18748 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18749 "!TARGET_64BIT"
18750 "rdtsc"
18751 [(set_attr "type" "other")
18752 (set_attr "length" "2")])
18753
18754 (define_insn "rdtsc_rex64"
18755 [(set (match_operand:DI 0 "register_operand" "=a")
18756 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18757 (set (match_operand:DI 1 "register_operand" "=d")
18758 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18759 "TARGET_64BIT"
18760 "rdtsc"
18761 [(set_attr "type" "other")
18762 (set_attr "length" "2")])
18763
18764 (define_insn "rdtscp"
18765 [(set (match_operand:DI 0 "register_operand" "=A")
18766 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18767 (set (match_operand:SI 1 "register_operand" "=c")
18768 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18769 "!TARGET_64BIT"
18770 "rdtscp"
18771 [(set_attr "type" "other")
18772 (set_attr "length" "3")])
18773
18774 (define_insn "rdtscp_rex64"
18775 [(set (match_operand:DI 0 "register_operand" "=a")
18776 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18777 (set (match_operand:DI 1 "register_operand" "=d")
18778 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18779 (set (match_operand:SI 2 "register_operand" "=c")
18780 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18781 "TARGET_64BIT"
18782 "rdtscp"
18783 [(set_attr "type" "other")
18784 (set_attr "length" "3")])
18785
18786 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18787 ;;
18788 ;; FXSR, XSAVE and XSAVEOPT instructions
18789 ;;
18790 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18791
18792 (define_insn "fxsave"
18793 [(set (match_operand:BLK 0 "memory_operand" "=m")
18794 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18795 "TARGET_FXSR"
18796 "fxsave\t%0"
18797 [(set_attr "type" "other")
18798 (set_attr "memory" "store")
18799 (set (attr "length")
18800 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18801
18802 (define_insn "fxsave64"
18803 [(set (match_operand:BLK 0 "memory_operand" "=m")
18804 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18805 "TARGET_64BIT && TARGET_FXSR"
18806 "fxsave64\t%0"
18807 [(set_attr "type" "other")
18808 (set_attr "memory" "store")
18809 (set (attr "length")
18810 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18811
18812 (define_insn "fxrstor"
18813 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18814 UNSPECV_FXRSTOR)]
18815 "TARGET_FXSR"
18816 "fxrstor\t%0"
18817 [(set_attr "type" "other")
18818 (set_attr "memory" "load")
18819 (set (attr "length")
18820 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18821
18822 (define_insn "fxrstor64"
18823 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18824 UNSPECV_FXRSTOR64)]
18825 "TARGET_64BIT && TARGET_FXSR"
18826 "fxrstor64\t%0"
18827 [(set_attr "type" "other")
18828 (set_attr "memory" "load")
18829 (set (attr "length")
18830 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18831
18832 (define_int_iterator ANY_XSAVE
18833 [UNSPECV_XSAVE
18834 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18835 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18836 (UNSPECV_XSAVES "TARGET_XSAVES")])
18837
18838 (define_int_iterator ANY_XSAVE64
18839 [UNSPECV_XSAVE64
18840 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18841 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18842 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18843
18844 (define_int_attr xsave
18845 [(UNSPECV_XSAVE "xsave")
18846 (UNSPECV_XSAVE64 "xsave64")
18847 (UNSPECV_XSAVEOPT "xsaveopt")
18848 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18849 (UNSPECV_XSAVEC "xsavec")
18850 (UNSPECV_XSAVEC64 "xsavec64")
18851 (UNSPECV_XSAVES "xsaves")
18852 (UNSPECV_XSAVES64 "xsaves64")])
18853
18854 (define_int_iterator ANY_XRSTOR
18855 [UNSPECV_XRSTOR
18856 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18857
18858 (define_int_iterator ANY_XRSTOR64
18859 [UNSPECV_XRSTOR64
18860 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18861
18862 (define_int_attr xrstor
18863 [(UNSPECV_XRSTOR "xrstor")
18864 (UNSPECV_XRSTOR64 "xrstor")
18865 (UNSPECV_XRSTORS "xrstors")
18866 (UNSPECV_XRSTORS64 "xrstors")])
18867
18868 (define_insn "<xsave>"
18869 [(set (match_operand:BLK 0 "memory_operand" "=m")
18870 (unspec_volatile:BLK
18871 [(match_operand:DI 1 "register_operand" "A")]
18872 ANY_XSAVE))]
18873 "!TARGET_64BIT && TARGET_XSAVE"
18874 "<xsave>\t%0"
18875 [(set_attr "type" "other")
18876 (set_attr "memory" "store")
18877 (set (attr "length")
18878 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18879
18880 (define_insn "<xsave>_rex64"
18881 [(set (match_operand:BLK 0 "memory_operand" "=m")
18882 (unspec_volatile:BLK
18883 [(match_operand:SI 1 "register_operand" "a")
18884 (match_operand:SI 2 "register_operand" "d")]
18885 ANY_XSAVE))]
18886 "TARGET_64BIT && TARGET_XSAVE"
18887 "<xsave>\t%0"
18888 [(set_attr "type" "other")
18889 (set_attr "memory" "store")
18890 (set (attr "length")
18891 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18892
18893 (define_insn "<xsave>"
18894 [(set (match_operand:BLK 0 "memory_operand" "=m")
18895 (unspec_volatile:BLK
18896 [(match_operand:SI 1 "register_operand" "a")
18897 (match_operand:SI 2 "register_operand" "d")]
18898 ANY_XSAVE64))]
18899 "TARGET_64BIT && TARGET_XSAVE"
18900 "<xsave>\t%0"
18901 [(set_attr "type" "other")
18902 (set_attr "memory" "store")
18903 (set (attr "length")
18904 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18905
18906 (define_insn "<xrstor>"
18907 [(unspec_volatile:BLK
18908 [(match_operand:BLK 0 "memory_operand" "m")
18909 (match_operand:DI 1 "register_operand" "A")]
18910 ANY_XRSTOR)]
18911 "!TARGET_64BIT && TARGET_XSAVE"
18912 "<xrstor>\t%0"
18913 [(set_attr "type" "other")
18914 (set_attr "memory" "load")
18915 (set (attr "length")
18916 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18917
18918 (define_insn "<xrstor>_rex64"
18919 [(unspec_volatile:BLK
18920 [(match_operand:BLK 0 "memory_operand" "m")
18921 (match_operand:SI 1 "register_operand" "a")
18922 (match_operand:SI 2 "register_operand" "d")]
18923 ANY_XRSTOR)]
18924 "TARGET_64BIT && TARGET_XSAVE"
18925 "<xrstor>\t%0"
18926 [(set_attr "type" "other")
18927 (set_attr "memory" "load")
18928 (set (attr "length")
18929 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18930
18931 (define_insn "<xrstor>64"
18932 [(unspec_volatile:BLK
18933 [(match_operand:BLK 0 "memory_operand" "m")
18934 (match_operand:SI 1 "register_operand" "a")
18935 (match_operand:SI 2 "register_operand" "d")]
18936 ANY_XRSTOR64)]
18937 "TARGET_64BIT && TARGET_XSAVE"
18938 "<xrstor>64\t%0"
18939 [(set_attr "type" "other")
18940 (set_attr "memory" "load")
18941 (set (attr "length")
18942 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18943
18944 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18945 ;;
18946 ;; Floating-point instructions for atomic compound assignments
18947 ;;
18948 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18949
18950 ; Clobber all floating-point registers on environment save and restore
18951 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18952 (define_insn "fnstenv"
18953 [(set (match_operand:BLK 0 "memory_operand" "=m")
18954 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18955 (clobber (reg:HI FPCR_REG))
18956 (clobber (reg:XF ST0_REG))
18957 (clobber (reg:XF ST1_REG))
18958 (clobber (reg:XF ST2_REG))
18959 (clobber (reg:XF ST3_REG))
18960 (clobber (reg:XF ST4_REG))
18961 (clobber (reg:XF ST5_REG))
18962 (clobber (reg:XF ST6_REG))
18963 (clobber (reg:XF ST7_REG))]
18964 "TARGET_80387"
18965 "fnstenv\t%0"
18966 [(set_attr "type" "other")
18967 (set_attr "memory" "store")
18968 (set (attr "length")
18969 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18970
18971 (define_insn "fldenv"
18972 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18973 UNSPECV_FLDENV)
18974 (clobber (reg:CCFP FPSR_REG))
18975 (clobber (reg:HI FPCR_REG))
18976 (clobber (reg:XF ST0_REG))
18977 (clobber (reg:XF ST1_REG))
18978 (clobber (reg:XF ST2_REG))
18979 (clobber (reg:XF ST3_REG))
18980 (clobber (reg:XF ST4_REG))
18981 (clobber (reg:XF ST5_REG))
18982 (clobber (reg:XF ST6_REG))
18983 (clobber (reg:XF ST7_REG))]
18984 "TARGET_80387"
18985 "fldenv\t%0"
18986 [(set_attr "type" "other")
18987 (set_attr "memory" "load")
18988 (set (attr "length")
18989 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18990
18991 (define_insn "fnstsw"
18992 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18993 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18994 "TARGET_80387"
18995 "fnstsw\t%0"
18996 [(set_attr "type" "other,other")
18997 (set_attr "memory" "none,store")
18998 (set (attr "length")
18999 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19000
19001 (define_insn "fnclex"
19002 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19003 "TARGET_80387"
19004 "fnclex"
19005 [(set_attr "type" "other")
19006 (set_attr "memory" "none")
19007 (set_attr "length" "2")])
19008
19009 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19010 ;;
19011 ;; LWP instructions
19012 ;;
19013 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19014
19015 (define_expand "lwp_llwpcb"
19016 [(unspec_volatile [(match_operand 0 "register_operand")]
19017 UNSPECV_LLWP_INTRINSIC)]
19018 "TARGET_LWP")
19019
19020 (define_insn "*lwp_llwpcb<mode>1"
19021 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19022 UNSPECV_LLWP_INTRINSIC)]
19023 "TARGET_LWP"
19024 "llwpcb\t%0"
19025 [(set_attr "type" "lwp")
19026 (set_attr "mode" "<MODE>")
19027 (set_attr "length" "5")])
19028
19029 (define_expand "lwp_slwpcb"
19030 [(set (match_operand 0 "register_operand")
19031 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19032 "TARGET_LWP"
19033 {
19034 rtx (*insn)(rtx);
19035
19036 insn = (Pmode == DImode
19037 ? gen_lwp_slwpcbdi
19038 : gen_lwp_slwpcbsi);
19039
19040 emit_insn (insn (operands[0]));
19041 DONE;
19042 })
19043
19044 (define_insn "lwp_slwpcb<mode>"
19045 [(set (match_operand:P 0 "register_operand" "=r")
19046 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19047 "TARGET_LWP"
19048 "slwpcb\t%0"
19049 [(set_attr "type" "lwp")
19050 (set_attr "mode" "<MODE>")
19051 (set_attr "length" "5")])
19052
19053 (define_expand "lwp_lwpval<mode>3"
19054 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19055 (match_operand:SI 2 "nonimmediate_operand")
19056 (match_operand:SI 3 "const_int_operand")]
19057 UNSPECV_LWPVAL_INTRINSIC)]
19058 "TARGET_LWP"
19059 ;; Avoid unused variable warning.
19060 "(void) operands[0];")
19061
19062 (define_insn "*lwp_lwpval<mode>3_1"
19063 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19064 (match_operand:SI 1 "nonimmediate_operand" "rm")
19065 (match_operand:SI 2 "const_int_operand" "i")]
19066 UNSPECV_LWPVAL_INTRINSIC)]
19067 "TARGET_LWP"
19068 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19069 [(set_attr "type" "lwp")
19070 (set_attr "mode" "<MODE>")
19071 (set (attr "length")
19072 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19073
19074 (define_expand "lwp_lwpins<mode>3"
19075 [(set (reg:CCC FLAGS_REG)
19076 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19077 (match_operand:SI 2 "nonimmediate_operand")
19078 (match_operand:SI 3 "const_int_operand")]
19079 UNSPECV_LWPINS_INTRINSIC))
19080 (set (match_operand:QI 0 "nonimmediate_operand")
19081 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19082 "TARGET_LWP")
19083
19084 (define_insn "*lwp_lwpins<mode>3_1"
19085 [(set (reg:CCC FLAGS_REG)
19086 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19087 (match_operand:SI 1 "nonimmediate_operand" "rm")
19088 (match_operand:SI 2 "const_int_operand" "i")]
19089 UNSPECV_LWPINS_INTRINSIC))]
19090 "TARGET_LWP"
19091 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19092 [(set_attr "type" "lwp")
19093 (set_attr "mode" "<MODE>")
19094 (set (attr "length")
19095 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19096
19097 (define_int_iterator RDFSGSBASE
19098 [UNSPECV_RDFSBASE
19099 UNSPECV_RDGSBASE])
19100
19101 (define_int_iterator WRFSGSBASE
19102 [UNSPECV_WRFSBASE
19103 UNSPECV_WRGSBASE])
19104
19105 (define_int_attr fsgs
19106 [(UNSPECV_RDFSBASE "fs")
19107 (UNSPECV_RDGSBASE "gs")
19108 (UNSPECV_WRFSBASE "fs")
19109 (UNSPECV_WRGSBASE "gs")])
19110
19111 (define_insn "rd<fsgs>base<mode>"
19112 [(set (match_operand:SWI48 0 "register_operand" "=r")
19113 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19114 "TARGET_64BIT && TARGET_FSGSBASE"
19115 "rd<fsgs>base\t%0"
19116 [(set_attr "type" "other")
19117 (set_attr "prefix_extra" "2")])
19118
19119 (define_insn "wr<fsgs>base<mode>"
19120 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19121 WRFSGSBASE)]
19122 "TARGET_64BIT && TARGET_FSGSBASE"
19123 "wr<fsgs>base\t%0"
19124 [(set_attr "type" "other")
19125 (set_attr "prefix_extra" "2")])
19126
19127 (define_insn "rdrand<mode>_1"
19128 [(set (match_operand:SWI248 0 "register_operand" "=r")
19129 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19130 (set (reg:CCC FLAGS_REG)
19131 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19132 "TARGET_RDRND"
19133 "rdrand\t%0"
19134 [(set_attr "type" "other")
19135 (set_attr "prefix_extra" "1")])
19136
19137 (define_insn "rdseed<mode>_1"
19138 [(set (match_operand:SWI248 0 "register_operand" "=r")
19139 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19140 (set (reg:CCC FLAGS_REG)
19141 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19142 "TARGET_RDSEED"
19143 "rdseed\t%0"
19144 [(set_attr "type" "other")
19145 (set_attr "prefix_extra" "1")])
19146
19147 (define_expand "pause"
19148 [(set (match_dup 0)
19149 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19150 ""
19151 {
19152 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19153 MEM_VOLATILE_P (operands[0]) = 1;
19154 })
19155
19156 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19157 ;; They have the same encoding.
19158 (define_insn "*pause"
19159 [(set (match_operand:BLK 0)
19160 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19161 ""
19162 "rep%; nop"
19163 [(set_attr "length" "2")
19164 (set_attr "memory" "unknown")])
19165
19166 (define_expand "xbegin"
19167 [(set (match_operand:SI 0 "register_operand")
19168 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19169 "TARGET_RTM"
19170 {
19171 rtx_code_label *label = gen_label_rtx ();
19172
19173 /* xbegin is emitted as jump_insn, so reload won't be able
19174 to reload its operand. Force the value into AX hard register. */
19175 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19176 emit_move_insn (ax_reg, constm1_rtx);
19177
19178 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19179
19180 emit_label (label);
19181 LABEL_NUSES (label) = 1;
19182
19183 emit_move_insn (operands[0], ax_reg);
19184
19185 DONE;
19186 })
19187
19188 (define_insn "xbegin_1"
19189 [(set (pc)
19190 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19191 (const_int 0))
19192 (label_ref (match_operand 1))
19193 (pc)))
19194 (set (match_operand:SI 0 "register_operand" "+a")
19195 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19196 "TARGET_RTM"
19197 "xbegin\t%l1"
19198 [(set_attr "type" "other")
19199 (set_attr "length" "6")])
19200
19201 (define_insn "xend"
19202 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19203 "TARGET_RTM"
19204 "xend"
19205 [(set_attr "type" "other")
19206 (set_attr "length" "3")])
19207
19208 (define_insn "xabort"
19209 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19210 UNSPECV_XABORT)]
19211 "TARGET_RTM"
19212 "xabort\t%0"
19213 [(set_attr "type" "other")
19214 (set_attr "length" "3")])
19215
19216 (define_expand "xtest"
19217 [(set (match_operand:QI 0 "register_operand")
19218 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19219 "TARGET_RTM"
19220 {
19221 emit_insn (gen_xtest_1 ());
19222
19223 ix86_expand_setcc (operands[0], NE,
19224 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19225 DONE;
19226 })
19227
19228 (define_insn "xtest_1"
19229 [(set (reg:CCZ FLAGS_REG)
19230 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19231 "TARGET_RTM"
19232 "xtest"
19233 [(set_attr "type" "other")
19234 (set_attr "length" "3")])
19235
19236 (define_insn "clwb"
19237 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19238 UNSPECV_CLWB)]
19239 "TARGET_CLWB"
19240 "clwb\t%a0"
19241 [(set_attr "type" "sse")
19242 (set_attr "atom_sse_attr" "fence")
19243 (set_attr "memory" "unknown")])
19244
19245 (define_insn "clflushopt"
19246 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19247 UNSPECV_CLFLUSHOPT)]
19248 "TARGET_CLFLUSHOPT"
19249 "clflushopt\t%a0"
19250 [(set_attr "type" "sse")
19251 (set_attr "atom_sse_attr" "fence")
19252 (set_attr "memory" "unknown")])
19253
19254 ;; MONITORX and MWAITX
19255 (define_insn "mwaitx"
19256 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19257 (match_operand:SI 1 "register_operand" "a")
19258 (match_operand:SI 2 "register_operand" "b")]
19259 UNSPECV_MWAITX)]
19260 "TARGET_MWAITX"
19261 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19262 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19263 ;; we only need to set up 32bit registers.
19264 "mwaitx"
19265 [(set_attr "length" "3")])
19266
19267 (define_insn "monitorx_<mode>"
19268 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19269 (match_operand:SI 1 "register_operand" "c")
19270 (match_operand:SI 2 "register_operand" "d")]
19271 UNSPECV_MONITORX)]
19272 "TARGET_MWAITX"
19273 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19274 ;; RCX and RDX are used. Since 32bit register operands are implicitly
19275 ;; zero extended to 64bit, we only need to set up 32bit registers.
19276 "%^monitorx"
19277 [(set (attr "length")
19278 (symbol_ref ("(Pmode != word_mode) + 3")))])
19279
19280 ;; CLZERO
19281 (define_insn "clzero_<mode>"
19282 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
19283 UNSPECV_CLZERO)]
19284 "TARGET_CLZERO"
19285 "clzero"
19286 [(set_attr "length" "3")
19287 (set_attr "memory" "unknown")])
19288
19289 ;; MPX instructions
19290
19291 (define_expand "<mode>_mk"
19292 [(set (match_operand:BND 0 "register_operand")
19293 (unspec:BND
19294 [(mem:<bnd_ptr>
19295 (match_par_dup 3
19296 [(match_operand:<bnd_ptr> 1 "register_operand")
19297 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
19298 UNSPEC_BNDMK))]
19299 "TARGET_MPX"
19300 {
19301 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19302 operands[2]),
19303 UNSPEC_BNDMK_ADDR);
19304 })
19305
19306 (define_insn "*<mode>_mk"
19307 [(set (match_operand:BND 0 "register_operand" "=w")
19308 (unspec:BND
19309 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19310 [(unspec:<bnd_ptr>
19311 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
19312 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
19313 UNSPEC_BNDMK_ADDR)])]
19314 UNSPEC_BNDMK))]
19315 "TARGET_MPX"
19316 "bndmk\t{%3, %0|%0, %3}"
19317 [(set_attr "type" "mpxmk")])
19318
19319 (define_expand "mov<mode>"
19320 [(set (match_operand:BND 0 "general_operand")
19321 (match_operand:BND 1 "general_operand"))]
19322 "TARGET_MPX"
19323 "ix86_expand_move (<MODE>mode, operands); DONE;")
19324
19325 (define_insn "*mov<mode>_internal_mpx"
19326 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
19327 (match_operand:BND 1 "general_operand" "wm,w"))]
19328 "TARGET_MPX"
19329 "bndmov\t{%1, %0|%0, %1}"
19330 [(set_attr "type" "mpxmov")])
19331
19332 (define_expand "<mode>_<bndcheck>"
19333 [(parallel
19334 [(unspec
19335 [(match_operand:BND 0 "register_operand")
19336 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
19337 (set (match_dup 2)
19338 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
19339 "TARGET_MPX"
19340 {
19341 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
19342 MEM_VOLATILE_P (operands[2]) = 1;
19343 })
19344
19345 (define_insn "*<mode>_<bndcheck>"
19346 [(unspec
19347 [(match_operand:BND 0 "register_operand" "w")
19348 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
19349 (set (match_operand:BLK 2 "bnd_mem_operator")
19350 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
19351 "TARGET_MPX"
19352 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
19353 [(set_attr "type" "mpxchk")])
19354
19355 (define_expand "<mode>_ldx"
19356 [(parallel
19357 [(set (match_operand:BND 0 "register_operand")
19358 (unspec:BND
19359 [(mem:<bnd_ptr>
19360 (match_par_dup 3
19361 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
19362 (match_operand:<bnd_ptr> 2 "register_operand")]))]
19363 UNSPEC_BNDLDX))
19364 (use (mem:BLK (match_dup 1)))])]
19365 "TARGET_MPX"
19366 {
19367 /* Avoid registers which cannot be used as index. */
19368 if (!index_register_operand (operands[2], Pmode))
19369 operands[2] = copy_addr_to_reg (operands[2]);
19370
19371 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19372 operands[2]),
19373 UNSPEC_BNDLDX_ADDR);
19374 })
19375
19376 (define_insn "*<mode>_ldx"
19377 [(set (match_operand:BND 0 "register_operand" "=w")
19378 (unspec:BND
19379 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19380 [(unspec:<bnd_ptr>
19381 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19382 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19383 UNSPEC_BNDLDX_ADDR)])]
19384 UNSPEC_BNDLDX))
19385 (use (mem:BLK (match_dup 1)))]
19386 "TARGET_MPX"
19387 "bndldx\t{%3, %0|%0, %3}"
19388 [(set_attr "type" "mpxld")])
19389
19390 (define_expand "<mode>_stx"
19391 [(parallel
19392 [(unspec
19393 [(mem:<bnd_ptr>
19394 (match_par_dup 3
19395 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19396 (match_operand:<bnd_ptr> 1 "register_operand")]))
19397 (match_operand:BND 2 "register_operand")]
19398 UNSPEC_BNDSTX)
19399 (set (match_dup 4)
19400 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19401 "TARGET_MPX"
19402 {
19403 /* Avoid registers which cannot be used as index. */
19404 if (!index_register_operand (operands[1], Pmode))
19405 operands[1] = copy_addr_to_reg (operands[1]);
19406
19407 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19408 operands[1]),
19409 UNSPEC_BNDLDX_ADDR);
19410 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19411 MEM_VOLATILE_P (operands[4]) = 1;
19412 })
19413
19414 (define_insn "*<mode>_stx"
19415 [(unspec
19416 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19417 [(unspec:<bnd_ptr>
19418 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19419 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19420 UNSPEC_BNDLDX_ADDR)])
19421 (match_operand:BND 2 "register_operand" "w")]
19422 UNSPEC_BNDSTX)
19423 (set (match_operand:BLK 4 "bnd_mem_operator")
19424 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
19425 "TARGET_MPX"
19426 "bndstx\t{%2, %3|%3, %2}"
19427 [(set_attr "type" "mpxst")])
19428
19429 (define_insn "move_size_reloc_<mode>"
19430 [(set (match_operand:SWI48 0 "register_operand" "=r")
19431 (unspec:SWI48
19432 [(match_operand:SWI48 1 "symbol_operand")]
19433 UNSPEC_SIZEOF))]
19434 "TARGET_MPX"
19435 {
19436 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19437 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19438 else
19439 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19440 }
19441 [(set_attr "type" "imov")
19442 (set_attr "mode" "<MODE>")])
19443
19444 ;; RDPKRU and WRPKRU
19445
19446 (define_expand "rdpkru"
19447 [(parallel
19448 [(set (match_operand:SI 0 "register_operand")
19449 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
19450 (set (match_dup 2) (const_int 0))])]
19451 "TARGET_PKU"
19452 {
19453 operands[1] = force_reg (SImode, const0_rtx);
19454 operands[2] = gen_reg_rtx (SImode);
19455 })
19456
19457 (define_insn "*rdpkru"
19458 [(set (match_operand:SI 0 "register_operand" "=a")
19459 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
19460 UNSPECV_PKU))
19461 (set (match_operand:SI 1 "register_operand" "=d")
19462 (const_int 0))]
19463 "TARGET_PKU"
19464 "rdpkru"
19465 [(set_attr "type" "other")])
19466
19467 (define_expand "wrpkru"
19468 [(unspec_volatile:SI
19469 [(match_operand:SI 0 "register_operand")
19470 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
19471 "TARGET_PKU"
19472 {
19473 operands[1] = force_reg (SImode, const0_rtx);
19474 operands[2] = force_reg (SImode, const0_rtx);
19475 })
19476
19477 (define_insn "*wrpkru"
19478 [(unspec_volatile:SI
19479 [(match_operand:SI 0 "register_operand" "a")
19480 (match_operand:SI 1 "register_operand" "d")
19481 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
19482 "TARGET_PKU"
19483 "wrpkru"
19484 [(set_attr "type" "other")])
19485
19486 (include "mmx.md")
19487 (include "sse.md")
19488 (include "sync.md")