866fb05d867e719bf2d9527dd48f7cd3b282bcf9
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;; otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
64
65 ;; UNSPEC usage:
66
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
69 UNSPEC_GOT
70 UNSPEC_GOTOFF
71 UNSPEC_GOTPCREL
72 UNSPEC_GOTTPOFF
73 UNSPEC_TPOFF
74 UNSPEC_NTPOFF
75 UNSPEC_DTPOFF
76 UNSPEC_GOTNTPOFF
77 UNSPEC_INDNTPOFF
78 UNSPEC_PLTOFF
79 UNSPEC_MACHOPIC_OFFSET
80 UNSPEC_PCREL
81
82 ;; Prologue support
83 UNSPEC_STACK_ALLOC
84 UNSPEC_SET_GOT
85 UNSPEC_REG_SAVE
86 UNSPEC_DEF_CFA
87 UNSPEC_SET_RIP
88 UNSPEC_SET_GOT_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
90 UNSPEC_STACK_CHECK
91
92 ;; TLS support
93 UNSPEC_TP
94 UNSPEC_TLS_GD
95 UNSPEC_TLS_LD_BASE
96 UNSPEC_TLSDESC
97 UNSPEC_TLS_IE_SUN
98
99 ;; Other random patterns
100 UNSPEC_SCAS
101 UNSPEC_FNSTSW
102 UNSPEC_SAHF
103 UNSPEC_PARITY
104 UNSPEC_FSTCW
105 UNSPEC_ADD_CARRY
106 UNSPEC_FLDCW
107 UNSPEC_REP
108 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_TRUNC_NOOP
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_CALL_NEEDS_VZEROUPPER
112 UNSPEC_PAUSE
113
114 ;; For SSE/MMX support:
115 UNSPEC_FIX_NOTRUNC
116 UNSPEC_MASKMOV
117 UNSPEC_MOVMSK
118 UNSPEC_MOVNT
119 UNSPEC_MOVU
120 UNSPEC_RCP
121 UNSPEC_RSQRT
122 UNSPEC_SFENCE
123 UNSPEC_PFRCP
124 UNSPEC_PFRCPIT1
125 UNSPEC_PFRCPIT2
126 UNSPEC_PFRSQRT
127 UNSPEC_PFRSQIT1
128 UNSPEC_MFENCE
129 UNSPEC_LFENCE
130 UNSPEC_PSADBW
131 UNSPEC_LDDQU
132 UNSPEC_MS_TO_SYSV_CALL
133
134 ;; Generic math support
135 UNSPEC_COPYSIGN
136 UNSPEC_IEEE_MIN ; not commutative
137 UNSPEC_IEEE_MAX ; not commutative
138
139 ;; x87 Floating point
140 UNSPEC_SIN
141 UNSPEC_COS
142 UNSPEC_FPATAN
143 UNSPEC_FYL2X
144 UNSPEC_FYL2XP1
145 UNSPEC_FRNDINT
146 UNSPEC_FIST
147 UNSPEC_F2XM1
148 UNSPEC_TAN
149 UNSPEC_FXAM
150
151 ;; x87 Rounding
152 UNSPEC_FRNDINT_FLOOR
153 UNSPEC_FRNDINT_CEIL
154 UNSPEC_FRNDINT_TRUNC
155 UNSPEC_FRNDINT_MASK_PM
156 UNSPEC_FIST_FLOOR
157 UNSPEC_FIST_CEIL
158
159 ;; x87 Double output FP
160 UNSPEC_SINCOS_COS
161 UNSPEC_SINCOS_SIN
162 UNSPEC_XTRACT_FRACT
163 UNSPEC_XTRACT_EXP
164 UNSPEC_FSCALE_FRACT
165 UNSPEC_FSCALE_EXP
166 UNSPEC_FPREM_F
167 UNSPEC_FPREM_U
168 UNSPEC_FPREM1_F
169 UNSPEC_FPREM1_U
170
171 UNSPEC_C2_FLAG
172 UNSPEC_FXAM_MEM
173
174 ;; SSP patterns
175 UNSPEC_SP_SET
176 UNSPEC_SP_TEST
177 UNSPEC_SP_TLS_SET
178 UNSPEC_SP_TLS_TEST
179
180 ;; SSSE3
181 UNSPEC_PSHUFB
182 UNSPEC_PSIGN
183 UNSPEC_PALIGNR
184
185 ;; For SSE4A support
186 UNSPEC_EXTRQI
187 UNSPEC_EXTRQ
188 UNSPEC_INSERTQI
189 UNSPEC_INSERTQ
190
191 ;; For SSE4.1 support
192 UNSPEC_BLENDV
193 UNSPEC_INSERTPS
194 UNSPEC_DP
195 UNSPEC_MOVNTDQA
196 UNSPEC_MPSADBW
197 UNSPEC_PHMINPOSUW
198 UNSPEC_PTEST
199 UNSPEC_ROUND
200
201 ;; For SSE4.2 support
202 UNSPEC_CRC32
203 UNSPEC_PCMPESTR
204 UNSPEC_PCMPISTR
205
206 ;; For FMA4 support
207 UNSPEC_FMADDSUB
208 UNSPEC_XOP_UNSIGNED_CMP
209 UNSPEC_XOP_TRUEFALSE
210 UNSPEC_XOP_PERMUTE
211 UNSPEC_FRCZ
212
213 ;; For AES support
214 UNSPEC_AESENC
215 UNSPEC_AESENCLAST
216 UNSPEC_AESDEC
217 UNSPEC_AESDECLAST
218 UNSPEC_AESIMC
219 UNSPEC_AESKEYGENASSIST
220
221 ;; For PCLMUL support
222 UNSPEC_PCLMUL
223
224 ;; For AVX support
225 UNSPEC_PCMP
226 UNSPEC_VPERMIL
227 UNSPEC_VPERMIL2
228 UNSPEC_VPERMIL2F128
229 UNSPEC_CAST
230 UNSPEC_VTESTP
231 UNSPEC_VCVTPH2PS
232 UNSPEC_VCVTPS2PH
233
234 ;; For AVX2 support
235 UNSPEC_VPERMSI
236 UNSPEC_VPERMDF
237 UNSPEC_VPERMSF
238 UNSPEC_VPERMTI
239 UNSPEC_GATHER
240
241 ;; For BMI support
242 UNSPEC_BEXTR
243
244 ;; For RDRAND support
245 UNSPEC_RDRAND
246
247 ;; For BMI2 support
248 UNSPEC_PDEP
249 UNSPEC_PEXT
250 ])
251
252 (define_c_enum "unspecv" [
253 UNSPECV_BLOCKAGE
254 UNSPECV_STACK_PROBE
255 UNSPECV_PROBE_STACK_RANGE
256 UNSPECV_EMMS
257 UNSPECV_LDMXCSR
258 UNSPECV_STMXCSR
259 UNSPECV_FEMMS
260 UNSPECV_CLFLUSH
261 UNSPECV_ALIGN
262 UNSPECV_MONITOR
263 UNSPECV_MWAIT
264 UNSPECV_CMPXCHG
265 UNSPECV_XCHG
266 UNSPECV_LOCK
267 UNSPECV_PROLOGUE_USE
268 UNSPECV_CLD
269 UNSPECV_NOPS
270 UNSPECV_VZEROALL
271 UNSPECV_VZEROUPPER
272 UNSPECV_RDTSC
273 UNSPECV_RDTSCP
274 UNSPECV_RDPMC
275 UNSPECV_LLWP_INTRINSIC
276 UNSPECV_SLWP_INTRINSIC
277 UNSPECV_LWPVAL_INTRINSIC
278 UNSPECV_LWPINS_INTRINSIC
279 UNSPECV_RDFSBASE
280 UNSPECV_RDGSBASE
281 UNSPECV_WRFSBASE
282 UNSPECV_WRGSBASE
283 UNSPECV_SPLIT_STACK_RETURN
284 ])
285
286 ;; Constants to represent rounding modes in the ROUND instruction
287 (define_constants
288 [(ROUND_FLOOR 0x1)
289 (ROUND_CEIL 0x2)
290 (ROUND_TRUNC 0x3)
291 (ROUND_MXCSR 0x4)
292 (ROUND_NO_EXC 0x8)
293 ])
294
295 ;; Constants to represent pcomtrue/pcomfalse variants
296 (define_constants
297 [(PCOM_FALSE 0)
298 (PCOM_TRUE 1)
299 (COM_FALSE_S 2)
300 (COM_FALSE_P 3)
301 (COM_TRUE_S 4)
302 (COM_TRUE_P 5)
303 ])
304
305 ;; Constants used in the XOP pperm instruction
306 (define_constants
307 [(PPERM_SRC 0x00) /* copy source */
308 (PPERM_INVERT 0x20) /* invert source */
309 (PPERM_REVERSE 0x40) /* bit reverse source */
310 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
311 (PPERM_ZERO 0x80) /* all 0's */
312 (PPERM_ONES 0xa0) /* all 1's */
313 (PPERM_SIGN 0xc0) /* propagate sign bit */
314 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
315 (PPERM_SRC1 0x00) /* use first source byte */
316 (PPERM_SRC2 0x10) /* use second source byte */
317 ])
318
319 ;; Registers by name.
320 (define_constants
321 [(AX_REG 0)
322 (DX_REG 1)
323 (CX_REG 2)
324 (BX_REG 3)
325 (SI_REG 4)
326 (DI_REG 5)
327 (BP_REG 6)
328 (SP_REG 7)
329 (ST0_REG 8)
330 (ST1_REG 9)
331 (ST2_REG 10)
332 (ST3_REG 11)
333 (ST4_REG 12)
334 (ST5_REG 13)
335 (ST6_REG 14)
336 (ST7_REG 15)
337 (FLAGS_REG 17)
338 (FPSR_REG 18)
339 (FPCR_REG 19)
340 (XMM0_REG 21)
341 (XMM1_REG 22)
342 (XMM2_REG 23)
343 (XMM3_REG 24)
344 (XMM4_REG 25)
345 (XMM5_REG 26)
346 (XMM6_REG 27)
347 (XMM7_REG 28)
348 (MM0_REG 29)
349 (MM1_REG 30)
350 (MM2_REG 31)
351 (MM3_REG 32)
352 (MM4_REG 33)
353 (MM5_REG 34)
354 (MM6_REG 35)
355 (MM7_REG 36)
356 (R8_REG 37)
357 (R9_REG 38)
358 (R10_REG 39)
359 (R11_REG 40)
360 (R12_REG 41)
361 (R13_REG 42)
362 (XMM8_REG 45)
363 (XMM9_REG 46)
364 (XMM10_REG 47)
365 (XMM11_REG 48)
366 (XMM12_REG 49)
367 (XMM13_REG 50)
368 (XMM14_REG 51)
369 (XMM15_REG 52)
370 ])
371
372 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
373 ;; from i386.c.
374
375 ;; In C guard expressions, put expressions which may be compile-time
376 ;; constants first. This allows for better optimization. For
377 ;; example, write "TARGET_64BIT && reload_completed", not
378 ;; "reload_completed && TARGET_64BIT".
379
380 \f
381 ;; Processor type.
382 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
383 atom,generic64,amdfam10,bdver1,bdver2,btver1"
384 (const (symbol_ref "ix86_schedule")))
385
386 ;; A basic instruction type. Refinements due to arguments to be
387 ;; provided in other attributes.
388 (define_attr "type"
389 "other,multi,
390 alu,alu1,negnot,imov,imovx,lea,
391 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
392 icmp,test,ibr,setcc,icmov,
393 push,pop,call,callv,leave,
394 str,bitmanip,
395 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
396 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
397 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
398 ssemuladd,sse4arg,lwp,
399 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
400 (const_string "other"))
401
402 ;; Main data type used by the insn
403 (define_attr "mode"
404 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
405 (const_string "unknown"))
406
407 ;; The CPU unit operations uses.
408 (define_attr "unit" "integer,i387,sse,mmx,unknown"
409 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
410 (const_string "i387")
411 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
412 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
413 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
414 (const_string "sse")
415 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
416 (const_string "mmx")
417 (eq_attr "type" "other")
418 (const_string "unknown")]
419 (const_string "integer")))
420
421 ;; The (bounding maximum) length of an instruction immediate.
422 (define_attr "length_immediate" ""
423 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
424 bitmanip,imulx")
425 (const_int 0)
426 (eq_attr "unit" "i387,sse,mmx")
427 (const_int 0)
428 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
429 rotate,rotatex,rotate1,imul,icmp,push,pop")
430 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
431 (eq_attr "type" "imov,test")
432 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
433 (eq_attr "type" "call")
434 (if_then_else (match_operand 0 "constant_call_address_operand" "")
435 (const_int 4)
436 (const_int 0))
437 (eq_attr "type" "callv")
438 (if_then_else (match_operand 1 "constant_call_address_operand" "")
439 (const_int 4)
440 (const_int 0))
441 ;; We don't know the size before shorten_branches. Expect
442 ;; the instruction to fit for better scheduling.
443 (eq_attr "type" "ibr")
444 (const_int 1)
445 ]
446 (symbol_ref "/* Update immediate_length and other attributes! */
447 gcc_unreachable (),1")))
448
449 ;; The (bounding maximum) length of an instruction address.
450 (define_attr "length_address" ""
451 (cond [(eq_attr "type" "str,other,multi,fxch")
452 (const_int 0)
453 (and (eq_attr "type" "call")
454 (match_operand 0 "constant_call_address_operand" ""))
455 (const_int 0)
456 (and (eq_attr "type" "callv")
457 (match_operand 1 "constant_call_address_operand" ""))
458 (const_int 0)
459 ]
460 (symbol_ref "ix86_attr_length_address_default (insn)")))
461
462 ;; Set when length prefix is used.
463 (define_attr "prefix_data16" ""
464 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
465 (const_int 0)
466 (eq_attr "mode" "HI")
467 (const_int 1)
468 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
469 (const_int 1)
470 ]
471 (const_int 0)))
472
473 ;; Set when string REP prefix is used.
474 (define_attr "prefix_rep" ""
475 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
476 (const_int 0)
477 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
478 (const_int 1)
479 ]
480 (const_int 0)))
481
482 ;; Set when 0f opcode prefix is used.
483 (define_attr "prefix_0f" ""
484 (if_then_else
485 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
486 (eq_attr "unit" "sse,mmx"))
487 (const_int 1)
488 (const_int 0)))
489
490 ;; Set when REX opcode prefix is used.
491 (define_attr "prefix_rex" ""
492 (cond [(not (match_test "TARGET_64BIT"))
493 (const_int 0)
494 (and (eq_attr "mode" "DI")
495 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
496 (eq_attr "unit" "!mmx")))
497 (const_int 1)
498 (and (eq_attr "mode" "QI")
499 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
500 (const_int 1)
501 (match_test "x86_extended_reg_mentioned_p (insn)")
502 (const_int 1)
503 (and (eq_attr "type" "imovx")
504 (match_operand:QI 1 "ext_QIreg_operand" ""))
505 (const_int 1)
506 ]
507 (const_int 0)))
508
509 ;; There are also additional prefixes in 3DNOW, SSSE3.
510 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
511 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
512 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
513 (define_attr "prefix_extra" ""
514 (cond [(eq_attr "type" "ssemuladd,sse4arg")
515 (const_int 2)
516 (eq_attr "type" "sseiadd1,ssecvt1")
517 (const_int 1)
518 ]
519 (const_int 0)))
520
521 ;; Prefix used: original, VEX or maybe VEX.
522 (define_attr "prefix" "orig,vex,maybe_vex"
523 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
524 (const_string "vex")
525 (const_string "orig")))
526
527 ;; VEX W bit is used.
528 (define_attr "prefix_vex_w" "" (const_int 0))
529
530 ;; The length of VEX prefix
531 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
532 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
533 ;; still prefix_0f 1, with prefix_extra 1.
534 (define_attr "length_vex" ""
535 (if_then_else (and (eq_attr "prefix_0f" "1")
536 (eq_attr "prefix_extra" "0"))
537 (if_then_else (eq_attr "prefix_vex_w" "1")
538 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
539 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
540 (if_then_else (eq_attr "prefix_vex_w" "1")
541 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
542 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
543
544 ;; Set when modrm byte is used.
545 (define_attr "modrm" ""
546 (cond [(eq_attr "type" "str,leave")
547 (const_int 0)
548 (eq_attr "unit" "i387")
549 (const_int 0)
550 (and (eq_attr "type" "incdec")
551 (and (not (match_test "TARGET_64BIT"))
552 (ior (match_operand:SI 1 "register_operand" "")
553 (match_operand:HI 1 "register_operand" ""))))
554 (const_int 0)
555 (and (eq_attr "type" "push")
556 (not (match_operand 1 "memory_operand" "")))
557 (const_int 0)
558 (and (eq_attr "type" "pop")
559 (not (match_operand 0 "memory_operand" "")))
560 (const_int 0)
561 (and (eq_attr "type" "imov")
562 (and (not (eq_attr "mode" "DI"))
563 (ior (and (match_operand 0 "register_operand" "")
564 (match_operand 1 "immediate_operand" ""))
565 (ior (and (match_operand 0 "ax_reg_operand" "")
566 (match_operand 1 "memory_displacement_only_operand" ""))
567 (and (match_operand 0 "memory_displacement_only_operand" "")
568 (match_operand 1 "ax_reg_operand" ""))))))
569 (const_int 0)
570 (and (eq_attr "type" "call")
571 (match_operand 0 "constant_call_address_operand" ""))
572 (const_int 0)
573 (and (eq_attr "type" "callv")
574 (match_operand 1 "constant_call_address_operand" ""))
575 (const_int 0)
576 (and (eq_attr "type" "alu,alu1,icmp,test")
577 (match_operand 0 "ax_reg_operand" ""))
578 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
579 ]
580 (const_int 1)))
581
582 ;; The (bounding maximum) length of an instruction in bytes.
583 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
584 ;; Later we may want to split them and compute proper length as for
585 ;; other insns.
586 (define_attr "length" ""
587 (cond [(eq_attr "type" "other,multi,fistp,frndint")
588 (const_int 16)
589 (eq_attr "type" "fcmp")
590 (const_int 4)
591 (eq_attr "unit" "i387")
592 (plus (const_int 2)
593 (plus (attr "prefix_data16")
594 (attr "length_address")))
595 (ior (eq_attr "prefix" "vex")
596 (and (eq_attr "prefix" "maybe_vex")
597 (match_test "TARGET_AVX")))
598 (plus (attr "length_vex")
599 (plus (attr "length_immediate")
600 (plus (attr "modrm")
601 (attr "length_address"))))]
602 (plus (plus (attr "modrm")
603 (plus (attr "prefix_0f")
604 (plus (attr "prefix_rex")
605 (plus (attr "prefix_extra")
606 (const_int 1)))))
607 (plus (attr "prefix_rep")
608 (plus (attr "prefix_data16")
609 (plus (attr "length_immediate")
610 (attr "length_address")))))))
611
612 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
613 ;; `store' if there is a simple memory reference therein, or `unknown'
614 ;; if the instruction is complex.
615
616 (define_attr "memory" "none,load,store,both,unknown"
617 (cond [(eq_attr "type" "other,multi,str,lwp")
618 (const_string "unknown")
619 (eq_attr "type" "lea,fcmov,fpspc")
620 (const_string "none")
621 (eq_attr "type" "fistp,leave")
622 (const_string "both")
623 (eq_attr "type" "frndint")
624 (const_string "load")
625 (eq_attr "type" "push")
626 (if_then_else (match_operand 1 "memory_operand" "")
627 (const_string "both")
628 (const_string "store"))
629 (eq_attr "type" "pop")
630 (if_then_else (match_operand 0 "memory_operand" "")
631 (const_string "both")
632 (const_string "load"))
633 (eq_attr "type" "setcc")
634 (if_then_else (match_operand 0 "memory_operand" "")
635 (const_string "store")
636 (const_string "none"))
637 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
638 (if_then_else (ior (match_operand 0 "memory_operand" "")
639 (match_operand 1 "memory_operand" ""))
640 (const_string "load")
641 (const_string "none"))
642 (eq_attr "type" "ibr")
643 (if_then_else (match_operand 0 "memory_operand" "")
644 (const_string "load")
645 (const_string "none"))
646 (eq_attr "type" "call")
647 (if_then_else (match_operand 0 "constant_call_address_operand" "")
648 (const_string "none")
649 (const_string "load"))
650 (eq_attr "type" "callv")
651 (if_then_else (match_operand 1 "constant_call_address_operand" "")
652 (const_string "none")
653 (const_string "load"))
654 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
655 (match_operand 1 "memory_operand" ""))
656 (const_string "both")
657 (and (match_operand 0 "memory_operand" "")
658 (match_operand 1 "memory_operand" ""))
659 (const_string "both")
660 (match_operand 0 "memory_operand" "")
661 (const_string "store")
662 (match_operand 1 "memory_operand" "")
663 (const_string "load")
664 (and (eq_attr "type"
665 "!alu1,negnot,ishift1,
666 imov,imovx,icmp,test,bitmanip,
667 fmov,fcmp,fsgn,
668 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
669 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
670 (match_operand 2 "memory_operand" ""))
671 (const_string "load")
672 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
673 (match_operand 3 "memory_operand" ""))
674 (const_string "load")
675 ]
676 (const_string "none")))
677
678 ;; Indicates if an instruction has both an immediate and a displacement.
679
680 (define_attr "imm_disp" "false,true,unknown"
681 (cond [(eq_attr "type" "other,multi")
682 (const_string "unknown")
683 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
684 (and (match_operand 0 "memory_displacement_operand" "")
685 (match_operand 1 "immediate_operand" "")))
686 (const_string "true")
687 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
688 (and (match_operand 0 "memory_displacement_operand" "")
689 (match_operand 2 "immediate_operand" "")))
690 (const_string "true")
691 ]
692 (const_string "false")))
693
694 ;; Indicates if an FP operation has an integer source.
695
696 (define_attr "fp_int_src" "false,true"
697 (const_string "false"))
698
699 ;; Defines rounding mode of an FP operation.
700
701 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
702 (const_string "any"))
703
704 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
705 (define_attr "use_carry" "0,1" (const_string "0"))
706
707 ;; Define attribute to indicate unaligned ssemov insns
708 (define_attr "movu" "0,1" (const_string "0"))
709
710 ;; Used to control the "enabled" attribute on a per-instruction basis.
711 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
712 (const_string "base"))
713
714 (define_attr "enabled" ""
715 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
716 (eq_attr "isa" "sse2_noavx")
717 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
718 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
719 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
720 (eq_attr "isa" "sse4_noavx")
721 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
722 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
723 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
724 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
725 ]
726 (const_int 1)))
727
728 ;; Describe a user's asm statement.
729 (define_asm_attributes
730 [(set_attr "length" "128")
731 (set_attr "type" "multi")])
732
733 (define_code_iterator plusminus [plus minus])
734
735 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
736
737 ;; Base name for define_insn
738 (define_code_attr plusminus_insn
739 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
740 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
741
742 ;; Base name for insn mnemonic.
743 (define_code_attr plusminus_mnemonic
744 [(plus "add") (ss_plus "adds") (us_plus "addus")
745 (minus "sub") (ss_minus "subs") (us_minus "subus")])
746 (define_code_attr plusminus_carry_mnemonic
747 [(plus "adc") (minus "sbb")])
748
749 ;; Mark commutative operators as such in constraints.
750 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
751 (minus "") (ss_minus "") (us_minus "")])
752
753 ;; Mapping of max and min
754 (define_code_iterator maxmin [smax smin umax umin])
755
756 ;; Mapping of signed max and min
757 (define_code_iterator smaxmin [smax smin])
758
759 ;; Mapping of unsigned max and min
760 (define_code_iterator umaxmin [umax umin])
761
762 ;; Base name for integer and FP insn mnemonic
763 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
764 (umax "maxu") (umin "minu")])
765 (define_code_attr maxmin_float [(smax "max") (smin "min")])
766
767 ;; Mapping of logic operators
768 (define_code_iterator any_logic [and ior xor])
769 (define_code_iterator any_or [ior xor])
770
771 ;; Base name for insn mnemonic.
772 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
773
774 ;; Mapping of shift-right operators
775 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
776
777 ;; Base name for define_insn
778 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
779
780 ;; Base name for insn mnemonic.
781 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
782
783 ;; Mapping of rotate operators
784 (define_code_iterator any_rotate [rotate rotatert])
785
786 ;; Base name for define_insn
787 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
788
789 ;; Base name for insn mnemonic.
790 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
791
792 ;; Mapping of abs neg operators
793 (define_code_iterator absneg [abs neg])
794
795 ;; Base name for x87 insn mnemonic.
796 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
797
798 ;; Used in signed and unsigned widening multiplications.
799 (define_code_iterator any_extend [sign_extend zero_extend])
800
801 ;; Prefix for insn menmonic.
802 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
803
804 ;; Prefix for define_insn
805 (define_code_attr u [(sign_extend "") (zero_extend "u")])
806 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
807
808 ;; All integer modes.
809 (define_mode_iterator SWI1248x [QI HI SI DI])
810
811 ;; All integer modes without QImode.
812 (define_mode_iterator SWI248x [HI SI DI])
813
814 ;; All integer modes without QImode and HImode.
815 (define_mode_iterator SWI48x [SI DI])
816
817 ;; All integer modes without SImode and DImode.
818 (define_mode_iterator SWI12 [QI HI])
819
820 ;; All integer modes without DImode.
821 (define_mode_iterator SWI124 [QI HI SI])
822
823 ;; All integer modes without QImode and DImode.
824 (define_mode_iterator SWI24 [HI SI])
825
826 ;; Single word integer modes.
827 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
828
829 ;; Single word integer modes without QImode.
830 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
831
832 ;; Single word integer modes without QImode and HImode.
833 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
834
835 ;; All math-dependant single and double word integer modes.
836 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
837 (HI "TARGET_HIMODE_MATH")
838 SI DI (TI "TARGET_64BIT")])
839
840 ;; Math-dependant single word integer modes.
841 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
842 (HI "TARGET_HIMODE_MATH")
843 SI (DI "TARGET_64BIT")])
844
845 ;; Math-dependant integer modes without DImode.
846 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
847 (HI "TARGET_HIMODE_MATH")
848 SI])
849
850 ;; Math-dependant single word integer modes without QImode.
851 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
852 SI (DI "TARGET_64BIT")])
853
854 ;; Double word integer modes.
855 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
856 (TI "TARGET_64BIT")])
857
858 ;; Double word integer modes as mode attribute.
859 (define_mode_attr DWI [(SI "DI") (DI "TI")])
860 (define_mode_attr dwi [(SI "di") (DI "ti")])
861
862 ;; Half mode for double word integer modes.
863 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
864 (DI "TARGET_64BIT")])
865
866 ;; Instruction suffix for integer modes.
867 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
868
869 ;; Pointer size prefix for integer modes (Intel asm dialect)
870 (define_mode_attr iptrsize [(QI "BYTE")
871 (HI "WORD")
872 (SI "DWORD")
873 (DI "QWORD")])
874
875 ;; Register class for integer modes.
876 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
877
878 ;; Immediate operand constraint for integer modes.
879 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
880
881 ;; General operand constraint for word modes.
882 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
883
884 ;; Immediate operand constraint for double integer modes.
885 (define_mode_attr di [(SI "nF") (DI "e")])
886
887 ;; Immediate operand constraint for shifts.
888 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
889
890 ;; General operand predicate for integer modes.
891 (define_mode_attr general_operand
892 [(QI "general_operand")
893 (HI "general_operand")
894 (SI "x86_64_general_operand")
895 (DI "x86_64_general_operand")
896 (TI "x86_64_general_operand")])
897
898 ;; General sign/zero extend operand predicate for integer modes.
899 (define_mode_attr general_szext_operand
900 [(QI "general_operand")
901 (HI "general_operand")
902 (SI "x86_64_szext_general_operand")
903 (DI "x86_64_szext_general_operand")])
904
905 ;; Immediate operand predicate for integer modes.
906 (define_mode_attr immediate_operand
907 [(QI "immediate_operand")
908 (HI "immediate_operand")
909 (SI "x86_64_immediate_operand")
910 (DI "x86_64_immediate_operand")])
911
912 ;; Nonmemory operand predicate for integer modes.
913 (define_mode_attr nonmemory_operand
914 [(QI "nonmemory_operand")
915 (HI "nonmemory_operand")
916 (SI "x86_64_nonmemory_operand")
917 (DI "x86_64_nonmemory_operand")])
918
919 ;; Operand predicate for shifts.
920 (define_mode_attr shift_operand
921 [(QI "nonimmediate_operand")
922 (HI "nonimmediate_operand")
923 (SI "nonimmediate_operand")
924 (DI "shiftdi_operand")
925 (TI "register_operand")])
926
927 ;; Operand predicate for shift argument.
928 (define_mode_attr shift_immediate_operand
929 [(QI "const_1_to_31_operand")
930 (HI "const_1_to_31_operand")
931 (SI "const_1_to_31_operand")
932 (DI "const_1_to_63_operand")])
933
934 ;; Input operand predicate for arithmetic left shifts.
935 (define_mode_attr ashl_input_operand
936 [(QI "nonimmediate_operand")
937 (HI "nonimmediate_operand")
938 (SI "nonimmediate_operand")
939 (DI "ashldi_input_operand")
940 (TI "reg_or_pm1_operand")])
941
942 ;; SSE and x87 SFmode and DFmode floating point modes
943 (define_mode_iterator MODEF [SF DF])
944
945 ;; All x87 floating point modes
946 (define_mode_iterator X87MODEF [SF DF XF])
947
948 ;; SSE instruction suffix for various modes
949 (define_mode_attr ssemodesuffix
950 [(SF "ss") (DF "sd")
951 (V8SF "ps") (V4DF "pd")
952 (V4SF "ps") (V2DF "pd")
953 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
954 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
955
956 ;; SSE vector suffix for floating point modes
957 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
958
959 ;; SSE vector mode corresponding to a scalar mode
960 (define_mode_attr ssevecmode
961 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
962
963 ;; Instruction suffix for REX 64bit operators.
964 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
965
966 ;; This mode iterator allows :P to be used for patterns that operate on
967 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
968 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
969
970 ;; This mode iterator allows :PTR to be used for patterns that operate on
971 ;; ptr_mode sized quantities.
972 (define_mode_iterator PTR
973 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
974 \f
975 ;; Scheduling descriptions
976
977 (include "pentium.md")
978 (include "ppro.md")
979 (include "k6.md")
980 (include "athlon.md")
981 (include "bdver1.md")
982 (include "geode.md")
983 (include "atom.md")
984 (include "core2.md")
985
986 \f
987 ;; Operand and operator predicates and constraints
988
989 (include "predicates.md")
990 (include "constraints.md")
991
992 \f
993 ;; Compare and branch/compare and store instructions.
994
995 (define_expand "cbranch<mode>4"
996 [(set (reg:CC FLAGS_REG)
997 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
998 (match_operand:SDWIM 2 "<general_operand>" "")))
999 (set (pc) (if_then_else
1000 (match_operator 0 "ordered_comparison_operator"
1001 [(reg:CC FLAGS_REG) (const_int 0)])
1002 (label_ref (match_operand 3 "" ""))
1003 (pc)))]
1004 ""
1005 {
1006 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1007 operands[1] = force_reg (<MODE>mode, operands[1]);
1008 ix86_expand_branch (GET_CODE (operands[0]),
1009 operands[1], operands[2], operands[3]);
1010 DONE;
1011 })
1012
1013 (define_expand "cstore<mode>4"
1014 [(set (reg:CC FLAGS_REG)
1015 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1016 (match_operand:SWIM 3 "<general_operand>" "")))
1017 (set (match_operand:QI 0 "register_operand" "")
1018 (match_operator 1 "ordered_comparison_operator"
1019 [(reg:CC FLAGS_REG) (const_int 0)]))]
1020 ""
1021 {
1022 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1023 operands[2] = force_reg (<MODE>mode, operands[2]);
1024 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1025 operands[2], operands[3]);
1026 DONE;
1027 })
1028
1029 (define_expand "cmp<mode>_1"
1030 [(set (reg:CC FLAGS_REG)
1031 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1032 (match_operand:SWI48 1 "<general_operand>" "")))])
1033
1034 (define_insn "*cmp<mode>_ccno_1"
1035 [(set (reg FLAGS_REG)
1036 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1037 (match_operand:SWI 1 "const0_operand" "")))]
1038 "ix86_match_ccmode (insn, CCNOmode)"
1039 "@
1040 test{<imodesuffix>}\t%0, %0
1041 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1042 [(set_attr "type" "test,icmp")
1043 (set_attr "length_immediate" "0,1")
1044 (set_attr "mode" "<MODE>")])
1045
1046 (define_insn "*cmp<mode>_1"
1047 [(set (reg FLAGS_REG)
1048 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1049 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1050 "ix86_match_ccmode (insn, CCmode)"
1051 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1052 [(set_attr "type" "icmp")
1053 (set_attr "mode" "<MODE>")])
1054
1055 (define_insn "*cmp<mode>_minus_1"
1056 [(set (reg FLAGS_REG)
1057 (compare
1058 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1059 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1060 (const_int 0)))]
1061 "ix86_match_ccmode (insn, CCGOCmode)"
1062 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1063 [(set_attr "type" "icmp")
1064 (set_attr "mode" "<MODE>")])
1065
1066 (define_insn "*cmpqi_ext_1"
1067 [(set (reg FLAGS_REG)
1068 (compare
1069 (match_operand:QI 0 "general_operand" "Qm")
1070 (subreg:QI
1071 (zero_extract:SI
1072 (match_operand 1 "ext_register_operand" "Q")
1073 (const_int 8)
1074 (const_int 8)) 0)))]
1075 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076 "cmp{b}\t{%h1, %0|%0, %h1}"
1077 [(set_attr "type" "icmp")
1078 (set_attr "mode" "QI")])
1079
1080 (define_insn "*cmpqi_ext_1_rex64"
1081 [(set (reg FLAGS_REG)
1082 (compare
1083 (match_operand:QI 0 "register_operand" "Q")
1084 (subreg:QI
1085 (zero_extract:SI
1086 (match_operand 1 "ext_register_operand" "Q")
1087 (const_int 8)
1088 (const_int 8)) 0)))]
1089 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1090 "cmp{b}\t{%h1, %0|%0, %h1}"
1091 [(set_attr "type" "icmp")
1092 (set_attr "mode" "QI")])
1093
1094 (define_insn "*cmpqi_ext_2"
1095 [(set (reg FLAGS_REG)
1096 (compare
1097 (subreg:QI
1098 (zero_extract:SI
1099 (match_operand 0 "ext_register_operand" "Q")
1100 (const_int 8)
1101 (const_int 8)) 0)
1102 (match_operand:QI 1 "const0_operand" "")))]
1103 "ix86_match_ccmode (insn, CCNOmode)"
1104 "test{b}\t%h0, %h0"
1105 [(set_attr "type" "test")
1106 (set_attr "length_immediate" "0")
1107 (set_attr "mode" "QI")])
1108
1109 (define_expand "cmpqi_ext_3"
1110 [(set (reg:CC FLAGS_REG)
1111 (compare:CC
1112 (subreg:QI
1113 (zero_extract:SI
1114 (match_operand 0 "ext_register_operand" "")
1115 (const_int 8)
1116 (const_int 8)) 0)
1117 (match_operand:QI 1 "immediate_operand" "")))])
1118
1119 (define_insn "*cmpqi_ext_3_insn"
1120 [(set (reg FLAGS_REG)
1121 (compare
1122 (subreg:QI
1123 (zero_extract:SI
1124 (match_operand 0 "ext_register_operand" "Q")
1125 (const_int 8)
1126 (const_int 8)) 0)
1127 (match_operand:QI 1 "general_operand" "Qmn")))]
1128 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1129 "cmp{b}\t{%1, %h0|%h0, %1}"
1130 [(set_attr "type" "icmp")
1131 (set_attr "modrm" "1")
1132 (set_attr "mode" "QI")])
1133
1134 (define_insn "*cmpqi_ext_3_insn_rex64"
1135 [(set (reg FLAGS_REG)
1136 (compare
1137 (subreg:QI
1138 (zero_extract:SI
1139 (match_operand 0 "ext_register_operand" "Q")
1140 (const_int 8)
1141 (const_int 8)) 0)
1142 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1143 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1144 "cmp{b}\t{%1, %h0|%h0, %1}"
1145 [(set_attr "type" "icmp")
1146 (set_attr "modrm" "1")
1147 (set_attr "mode" "QI")])
1148
1149 (define_insn "*cmpqi_ext_4"
1150 [(set (reg FLAGS_REG)
1151 (compare
1152 (subreg:QI
1153 (zero_extract:SI
1154 (match_operand 0 "ext_register_operand" "Q")
1155 (const_int 8)
1156 (const_int 8)) 0)
1157 (subreg:QI
1158 (zero_extract:SI
1159 (match_operand 1 "ext_register_operand" "Q")
1160 (const_int 8)
1161 (const_int 8)) 0)))]
1162 "ix86_match_ccmode (insn, CCmode)"
1163 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1164 [(set_attr "type" "icmp")
1165 (set_attr "mode" "QI")])
1166
1167 ;; These implement float point compares.
1168 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1169 ;; which would allow mix and match FP modes on the compares. Which is what
1170 ;; the old patterns did, but with many more of them.
1171
1172 (define_expand "cbranchxf4"
1173 [(set (reg:CC FLAGS_REG)
1174 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1175 (match_operand:XF 2 "nonmemory_operand" "")))
1176 (set (pc) (if_then_else
1177 (match_operator 0 "ix86_fp_comparison_operator"
1178 [(reg:CC FLAGS_REG)
1179 (const_int 0)])
1180 (label_ref (match_operand 3 "" ""))
1181 (pc)))]
1182 "TARGET_80387"
1183 {
1184 ix86_expand_branch (GET_CODE (operands[0]),
1185 operands[1], operands[2], operands[3]);
1186 DONE;
1187 })
1188
1189 (define_expand "cstorexf4"
1190 [(set (reg:CC FLAGS_REG)
1191 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1192 (match_operand:XF 3 "nonmemory_operand" "")))
1193 (set (match_operand:QI 0 "register_operand" "")
1194 (match_operator 1 "ix86_fp_comparison_operator"
1195 [(reg:CC FLAGS_REG)
1196 (const_int 0)]))]
1197 "TARGET_80387"
1198 {
1199 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1200 operands[2], operands[3]);
1201 DONE;
1202 })
1203
1204 (define_expand "cbranch<mode>4"
1205 [(set (reg:CC FLAGS_REG)
1206 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1207 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1208 (set (pc) (if_then_else
1209 (match_operator 0 "ix86_fp_comparison_operator"
1210 [(reg:CC FLAGS_REG)
1211 (const_int 0)])
1212 (label_ref (match_operand 3 "" ""))
1213 (pc)))]
1214 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1215 {
1216 ix86_expand_branch (GET_CODE (operands[0]),
1217 operands[1], operands[2], operands[3]);
1218 DONE;
1219 })
1220
1221 (define_expand "cstore<mode>4"
1222 [(set (reg:CC FLAGS_REG)
1223 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1224 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1225 (set (match_operand:QI 0 "register_operand" "")
1226 (match_operator 1 "ix86_fp_comparison_operator"
1227 [(reg:CC FLAGS_REG)
1228 (const_int 0)]))]
1229 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1230 {
1231 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1232 operands[2], operands[3]);
1233 DONE;
1234 })
1235
1236 (define_expand "cbranchcc4"
1237 [(set (pc) (if_then_else
1238 (match_operator 0 "comparison_operator"
1239 [(match_operand 1 "flags_reg_operand" "")
1240 (match_operand 2 "const0_operand" "")])
1241 (label_ref (match_operand 3 "" ""))
1242 (pc)))]
1243 ""
1244 {
1245 ix86_expand_branch (GET_CODE (operands[0]),
1246 operands[1], operands[2], operands[3]);
1247 DONE;
1248 })
1249
1250 (define_expand "cstorecc4"
1251 [(set (match_operand:QI 0 "register_operand" "")
1252 (match_operator 1 "comparison_operator"
1253 [(match_operand 2 "flags_reg_operand" "")
1254 (match_operand 3 "const0_operand" "")]))]
1255 ""
1256 {
1257 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1258 operands[2], operands[3]);
1259 DONE;
1260 })
1261
1262
1263 ;; FP compares, step 1:
1264 ;; Set the FP condition codes.
1265 ;;
1266 ;; CCFPmode compare with exceptions
1267 ;; CCFPUmode compare with no exceptions
1268
1269 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1270 ;; used to manage the reg stack popping would not be preserved.
1271
1272 (define_insn "*cmpfp_0"
1273 [(set (match_operand:HI 0 "register_operand" "=a")
1274 (unspec:HI
1275 [(compare:CCFP
1276 (match_operand 1 "register_operand" "f")
1277 (match_operand 2 "const0_operand" ""))]
1278 UNSPEC_FNSTSW))]
1279 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1280 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1281 "* return output_fp_compare (insn, operands, false, false);"
1282 [(set_attr "type" "multi")
1283 (set_attr "unit" "i387")
1284 (set (attr "mode")
1285 (cond [(match_operand:SF 1 "" "")
1286 (const_string "SF")
1287 (match_operand:DF 1 "" "")
1288 (const_string "DF")
1289 ]
1290 (const_string "XF")))])
1291
1292 (define_insn_and_split "*cmpfp_0_cc"
1293 [(set (reg:CCFP FLAGS_REG)
1294 (compare:CCFP
1295 (match_operand 1 "register_operand" "f")
1296 (match_operand 2 "const0_operand" "")))
1297 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1298 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1299 && TARGET_SAHF && !TARGET_CMOVE
1300 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1301 "#"
1302 "&& reload_completed"
1303 [(set (match_dup 0)
1304 (unspec:HI
1305 [(compare:CCFP (match_dup 1)(match_dup 2))]
1306 UNSPEC_FNSTSW))
1307 (set (reg:CC FLAGS_REG)
1308 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1309 ""
1310 [(set_attr "type" "multi")
1311 (set_attr "unit" "i387")
1312 (set (attr "mode")
1313 (cond [(match_operand:SF 1 "" "")
1314 (const_string "SF")
1315 (match_operand:DF 1 "" "")
1316 (const_string "DF")
1317 ]
1318 (const_string "XF")))])
1319
1320 (define_insn "*cmpfp_xf"
1321 [(set (match_operand:HI 0 "register_operand" "=a")
1322 (unspec:HI
1323 [(compare:CCFP
1324 (match_operand:XF 1 "register_operand" "f")
1325 (match_operand:XF 2 "register_operand" "f"))]
1326 UNSPEC_FNSTSW))]
1327 "TARGET_80387"
1328 "* return output_fp_compare (insn, operands, false, false);"
1329 [(set_attr "type" "multi")
1330 (set_attr "unit" "i387")
1331 (set_attr "mode" "XF")])
1332
1333 (define_insn_and_split "*cmpfp_xf_cc"
1334 [(set (reg:CCFP FLAGS_REG)
1335 (compare:CCFP
1336 (match_operand:XF 1 "register_operand" "f")
1337 (match_operand:XF 2 "register_operand" "f")))
1338 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1339 "TARGET_80387
1340 && TARGET_SAHF && !TARGET_CMOVE"
1341 "#"
1342 "&& reload_completed"
1343 [(set (match_dup 0)
1344 (unspec:HI
1345 [(compare:CCFP (match_dup 1)(match_dup 2))]
1346 UNSPEC_FNSTSW))
1347 (set (reg:CC FLAGS_REG)
1348 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1349 ""
1350 [(set_attr "type" "multi")
1351 (set_attr "unit" "i387")
1352 (set_attr "mode" "XF")])
1353
1354 (define_insn "*cmpfp_<mode>"
1355 [(set (match_operand:HI 0 "register_operand" "=a")
1356 (unspec:HI
1357 [(compare:CCFP
1358 (match_operand:MODEF 1 "register_operand" "f")
1359 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1360 UNSPEC_FNSTSW))]
1361 "TARGET_80387"
1362 "* return output_fp_compare (insn, operands, false, false);"
1363 [(set_attr "type" "multi")
1364 (set_attr "unit" "i387")
1365 (set_attr "mode" "<MODE>")])
1366
1367 (define_insn_and_split "*cmpfp_<mode>_cc"
1368 [(set (reg:CCFP FLAGS_REG)
1369 (compare:CCFP
1370 (match_operand:MODEF 1 "register_operand" "f")
1371 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1372 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1373 "TARGET_80387
1374 && TARGET_SAHF && !TARGET_CMOVE"
1375 "#"
1376 "&& reload_completed"
1377 [(set (match_dup 0)
1378 (unspec:HI
1379 [(compare:CCFP (match_dup 1)(match_dup 2))]
1380 UNSPEC_FNSTSW))
1381 (set (reg:CC FLAGS_REG)
1382 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1383 ""
1384 [(set_attr "type" "multi")
1385 (set_attr "unit" "i387")
1386 (set_attr "mode" "<MODE>")])
1387
1388 (define_insn "*cmpfp_u"
1389 [(set (match_operand:HI 0 "register_operand" "=a")
1390 (unspec:HI
1391 [(compare:CCFPU
1392 (match_operand 1 "register_operand" "f")
1393 (match_operand 2 "register_operand" "f"))]
1394 UNSPEC_FNSTSW))]
1395 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1396 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1397 "* return output_fp_compare (insn, operands, false, true);"
1398 [(set_attr "type" "multi")
1399 (set_attr "unit" "i387")
1400 (set (attr "mode")
1401 (cond [(match_operand:SF 1 "" "")
1402 (const_string "SF")
1403 (match_operand:DF 1 "" "")
1404 (const_string "DF")
1405 ]
1406 (const_string "XF")))])
1407
1408 (define_insn_and_split "*cmpfp_u_cc"
1409 [(set (reg:CCFPU FLAGS_REG)
1410 (compare:CCFPU
1411 (match_operand 1 "register_operand" "f")
1412 (match_operand 2 "register_operand" "f")))
1413 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1414 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1415 && TARGET_SAHF && !TARGET_CMOVE
1416 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1417 "#"
1418 "&& reload_completed"
1419 [(set (match_dup 0)
1420 (unspec:HI
1421 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1422 UNSPEC_FNSTSW))
1423 (set (reg:CC FLAGS_REG)
1424 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1425 ""
1426 [(set_attr "type" "multi")
1427 (set_attr "unit" "i387")
1428 (set (attr "mode")
1429 (cond [(match_operand:SF 1 "" "")
1430 (const_string "SF")
1431 (match_operand:DF 1 "" "")
1432 (const_string "DF")
1433 ]
1434 (const_string "XF")))])
1435
1436 (define_insn "*cmpfp_<mode>"
1437 [(set (match_operand:HI 0 "register_operand" "=a")
1438 (unspec:HI
1439 [(compare:CCFP
1440 (match_operand 1 "register_operand" "f")
1441 (match_operator 3 "float_operator"
1442 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1443 UNSPEC_FNSTSW))]
1444 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1445 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1446 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1447 "* return output_fp_compare (insn, operands, false, false);"
1448 [(set_attr "type" "multi")
1449 (set_attr "unit" "i387")
1450 (set_attr "fp_int_src" "true")
1451 (set_attr "mode" "<MODE>")])
1452
1453 (define_insn_and_split "*cmpfp_<mode>_cc"
1454 [(set (reg:CCFP FLAGS_REG)
1455 (compare:CCFP
1456 (match_operand 1 "register_operand" "f")
1457 (match_operator 3 "float_operator"
1458 [(match_operand:SWI24 2 "memory_operand" "m")])))
1459 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1460 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1461 && TARGET_SAHF && !TARGET_CMOVE
1462 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1463 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1464 "#"
1465 "&& reload_completed"
1466 [(set (match_dup 0)
1467 (unspec:HI
1468 [(compare:CCFP
1469 (match_dup 1)
1470 (match_op_dup 3 [(match_dup 2)]))]
1471 UNSPEC_FNSTSW))
1472 (set (reg:CC FLAGS_REG)
1473 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1474 ""
1475 [(set_attr "type" "multi")
1476 (set_attr "unit" "i387")
1477 (set_attr "fp_int_src" "true")
1478 (set_attr "mode" "<MODE>")])
1479
1480 ;; FP compares, step 2
1481 ;; Move the fpsw to ax.
1482
1483 (define_insn "x86_fnstsw_1"
1484 [(set (match_operand:HI 0 "register_operand" "=a")
1485 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1486 "TARGET_80387"
1487 "fnstsw\t%0"
1488 [(set (attr "length")
1489 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1490 (set_attr "mode" "SI")
1491 (set_attr "unit" "i387")])
1492
1493 ;; FP compares, step 3
1494 ;; Get ax into flags, general case.
1495
1496 (define_insn "x86_sahf_1"
1497 [(set (reg:CC FLAGS_REG)
1498 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1499 UNSPEC_SAHF))]
1500 "TARGET_SAHF"
1501 {
1502 #ifndef HAVE_AS_IX86_SAHF
1503 if (TARGET_64BIT)
1504 return ASM_BYTE "0x9e";
1505 else
1506 #endif
1507 return "sahf";
1508 }
1509 [(set_attr "length" "1")
1510 (set_attr "athlon_decode" "vector")
1511 (set_attr "amdfam10_decode" "direct")
1512 (set_attr "bdver1_decode" "direct")
1513 (set_attr "mode" "SI")])
1514
1515 ;; Pentium Pro can do steps 1 through 3 in one go.
1516 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1517 ;; (these i387 instructions set flags directly)
1518 (define_insn "*cmpfp_i_mixed"
1519 [(set (reg:CCFP FLAGS_REG)
1520 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1521 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1522 "TARGET_MIX_SSE_I387
1523 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1524 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1525 "* return output_fp_compare (insn, operands, true, false);"
1526 [(set_attr "type" "fcmp,ssecomi")
1527 (set_attr "prefix" "orig,maybe_vex")
1528 (set (attr "mode")
1529 (if_then_else (match_operand:SF 1 "" "")
1530 (const_string "SF")
1531 (const_string "DF")))
1532 (set (attr "prefix_rep")
1533 (if_then_else (eq_attr "type" "ssecomi")
1534 (const_string "0")
1535 (const_string "*")))
1536 (set (attr "prefix_data16")
1537 (cond [(eq_attr "type" "fcmp")
1538 (const_string "*")
1539 (eq_attr "mode" "DF")
1540 (const_string "1")
1541 ]
1542 (const_string "0")))
1543 (set_attr "athlon_decode" "vector")
1544 (set_attr "amdfam10_decode" "direct")
1545 (set_attr "bdver1_decode" "double")])
1546
1547 (define_insn "*cmpfp_i_sse"
1548 [(set (reg:CCFP FLAGS_REG)
1549 (compare:CCFP (match_operand 0 "register_operand" "x")
1550 (match_operand 1 "nonimmediate_operand" "xm")))]
1551 "TARGET_SSE_MATH
1552 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1553 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1554 "* return output_fp_compare (insn, operands, true, false);"
1555 [(set_attr "type" "ssecomi")
1556 (set_attr "prefix" "maybe_vex")
1557 (set (attr "mode")
1558 (if_then_else (match_operand:SF 1 "" "")
1559 (const_string "SF")
1560 (const_string "DF")))
1561 (set_attr "prefix_rep" "0")
1562 (set (attr "prefix_data16")
1563 (if_then_else (eq_attr "mode" "DF")
1564 (const_string "1")
1565 (const_string "0")))
1566 (set_attr "athlon_decode" "vector")
1567 (set_attr "amdfam10_decode" "direct")
1568 (set_attr "bdver1_decode" "double")])
1569
1570 (define_insn "*cmpfp_i_i387"
1571 [(set (reg:CCFP FLAGS_REG)
1572 (compare:CCFP (match_operand 0 "register_operand" "f")
1573 (match_operand 1 "register_operand" "f")))]
1574 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1575 && TARGET_CMOVE
1576 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1577 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1578 "* return output_fp_compare (insn, operands, true, false);"
1579 [(set_attr "type" "fcmp")
1580 (set (attr "mode")
1581 (cond [(match_operand:SF 1 "" "")
1582 (const_string "SF")
1583 (match_operand:DF 1 "" "")
1584 (const_string "DF")
1585 ]
1586 (const_string "XF")))
1587 (set_attr "athlon_decode" "vector")
1588 (set_attr "amdfam10_decode" "direct")
1589 (set_attr "bdver1_decode" "double")])
1590
1591 (define_insn "*cmpfp_iu_mixed"
1592 [(set (reg:CCFPU FLAGS_REG)
1593 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1594 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1595 "TARGET_MIX_SSE_I387
1596 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1597 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1598 "* return output_fp_compare (insn, operands, true, true);"
1599 [(set_attr "type" "fcmp,ssecomi")
1600 (set_attr "prefix" "orig,maybe_vex")
1601 (set (attr "mode")
1602 (if_then_else (match_operand:SF 1 "" "")
1603 (const_string "SF")
1604 (const_string "DF")))
1605 (set (attr "prefix_rep")
1606 (if_then_else (eq_attr "type" "ssecomi")
1607 (const_string "0")
1608 (const_string "*")))
1609 (set (attr "prefix_data16")
1610 (cond [(eq_attr "type" "fcmp")
1611 (const_string "*")
1612 (eq_attr "mode" "DF")
1613 (const_string "1")
1614 ]
1615 (const_string "0")))
1616 (set_attr "athlon_decode" "vector")
1617 (set_attr "amdfam10_decode" "direct")
1618 (set_attr "bdver1_decode" "double")])
1619
1620 (define_insn "*cmpfp_iu_sse"
1621 [(set (reg:CCFPU FLAGS_REG)
1622 (compare:CCFPU (match_operand 0 "register_operand" "x")
1623 (match_operand 1 "nonimmediate_operand" "xm")))]
1624 "TARGET_SSE_MATH
1625 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1626 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1627 "* return output_fp_compare (insn, operands, true, true);"
1628 [(set_attr "type" "ssecomi")
1629 (set_attr "prefix" "maybe_vex")
1630 (set (attr "mode")
1631 (if_then_else (match_operand:SF 1 "" "")
1632 (const_string "SF")
1633 (const_string "DF")))
1634 (set_attr "prefix_rep" "0")
1635 (set (attr "prefix_data16")
1636 (if_then_else (eq_attr "mode" "DF")
1637 (const_string "1")
1638 (const_string "0")))
1639 (set_attr "athlon_decode" "vector")
1640 (set_attr "amdfam10_decode" "direct")
1641 (set_attr "bdver1_decode" "double")])
1642
1643 (define_insn "*cmpfp_iu_387"
1644 [(set (reg:CCFPU FLAGS_REG)
1645 (compare:CCFPU (match_operand 0 "register_operand" "f")
1646 (match_operand 1 "register_operand" "f")))]
1647 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1648 && TARGET_CMOVE
1649 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1650 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1651 "* return output_fp_compare (insn, operands, true, true);"
1652 [(set_attr "type" "fcmp")
1653 (set (attr "mode")
1654 (cond [(match_operand:SF 1 "" "")
1655 (const_string "SF")
1656 (match_operand:DF 1 "" "")
1657 (const_string "DF")
1658 ]
1659 (const_string "XF")))
1660 (set_attr "athlon_decode" "vector")
1661 (set_attr "amdfam10_decode" "direct")
1662 (set_attr "bdver1_decode" "direct")])
1663 \f
1664 ;; Push/pop instructions.
1665
1666 (define_insn "*push<mode>2"
1667 [(set (match_operand:DWI 0 "push_operand" "=<")
1668 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1669 ""
1670 "#"
1671 [(set_attr "type" "multi")
1672 (set_attr "mode" "<MODE>")])
1673
1674 (define_split
1675 [(set (match_operand:TI 0 "push_operand" "")
1676 (match_operand:TI 1 "general_operand" ""))]
1677 "TARGET_64BIT && reload_completed
1678 && !SSE_REG_P (operands[1])"
1679 [(const_int 0)]
1680 "ix86_split_long_move (operands); DONE;")
1681
1682 (define_insn "*pushdi2_rex64"
1683 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1684 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1685 "TARGET_64BIT"
1686 "@
1687 push{q}\t%1
1688 #"
1689 [(set_attr "type" "push,multi")
1690 (set_attr "mode" "DI")])
1691
1692 ;; Convert impossible pushes of immediate to existing instructions.
1693 ;; First try to get scratch register and go through it. In case this
1694 ;; fails, push sign extended lower part first and then overwrite
1695 ;; upper part by 32bit move.
1696 (define_peephole2
1697 [(match_scratch:DI 2 "r")
1698 (set (match_operand:DI 0 "push_operand" "")
1699 (match_operand:DI 1 "immediate_operand" ""))]
1700 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1701 && !x86_64_immediate_operand (operands[1], DImode)"
1702 [(set (match_dup 2) (match_dup 1))
1703 (set (match_dup 0) (match_dup 2))])
1704
1705 ;; We need to define this as both peepholer and splitter for case
1706 ;; peephole2 pass is not run.
1707 ;; "&& 1" is needed to keep it from matching the previous pattern.
1708 (define_peephole2
1709 [(set (match_operand:DI 0 "push_operand" "")
1710 (match_operand:DI 1 "immediate_operand" ""))]
1711 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1712 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1713 [(set (match_dup 0) (match_dup 1))
1714 (set (match_dup 2) (match_dup 3))]
1715 {
1716 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1717
1718 operands[1] = gen_lowpart (DImode, operands[2]);
1719 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1720 GEN_INT (4)));
1721 })
1722
1723 (define_split
1724 [(set (match_operand:DI 0 "push_operand" "")
1725 (match_operand:DI 1 "immediate_operand" ""))]
1726 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1727 ? epilogue_completed : reload_completed)
1728 && !symbolic_operand (operands[1], DImode)
1729 && !x86_64_immediate_operand (operands[1], DImode)"
1730 [(set (match_dup 0) (match_dup 1))
1731 (set (match_dup 2) (match_dup 3))]
1732 {
1733 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1734
1735 operands[1] = gen_lowpart (DImode, operands[2]);
1736 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1737 GEN_INT (4)));
1738 })
1739
1740 (define_split
1741 [(set (match_operand:DI 0 "push_operand" "")
1742 (match_operand:DI 1 "general_operand" ""))]
1743 "!TARGET_64BIT && reload_completed
1744 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1745 [(const_int 0)]
1746 "ix86_split_long_move (operands); DONE;")
1747
1748 (define_insn "*pushsi2"
1749 [(set (match_operand:SI 0 "push_operand" "=<")
1750 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1751 "!TARGET_64BIT"
1752 "push{l}\t%1"
1753 [(set_attr "type" "push")
1754 (set_attr "mode" "SI")])
1755
1756 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1757 ;; "push a byte/word". But actually we use pushl, which has the effect
1758 ;; of rounding the amount pushed up to a word.
1759
1760 ;; For TARGET_64BIT we always round up to 8 bytes.
1761 (define_insn "*push<mode>2_rex64"
1762 [(set (match_operand:SWI124 0 "push_operand" "=X")
1763 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1764 "TARGET_64BIT"
1765 "push{q}\t%q1"
1766 [(set_attr "type" "push")
1767 (set_attr "mode" "DI")])
1768
1769 (define_insn "*push<mode>2"
1770 [(set (match_operand:SWI12 0 "push_operand" "=X")
1771 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1772 "!TARGET_64BIT"
1773 "push{l}\t%k1"
1774 [(set_attr "type" "push")
1775 (set_attr "mode" "SI")])
1776
1777 (define_insn "*push<mode>2_prologue"
1778 [(set (match_operand:P 0 "push_operand" "=<")
1779 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1780 (clobber (mem:BLK (scratch)))]
1781 ""
1782 "push{<imodesuffix>}\t%1"
1783 [(set_attr "type" "push")
1784 (set_attr "mode" "<MODE>")])
1785
1786 (define_insn "*pop<mode>1"
1787 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1788 (match_operand:P 1 "pop_operand" ">"))]
1789 ""
1790 "pop{<imodesuffix>}\t%0"
1791 [(set_attr "type" "pop")
1792 (set_attr "mode" "<MODE>")])
1793
1794 (define_insn "*pop<mode>1_epilogue"
1795 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1796 (match_operand:P 1 "pop_operand" ">"))
1797 (clobber (mem:BLK (scratch)))]
1798 ""
1799 "pop{<imodesuffix>}\t%0"
1800 [(set_attr "type" "pop")
1801 (set_attr "mode" "<MODE>")])
1802 \f
1803 ;; Move instructions.
1804
1805 (define_expand "movoi"
1806 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1807 (match_operand:OI 1 "general_operand" ""))]
1808 "TARGET_AVX"
1809 "ix86_expand_move (OImode, operands); DONE;")
1810
1811 (define_expand "movti"
1812 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1813 (match_operand:TI 1 "nonimmediate_operand" ""))]
1814 "TARGET_64BIT || TARGET_SSE"
1815 {
1816 if (TARGET_64BIT)
1817 ix86_expand_move (TImode, operands);
1818 else if (push_operand (operands[0], TImode))
1819 ix86_expand_push (TImode, operands[1]);
1820 else
1821 ix86_expand_vector_move (TImode, operands);
1822 DONE;
1823 })
1824
1825 ;; This expands to what emit_move_complex would generate if we didn't
1826 ;; have a movti pattern. Having this avoids problems with reload on
1827 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1828 ;; to have around all the time.
1829 (define_expand "movcdi"
1830 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1831 (match_operand:CDI 1 "general_operand" ""))]
1832 ""
1833 {
1834 if (push_operand (operands[0], CDImode))
1835 emit_move_complex_push (CDImode, operands[0], operands[1]);
1836 else
1837 emit_move_complex_parts (operands[0], operands[1]);
1838 DONE;
1839 })
1840
1841 (define_expand "mov<mode>"
1842 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1843 (match_operand:SWI1248x 1 "general_operand" ""))]
1844 ""
1845 "ix86_expand_move (<MODE>mode, operands); DONE;")
1846
1847 (define_insn "*mov<mode>_xor"
1848 [(set (match_operand:SWI48 0 "register_operand" "=r")
1849 (match_operand:SWI48 1 "const0_operand" ""))
1850 (clobber (reg:CC FLAGS_REG))]
1851 "reload_completed"
1852 "xor{l}\t%k0, %k0"
1853 [(set_attr "type" "alu1")
1854 (set_attr "mode" "SI")
1855 (set_attr "length_immediate" "0")])
1856
1857 (define_insn "*mov<mode>_or"
1858 [(set (match_operand:SWI48 0 "register_operand" "=r")
1859 (match_operand:SWI48 1 "const_int_operand" ""))
1860 (clobber (reg:CC FLAGS_REG))]
1861 "reload_completed
1862 && operands[1] == constm1_rtx"
1863 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1864 [(set_attr "type" "alu1")
1865 (set_attr "mode" "<MODE>")
1866 (set_attr "length_immediate" "1")])
1867
1868 (define_insn "*movoi_internal_avx"
1869 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1870 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1871 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1872 {
1873 switch (which_alternative)
1874 {
1875 case 0:
1876 return standard_sse_constant_opcode (insn, operands[1]);
1877 case 1:
1878 case 2:
1879 if (misaligned_operand (operands[0], OImode)
1880 || misaligned_operand (operands[1], OImode))
1881 return "vmovdqu\t{%1, %0|%0, %1}";
1882 else
1883 return "vmovdqa\t{%1, %0|%0, %1}";
1884 default:
1885 gcc_unreachable ();
1886 }
1887 }
1888 [(set_attr "type" "sselog1,ssemov,ssemov")
1889 (set_attr "prefix" "vex")
1890 (set_attr "mode" "OI")])
1891
1892 (define_insn "*movti_internal_rex64"
1893 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1894 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1895 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1896 {
1897 switch (which_alternative)
1898 {
1899 case 0:
1900 case 1:
1901 return "#";
1902 case 2:
1903 return standard_sse_constant_opcode (insn, operands[1]);
1904 case 3:
1905 case 4:
1906 /* TDmode values are passed as TImode on the stack. Moving them
1907 to stack may result in unaligned memory access. */
1908 if (misaligned_operand (operands[0], TImode)
1909 || misaligned_operand (operands[1], TImode))
1910 {
1911 if (get_attr_mode (insn) == MODE_V4SF)
1912 return "%vmovups\t{%1, %0|%0, %1}";
1913 else
1914 return "%vmovdqu\t{%1, %0|%0, %1}";
1915 }
1916 else
1917 {
1918 if (get_attr_mode (insn) == MODE_V4SF)
1919 return "%vmovaps\t{%1, %0|%0, %1}";
1920 else
1921 return "%vmovdqa\t{%1, %0|%0, %1}";
1922 }
1923 default:
1924 gcc_unreachable ();
1925 }
1926 }
1927 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1928 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1929 (set (attr "mode")
1930 (cond [(eq_attr "alternative" "2,3")
1931 (if_then_else
1932 (match_test "optimize_function_for_size_p (cfun)")
1933 (const_string "V4SF")
1934 (const_string "TI"))
1935 (eq_attr "alternative" "4")
1936 (if_then_else
1937 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1938 (match_test "optimize_function_for_size_p (cfun)"))
1939 (const_string "V4SF")
1940 (const_string "TI"))]
1941 (const_string "DI")))])
1942
1943 (define_split
1944 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1945 (match_operand:TI 1 "general_operand" ""))]
1946 "reload_completed
1947 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1948 [(const_int 0)]
1949 "ix86_split_long_move (operands); DONE;")
1950
1951 (define_insn "*movti_internal_sse"
1952 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1953 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1954 "TARGET_SSE && !TARGET_64BIT
1955 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1956 {
1957 switch (which_alternative)
1958 {
1959 case 0:
1960 return standard_sse_constant_opcode (insn, operands[1]);
1961 case 1:
1962 case 2:
1963 /* TDmode values are passed as TImode on the stack. Moving them
1964 to stack may result in unaligned memory access. */
1965 if (misaligned_operand (operands[0], TImode)
1966 || misaligned_operand (operands[1], TImode))
1967 {
1968 if (get_attr_mode (insn) == MODE_V4SF)
1969 return "%vmovups\t{%1, %0|%0, %1}";
1970 else
1971 return "%vmovdqu\t{%1, %0|%0, %1}";
1972 }
1973 else
1974 {
1975 if (get_attr_mode (insn) == MODE_V4SF)
1976 return "%vmovaps\t{%1, %0|%0, %1}";
1977 else
1978 return "%vmovdqa\t{%1, %0|%0, %1}";
1979 }
1980 default:
1981 gcc_unreachable ();
1982 }
1983 }
1984 [(set_attr "type" "sselog1,ssemov,ssemov")
1985 (set_attr "prefix" "maybe_vex")
1986 (set (attr "mode")
1987 (cond [(ior (not (match_test "TARGET_SSE2"))
1988 (match_test "optimize_function_for_size_p (cfun)"))
1989 (const_string "V4SF")
1990 (and (eq_attr "alternative" "2")
1991 (match_test "TARGET_SSE_TYPELESS_STORES"))
1992 (const_string "V4SF")]
1993 (const_string "TI")))])
1994
1995 (define_insn "*movdi_internal_rex64"
1996 [(set (match_operand:DI 0 "nonimmediate_operand"
1997 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1998 (match_operand:DI 1 "general_operand"
1999 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
2000 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2001 {
2002 switch (get_attr_type (insn))
2003 {
2004 case TYPE_SSECVT:
2005 if (SSE_REG_P (operands[0]))
2006 return "movq2dq\t{%1, %0|%0, %1}";
2007 else
2008 return "movdq2q\t{%1, %0|%0, %1}";
2009
2010 case TYPE_SSEMOV:
2011 if (get_attr_mode (insn) == MODE_TI)
2012 return "%vmovdqa\t{%1, %0|%0, %1}";
2013 /* Handle broken assemblers that require movd instead of movq. */
2014 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2015 return "%vmovd\t{%1, %0|%0, %1}";
2016 else
2017 return "%vmovq\t{%1, %0|%0, %1}";
2018
2019 case TYPE_MMXMOV:
2020 /* Handle broken assemblers that require movd instead of movq. */
2021 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2022 return "movd\t{%1, %0|%0, %1}";
2023 else
2024 return "movq\t{%1, %0|%0, %1}";
2025
2026 case TYPE_SSELOG1:
2027 return standard_sse_constant_opcode (insn, operands[1]);
2028
2029 case TYPE_MMX:
2030 return "pxor\t%0, %0";
2031
2032 case TYPE_MULTI:
2033 return "#";
2034
2035 case TYPE_LEA:
2036 return "lea{q}\t{%a1, %0|%0, %a1}";
2037
2038 default:
2039 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2040 if (get_attr_mode (insn) == MODE_SI)
2041 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2042 else if (which_alternative == 2)
2043 return "movabs{q}\t{%1, %0|%0, %1}";
2044 else
2045 return "mov{q}\t{%1, %0|%0, %1}";
2046 }
2047 }
2048 [(set (attr "type")
2049 (cond [(eq_attr "alternative" "4")
2050 (const_string "multi")
2051 (eq_attr "alternative" "5")
2052 (const_string "mmx")
2053 (eq_attr "alternative" "6,7,8,9")
2054 (const_string "mmxmov")
2055 (eq_attr "alternative" "10")
2056 (const_string "sselog1")
2057 (eq_attr "alternative" "11,12,13,14,15")
2058 (const_string "ssemov")
2059 (eq_attr "alternative" "16,17")
2060 (const_string "ssecvt")
2061 (match_operand 1 "pic_32bit_operand" "")
2062 (const_string "lea")
2063 ]
2064 (const_string "imov")))
2065 (set (attr "modrm")
2066 (if_then_else
2067 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2068 (const_string "0")
2069 (const_string "*")))
2070 (set (attr "length_immediate")
2071 (if_then_else
2072 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2073 (const_string "8")
2074 (const_string "*")))
2075 (set (attr "prefix_rex")
2076 (if_then_else (eq_attr "alternative" "8,9")
2077 (const_string "1")
2078 (const_string "*")))
2079 (set (attr "prefix_data16")
2080 (if_then_else (eq_attr "alternative" "11")
2081 (const_string "1")
2082 (const_string "*")))
2083 (set (attr "prefix")
2084 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2085 (const_string "maybe_vex")
2086 (const_string "orig")))
2087 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2088
2089 ;; Reload patterns to support multi-word load/store
2090 ;; with non-offsetable address.
2091 (define_expand "reload_noff_store"
2092 [(parallel [(match_operand 0 "memory_operand" "=m")
2093 (match_operand 1 "register_operand" "r")
2094 (match_operand:DI 2 "register_operand" "=&r")])]
2095 "TARGET_64BIT"
2096 {
2097 rtx mem = operands[0];
2098 rtx addr = XEXP (mem, 0);
2099
2100 emit_move_insn (operands[2], addr);
2101 mem = replace_equiv_address_nv (mem, operands[2]);
2102
2103 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2104 DONE;
2105 })
2106
2107 (define_expand "reload_noff_load"
2108 [(parallel [(match_operand 0 "register_operand" "=r")
2109 (match_operand 1 "memory_operand" "m")
2110 (match_operand:DI 2 "register_operand" "=r")])]
2111 "TARGET_64BIT"
2112 {
2113 rtx mem = operands[1];
2114 rtx addr = XEXP (mem, 0);
2115
2116 emit_move_insn (operands[2], addr);
2117 mem = replace_equiv_address_nv (mem, operands[2]);
2118
2119 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2120 DONE;
2121 })
2122
2123 ;; Convert impossible stores of immediate to existing instructions.
2124 ;; First try to get scratch register and go through it. In case this
2125 ;; fails, move by 32bit parts.
2126 (define_peephole2
2127 [(match_scratch:DI 2 "r")
2128 (set (match_operand:DI 0 "memory_operand" "")
2129 (match_operand:DI 1 "immediate_operand" ""))]
2130 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2131 && !x86_64_immediate_operand (operands[1], DImode)"
2132 [(set (match_dup 2) (match_dup 1))
2133 (set (match_dup 0) (match_dup 2))])
2134
2135 ;; We need to define this as both peepholer and splitter for case
2136 ;; peephole2 pass is not run.
2137 ;; "&& 1" is needed to keep it from matching the previous pattern.
2138 (define_peephole2
2139 [(set (match_operand:DI 0 "memory_operand" "")
2140 (match_operand:DI 1 "immediate_operand" ""))]
2141 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2142 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2143 [(set (match_dup 2) (match_dup 3))
2144 (set (match_dup 4) (match_dup 5))]
2145 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2146
2147 (define_split
2148 [(set (match_operand:DI 0 "memory_operand" "")
2149 (match_operand:DI 1 "immediate_operand" ""))]
2150 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151 ? epilogue_completed : reload_completed)
2152 && !symbolic_operand (operands[1], DImode)
2153 && !x86_64_immediate_operand (operands[1], DImode)"
2154 [(set (match_dup 2) (match_dup 3))
2155 (set (match_dup 4) (match_dup 5))]
2156 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2157
2158 (define_insn "*movdi_internal"
2159 [(set (match_operand:DI 0 "nonimmediate_operand"
2160 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2161 (match_operand:DI 1 "general_operand"
2162 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2163 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2164 {
2165 switch (get_attr_type (insn))
2166 {
2167 case TYPE_SSECVT:
2168 if (SSE_REG_P (operands[0]))
2169 return "movq2dq\t{%1, %0|%0, %1}";
2170 else
2171 return "movdq2q\t{%1, %0|%0, %1}";
2172
2173 case TYPE_SSEMOV:
2174 switch (get_attr_mode (insn))
2175 {
2176 case MODE_TI:
2177 return "%vmovdqa\t{%1, %0|%0, %1}";
2178 case MODE_DI:
2179 return "%vmovq\t{%1, %0|%0, %1}";
2180 case MODE_V4SF:
2181 return "movaps\t{%1, %0|%0, %1}";
2182 case MODE_V2SF:
2183 return "movlps\t{%1, %0|%0, %1}";
2184 default:
2185 gcc_unreachable ();
2186 }
2187
2188 case TYPE_MMXMOV:
2189 return "movq\t{%1, %0|%0, %1}";
2190
2191 case TYPE_SSELOG1:
2192 return standard_sse_constant_opcode (insn, operands[1]);
2193
2194 case TYPE_MMX:
2195 return "pxor\t%0, %0";
2196
2197 case TYPE_MULTI:
2198 return "#";
2199
2200 default:
2201 gcc_unreachable ();
2202 }
2203 }
2204 [(set (attr "isa")
2205 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2206 (const_string "sse2")
2207 (eq_attr "alternative" "9,10,11,12")
2208 (const_string "noavx")
2209 ]
2210 (const_string "*")))
2211 (set (attr "type")
2212 (cond [(eq_attr "alternative" "0,1")
2213 (const_string "multi")
2214 (eq_attr "alternative" "2")
2215 (const_string "mmx")
2216 (eq_attr "alternative" "3,4")
2217 (const_string "mmxmov")
2218 (eq_attr "alternative" "5,9")
2219 (const_string "sselog1")
2220 (eq_attr "alternative" "13,14")
2221 (const_string "ssecvt")
2222 ]
2223 (const_string "ssemov")))
2224 (set (attr "prefix")
2225 (if_then_else (eq_attr "alternative" "5,6,7,8")
2226 (const_string "maybe_vex")
2227 (const_string "orig")))
2228 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2229
2230 (define_split
2231 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2232 (match_operand:DI 1 "general_operand" ""))]
2233 "!TARGET_64BIT && reload_completed
2234 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2235 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2236 [(const_int 0)]
2237 "ix86_split_long_move (operands); DONE;")
2238
2239 (define_insn "*movsi_internal"
2240 [(set (match_operand:SI 0 "nonimmediate_operand"
2241 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2242 (match_operand:SI 1 "general_operand"
2243 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2244 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2245 {
2246 switch (get_attr_type (insn))
2247 {
2248 case TYPE_SSELOG1:
2249 return standard_sse_constant_opcode (insn, operands[1]);
2250
2251 case TYPE_SSEMOV:
2252 switch (get_attr_mode (insn))
2253 {
2254 case MODE_TI:
2255 return "%vmovdqa\t{%1, %0|%0, %1}";
2256 case MODE_V4SF:
2257 return "%vmovaps\t{%1, %0|%0, %1}";
2258 case MODE_SI:
2259 return "%vmovd\t{%1, %0|%0, %1}";
2260 case MODE_SF:
2261 return "%vmovss\t{%1, %0|%0, %1}";
2262 default:
2263 gcc_unreachable ();
2264 }
2265
2266 case TYPE_MMX:
2267 return "pxor\t%0, %0";
2268
2269 case TYPE_MMXMOV:
2270 if (get_attr_mode (insn) == MODE_DI)
2271 return "movq\t{%1, %0|%0, %1}";
2272 return "movd\t{%1, %0|%0, %1}";
2273
2274 case TYPE_LEA:
2275 return "lea{l}\t{%a1, %0|%0, %a1}";
2276
2277 default:
2278 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2279 return "mov{l}\t{%1, %0|%0, %1}";
2280 }
2281 }
2282 [(set (attr "type")
2283 (cond [(eq_attr "alternative" "2")
2284 (const_string "mmx")
2285 (eq_attr "alternative" "3,4,5")
2286 (const_string "mmxmov")
2287 (eq_attr "alternative" "6")
2288 (const_string "sselog1")
2289 (eq_attr "alternative" "7,8,9,10,11")
2290 (const_string "ssemov")
2291 (match_operand 1 "pic_32bit_operand" "")
2292 (const_string "lea")
2293 ]
2294 (const_string "imov")))
2295 (set (attr "prefix")
2296 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2297 (const_string "orig")
2298 (const_string "maybe_vex")))
2299 (set (attr "prefix_data16")
2300 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2301 (const_string "1")
2302 (const_string "*")))
2303 (set (attr "mode")
2304 (cond [(eq_attr "alternative" "2,3")
2305 (const_string "DI")
2306 (eq_attr "alternative" "6,7")
2307 (if_then_else
2308 (not (match_test "TARGET_SSE2"))
2309 (const_string "V4SF")
2310 (const_string "TI"))
2311 (and (eq_attr "alternative" "8,9,10,11")
2312 (not (match_test "TARGET_SSE2")))
2313 (const_string "SF")
2314 ]
2315 (const_string "SI")))])
2316
2317 (define_insn "*movhi_internal"
2318 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2319 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2320 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2321 {
2322 switch (get_attr_type (insn))
2323 {
2324 case TYPE_IMOVX:
2325 /* movzwl is faster than movw on p2 due to partial word stalls,
2326 though not as fast as an aligned movl. */
2327 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2328 default:
2329 if (get_attr_mode (insn) == MODE_SI)
2330 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2331 else
2332 return "mov{w}\t{%1, %0|%0, %1}";
2333 }
2334 }
2335 [(set (attr "type")
2336 (cond [(match_test "optimize_function_for_size_p (cfun)")
2337 (const_string "imov")
2338 (and (eq_attr "alternative" "0")
2339 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2340 (not (match_test "TARGET_HIMODE_MATH"))))
2341 (const_string "imov")
2342 (and (eq_attr "alternative" "1,2")
2343 (match_operand:HI 1 "aligned_operand" ""))
2344 (const_string "imov")
2345 (and (match_test "TARGET_MOVX")
2346 (eq_attr "alternative" "0,2"))
2347 (const_string "imovx")
2348 ]
2349 (const_string "imov")))
2350 (set (attr "mode")
2351 (cond [(eq_attr "type" "imovx")
2352 (const_string "SI")
2353 (and (eq_attr "alternative" "1,2")
2354 (match_operand:HI 1 "aligned_operand" ""))
2355 (const_string "SI")
2356 (and (eq_attr "alternative" "0")
2357 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2358 (not (match_test "TARGET_HIMODE_MATH"))))
2359 (const_string "SI")
2360 ]
2361 (const_string "HI")))])
2362
2363 ;; Situation is quite tricky about when to choose full sized (SImode) move
2364 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2365 ;; partial register dependency machines (such as AMD Athlon), where QImode
2366 ;; moves issue extra dependency and for partial register stalls machines
2367 ;; that don't use QImode patterns (and QImode move cause stall on the next
2368 ;; instruction).
2369 ;;
2370 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2371 ;; register stall machines with, where we use QImode instructions, since
2372 ;; partial register stall can be caused there. Then we use movzx.
2373 (define_insn "*movqi_internal"
2374 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2375 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2376 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2377 {
2378 switch (get_attr_type (insn))
2379 {
2380 case TYPE_IMOVX:
2381 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2382 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2383 default:
2384 if (get_attr_mode (insn) == MODE_SI)
2385 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2386 else
2387 return "mov{b}\t{%1, %0|%0, %1}";
2388 }
2389 }
2390 [(set (attr "type")
2391 (cond [(and (eq_attr "alternative" "5")
2392 (not (match_operand:QI 1 "aligned_operand" "")))
2393 (const_string "imovx")
2394 (match_test "optimize_function_for_size_p (cfun)")
2395 (const_string "imov")
2396 (and (eq_attr "alternative" "3")
2397 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2398 (not (match_test "TARGET_QIMODE_MATH"))))
2399 (const_string "imov")
2400 (eq_attr "alternative" "3,5")
2401 (const_string "imovx")
2402 (and (match_test "TARGET_MOVX")
2403 (eq_attr "alternative" "2"))
2404 (const_string "imovx")
2405 ]
2406 (const_string "imov")))
2407 (set (attr "mode")
2408 (cond [(eq_attr "alternative" "3,4,5")
2409 (const_string "SI")
2410 (eq_attr "alternative" "6")
2411 (const_string "QI")
2412 (eq_attr "type" "imovx")
2413 (const_string "SI")
2414 (and (eq_attr "type" "imov")
2415 (and (eq_attr "alternative" "0,1")
2416 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2417 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2418 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2419 (const_string "SI")
2420 ;; Avoid partial register stalls when not using QImode arithmetic
2421 (and (eq_attr "type" "imov")
2422 (and (eq_attr "alternative" "0,1")
2423 (and (match_test "TARGET_PARTIAL_REG_STALL")
2424 (not (match_test "TARGET_QIMODE_MATH")))))
2425 (const_string "SI")
2426 ]
2427 (const_string "QI")))])
2428
2429 ;; Stores and loads of ax to arbitrary constant address.
2430 ;; We fake an second form of instruction to force reload to load address
2431 ;; into register when rax is not available
2432 (define_insn "*movabs<mode>_1"
2433 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2434 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2435 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2436 "@
2437 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2438 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2439 [(set_attr "type" "imov")
2440 (set_attr "modrm" "0,*")
2441 (set_attr "length_address" "8,0")
2442 (set_attr "length_immediate" "0,*")
2443 (set_attr "memory" "store")
2444 (set_attr "mode" "<MODE>")])
2445
2446 (define_insn "*movabs<mode>_2"
2447 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2448 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2449 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2450 "@
2451 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2452 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2453 [(set_attr "type" "imov")
2454 (set_attr "modrm" "0,*")
2455 (set_attr "length_address" "8,0")
2456 (set_attr "length_immediate" "0")
2457 (set_attr "memory" "load")
2458 (set_attr "mode" "<MODE>")])
2459
2460 (define_insn "*swap<mode>"
2461 [(set (match_operand:SWI48 0 "register_operand" "+r")
2462 (match_operand:SWI48 1 "register_operand" "+r"))
2463 (set (match_dup 1)
2464 (match_dup 0))]
2465 ""
2466 "xchg{<imodesuffix>}\t%1, %0"
2467 [(set_attr "type" "imov")
2468 (set_attr "mode" "<MODE>")
2469 (set_attr "pent_pair" "np")
2470 (set_attr "athlon_decode" "vector")
2471 (set_attr "amdfam10_decode" "double")
2472 (set_attr "bdver1_decode" "double")])
2473
2474 (define_insn "*swap<mode>_1"
2475 [(set (match_operand:SWI12 0 "register_operand" "+r")
2476 (match_operand:SWI12 1 "register_operand" "+r"))
2477 (set (match_dup 1)
2478 (match_dup 0))]
2479 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2480 "xchg{l}\t%k1, %k0"
2481 [(set_attr "type" "imov")
2482 (set_attr "mode" "SI")
2483 (set_attr "pent_pair" "np")
2484 (set_attr "athlon_decode" "vector")
2485 (set_attr "amdfam10_decode" "double")
2486 (set_attr "bdver1_decode" "double")])
2487
2488 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2489 ;; is disabled for AMDFAM10
2490 (define_insn "*swap<mode>_2"
2491 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2492 (match_operand:SWI12 1 "register_operand" "+<r>"))
2493 (set (match_dup 1)
2494 (match_dup 0))]
2495 "TARGET_PARTIAL_REG_STALL"
2496 "xchg{<imodesuffix>}\t%1, %0"
2497 [(set_attr "type" "imov")
2498 (set_attr "mode" "<MODE>")
2499 (set_attr "pent_pair" "np")
2500 (set_attr "athlon_decode" "vector")])
2501
2502 (define_expand "movstrict<mode>"
2503 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2504 (match_operand:SWI12 1 "general_operand" ""))]
2505 ""
2506 {
2507 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2508 FAIL;
2509 if (GET_CODE (operands[0]) == SUBREG
2510 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2511 FAIL;
2512 /* Don't generate memory->memory moves, go through a register */
2513 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2514 operands[1] = force_reg (<MODE>mode, operands[1]);
2515 })
2516
2517 (define_insn "*movstrict<mode>_1"
2518 [(set (strict_low_part
2519 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2520 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2521 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2522 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2523 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2524 [(set_attr "type" "imov")
2525 (set_attr "mode" "<MODE>")])
2526
2527 (define_insn "*movstrict<mode>_xor"
2528 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2529 (match_operand:SWI12 1 "const0_operand" ""))
2530 (clobber (reg:CC FLAGS_REG))]
2531 "reload_completed"
2532 "xor{<imodesuffix>}\t%0, %0"
2533 [(set_attr "type" "alu1")
2534 (set_attr "mode" "<MODE>")
2535 (set_attr "length_immediate" "0")])
2536
2537 (define_insn "*mov<mode>_extv_1"
2538 [(set (match_operand:SWI24 0 "register_operand" "=R")
2539 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2540 (const_int 8)
2541 (const_int 8)))]
2542 ""
2543 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2544 [(set_attr "type" "imovx")
2545 (set_attr "mode" "SI")])
2546
2547 (define_insn "*movqi_extv_1_rex64"
2548 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2549 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2550 (const_int 8)
2551 (const_int 8)))]
2552 "TARGET_64BIT"
2553 {
2554 switch (get_attr_type (insn))
2555 {
2556 case TYPE_IMOVX:
2557 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2558 default:
2559 return "mov{b}\t{%h1, %0|%0, %h1}";
2560 }
2561 }
2562 [(set (attr "type")
2563 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2564 (match_test "TARGET_MOVX"))
2565 (const_string "imovx")
2566 (const_string "imov")))
2567 (set (attr "mode")
2568 (if_then_else (eq_attr "type" "imovx")
2569 (const_string "SI")
2570 (const_string "QI")))])
2571
2572 (define_insn "*movqi_extv_1"
2573 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2574 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2575 (const_int 8)
2576 (const_int 8)))]
2577 "!TARGET_64BIT"
2578 {
2579 switch (get_attr_type (insn))
2580 {
2581 case TYPE_IMOVX:
2582 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2583 default:
2584 return "mov{b}\t{%h1, %0|%0, %h1}";
2585 }
2586 }
2587 [(set (attr "type")
2588 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2589 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2590 (match_test "TARGET_MOVX")))
2591 (const_string "imovx")
2592 (const_string "imov")))
2593 (set (attr "mode")
2594 (if_then_else (eq_attr "type" "imovx")
2595 (const_string "SI")
2596 (const_string "QI")))])
2597
2598 (define_insn "*mov<mode>_extzv_1"
2599 [(set (match_operand:SWI48 0 "register_operand" "=R")
2600 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2601 (const_int 8)
2602 (const_int 8)))]
2603 ""
2604 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2605 [(set_attr "type" "imovx")
2606 (set_attr "mode" "SI")])
2607
2608 (define_insn "*movqi_extzv_2_rex64"
2609 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2610 (subreg:QI
2611 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2612 (const_int 8)
2613 (const_int 8)) 0))]
2614 "TARGET_64BIT"
2615 {
2616 switch (get_attr_type (insn))
2617 {
2618 case TYPE_IMOVX:
2619 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2620 default:
2621 return "mov{b}\t{%h1, %0|%0, %h1}";
2622 }
2623 }
2624 [(set (attr "type")
2625 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2626 (match_test "TARGET_MOVX"))
2627 (const_string "imovx")
2628 (const_string "imov")))
2629 (set (attr "mode")
2630 (if_then_else (eq_attr "type" "imovx")
2631 (const_string "SI")
2632 (const_string "QI")))])
2633
2634 (define_insn "*movqi_extzv_2"
2635 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2636 (subreg:QI
2637 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2638 (const_int 8)
2639 (const_int 8)) 0))]
2640 "!TARGET_64BIT"
2641 {
2642 switch (get_attr_type (insn))
2643 {
2644 case TYPE_IMOVX:
2645 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2646 default:
2647 return "mov{b}\t{%h1, %0|%0, %h1}";
2648 }
2649 }
2650 [(set (attr "type")
2651 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2652 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2653 (match_test "TARGET_MOVX")))
2654 (const_string "imovx")
2655 (const_string "imov")))
2656 (set (attr "mode")
2657 (if_then_else (eq_attr "type" "imovx")
2658 (const_string "SI")
2659 (const_string "QI")))])
2660
2661 (define_expand "mov<mode>_insv_1"
2662 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2663 (const_int 8)
2664 (const_int 8))
2665 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2666
2667 (define_insn "*mov<mode>_insv_1_rex64"
2668 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2669 (const_int 8)
2670 (const_int 8))
2671 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2672 "TARGET_64BIT"
2673 "mov{b}\t{%b1, %h0|%h0, %b1}"
2674 [(set_attr "type" "imov")
2675 (set_attr "mode" "QI")])
2676
2677 (define_insn "*movsi_insv_1"
2678 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2679 (const_int 8)
2680 (const_int 8))
2681 (match_operand:SI 1 "general_operand" "Qmn"))]
2682 "!TARGET_64BIT"
2683 "mov{b}\t{%b1, %h0|%h0, %b1}"
2684 [(set_attr "type" "imov")
2685 (set_attr "mode" "QI")])
2686
2687 (define_insn "*movqi_insv_2"
2688 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2689 (const_int 8)
2690 (const_int 8))
2691 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2692 (const_int 8)))]
2693 ""
2694 "mov{b}\t{%h1, %h0|%h0, %h1}"
2695 [(set_attr "type" "imov")
2696 (set_attr "mode" "QI")])
2697 \f
2698 ;; Floating point push instructions.
2699
2700 (define_insn "*pushtf"
2701 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2702 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2703 "TARGET_SSE2"
2704 {
2705 /* This insn should be already split before reg-stack. */
2706 gcc_unreachable ();
2707 }
2708 [(set_attr "type" "multi")
2709 (set_attr "unit" "sse,*,*")
2710 (set_attr "mode" "TF,SI,SI")])
2711
2712 ;; %%% Kill this when call knows how to work this out.
2713 (define_split
2714 [(set (match_operand:TF 0 "push_operand" "")
2715 (match_operand:TF 1 "sse_reg_operand" ""))]
2716 "TARGET_SSE2 && reload_completed"
2717 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2718 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2719
2720 (define_insn "*pushxf"
2721 [(set (match_operand:XF 0 "push_operand" "=<,<")
2722 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2723 "optimize_function_for_speed_p (cfun)"
2724 {
2725 /* This insn should be already split before reg-stack. */
2726 gcc_unreachable ();
2727 }
2728 [(set_attr "type" "multi")
2729 (set_attr "unit" "i387,*")
2730 (set_attr "mode" "XF,SI")])
2731
2732 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2733 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2734 ;; Pushing using integer instructions is longer except for constants
2735 ;; and direct memory references (assuming that any given constant is pushed
2736 ;; only once, but this ought to be handled elsewhere).
2737
2738 (define_insn "*pushxf_nointeger"
2739 [(set (match_operand:XF 0 "push_operand" "=<,<")
2740 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2741 "optimize_function_for_size_p (cfun)"
2742 {
2743 /* This insn should be already split before reg-stack. */
2744 gcc_unreachable ();
2745 }
2746 [(set_attr "type" "multi")
2747 (set_attr "unit" "i387,*")
2748 (set_attr "mode" "XF,SI")])
2749
2750 ;; %%% Kill this when call knows how to work this out.
2751 (define_split
2752 [(set (match_operand:XF 0 "push_operand" "")
2753 (match_operand:XF 1 "fp_register_operand" ""))]
2754 "reload_completed"
2755 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2756 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2757 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2758
2759 (define_insn "*pushdf_rex64"
2760 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2761 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2762 "TARGET_64BIT"
2763 {
2764 /* This insn should be already split before reg-stack. */
2765 gcc_unreachable ();
2766 }
2767 [(set_attr "type" "multi")
2768 (set_attr "unit" "i387,*,*")
2769 (set_attr "mode" "DF,DI,DF")])
2770
2771 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2772 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2773 ;; On the average, pushdf using integers can be still shorter.
2774
2775 (define_insn "*pushdf"
2776 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2777 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2778 "!TARGET_64BIT"
2779 {
2780 /* This insn should be already split before reg-stack. */
2781 gcc_unreachable ();
2782 }
2783 [(set_attr "isa" "*,*,sse2")
2784 (set_attr "type" "multi")
2785 (set_attr "unit" "i387,*,*")
2786 (set_attr "mode" "DF,DI,DF")])
2787
2788 ;; %%% Kill this when call knows how to work this out.
2789 (define_split
2790 [(set (match_operand:DF 0 "push_operand" "")
2791 (match_operand:DF 1 "any_fp_register_operand" ""))]
2792 "reload_completed"
2793 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2794 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2795
2796 (define_insn "*pushsf_rex64"
2797 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2798 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2799 "TARGET_64BIT"
2800 {
2801 /* Anything else should be already split before reg-stack. */
2802 gcc_assert (which_alternative == 1);
2803 return "push{q}\t%q1";
2804 }
2805 [(set_attr "type" "multi,push,multi")
2806 (set_attr "unit" "i387,*,*")
2807 (set_attr "mode" "SF,DI,SF")])
2808
2809 (define_insn "*pushsf"
2810 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2811 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2812 "!TARGET_64BIT"
2813 {
2814 /* Anything else should be already split before reg-stack. */
2815 gcc_assert (which_alternative == 1);
2816 return "push{l}\t%1";
2817 }
2818 [(set_attr "type" "multi,push,multi")
2819 (set_attr "unit" "i387,*,*")
2820 (set_attr "mode" "SF,SI,SF")])
2821
2822 ;; %%% Kill this when call knows how to work this out.
2823 (define_split
2824 [(set (match_operand:SF 0 "push_operand" "")
2825 (match_operand:SF 1 "any_fp_register_operand" ""))]
2826 "reload_completed"
2827 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2828 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2829 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2830
2831 (define_split
2832 [(set (match_operand:SF 0 "push_operand" "")
2833 (match_operand:SF 1 "memory_operand" ""))]
2834 "reload_completed
2835 && (operands[2] = find_constant_src (insn))"
2836 [(set (match_dup 0) (match_dup 2))])
2837
2838 (define_split
2839 [(set (match_operand 0 "push_operand" "")
2840 (match_operand 1 "general_operand" ""))]
2841 "reload_completed
2842 && (GET_MODE (operands[0]) == TFmode
2843 || GET_MODE (operands[0]) == XFmode
2844 || GET_MODE (operands[0]) == DFmode)
2845 && !ANY_FP_REG_P (operands[1])"
2846 [(const_int 0)]
2847 "ix86_split_long_move (operands); DONE;")
2848 \f
2849 ;; Floating point move instructions.
2850
2851 (define_expand "movtf"
2852 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2853 (match_operand:TF 1 "nonimmediate_operand" ""))]
2854 "TARGET_SSE2"
2855 {
2856 ix86_expand_move (TFmode, operands);
2857 DONE;
2858 })
2859
2860 (define_expand "mov<mode>"
2861 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2862 (match_operand:X87MODEF 1 "general_operand" ""))]
2863 ""
2864 "ix86_expand_move (<MODE>mode, operands); DONE;")
2865
2866 (define_insn "*movtf_internal"
2867 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2868 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2869 "TARGET_SSE2
2870 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871 && (!can_create_pseudo_p ()
2872 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2873 || GET_CODE (operands[1]) != CONST_DOUBLE
2874 || (optimize_function_for_size_p (cfun)
2875 && standard_sse_constant_p (operands[1])
2876 && !memory_operand (operands[0], TFmode))
2877 || (!TARGET_MEMORY_MISMATCH_STALL
2878 && memory_operand (operands[0], TFmode)))"
2879 {
2880 switch (which_alternative)
2881 {
2882 case 0:
2883 case 1:
2884 /* Handle misaligned load/store since we
2885 don't have movmisaligntf pattern. */
2886 if (misaligned_operand (operands[0], TFmode)
2887 || misaligned_operand (operands[1], TFmode))
2888 {
2889 if (get_attr_mode (insn) == MODE_V4SF)
2890 return "%vmovups\t{%1, %0|%0, %1}";
2891 else
2892 return "%vmovdqu\t{%1, %0|%0, %1}";
2893 }
2894 else
2895 {
2896 if (get_attr_mode (insn) == MODE_V4SF)
2897 return "%vmovaps\t{%1, %0|%0, %1}";
2898 else
2899 return "%vmovdqa\t{%1, %0|%0, %1}";
2900 }
2901
2902 case 2:
2903 return standard_sse_constant_opcode (insn, operands[1]);
2904
2905 case 3:
2906 case 4:
2907 return "#";
2908
2909 default:
2910 gcc_unreachable ();
2911 }
2912 }
2913 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2914 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2915 (set (attr "mode")
2916 (cond [(eq_attr "alternative" "0,2")
2917 (if_then_else
2918 (match_test "optimize_function_for_size_p (cfun)")
2919 (const_string "V4SF")
2920 (const_string "TI"))
2921 (eq_attr "alternative" "1")
2922 (if_then_else
2923 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2924 (match_test "optimize_function_for_size_p (cfun)"))
2925 (const_string "V4SF")
2926 (const_string "TI"))]
2927 (const_string "DI")))])
2928
2929 ;; Possible store forwarding (partial memory) stall in alternative 4.
2930 (define_insn "*movxf_internal"
2931 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2932 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2933 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2934 && (!can_create_pseudo_p ()
2935 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2936 || GET_CODE (operands[1]) != CONST_DOUBLE
2937 || (optimize_function_for_size_p (cfun)
2938 && standard_80387_constant_p (operands[1]) > 0
2939 && !memory_operand (operands[0], XFmode))
2940 || (!TARGET_MEMORY_MISMATCH_STALL
2941 && memory_operand (operands[0], XFmode)))"
2942 {
2943 switch (which_alternative)
2944 {
2945 case 0:
2946 case 1:
2947 return output_387_reg_move (insn, operands);
2948
2949 case 2:
2950 return standard_80387_constant_opcode (operands[1]);
2951
2952 case 3:
2953 case 4:
2954 return "#";
2955
2956 default:
2957 gcc_unreachable ();
2958 }
2959 }
2960 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2961 (set_attr "mode" "XF,XF,XF,SI,SI")])
2962
2963 (define_insn "*movdf_internal_rex64"
2964 [(set (match_operand:DF 0 "nonimmediate_operand"
2965 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2966 (match_operand:DF 1 "general_operand"
2967 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2968 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2969 && (!can_create_pseudo_p ()
2970 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2971 || GET_CODE (operands[1]) != CONST_DOUBLE
2972 || (optimize_function_for_size_p (cfun)
2973 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2974 && standard_80387_constant_p (operands[1]) > 0)
2975 || (TARGET_SSE2 && TARGET_SSE_MATH
2976 && standard_sse_constant_p (operands[1]))))
2977 || memory_operand (operands[0], DFmode))"
2978 {
2979 switch (which_alternative)
2980 {
2981 case 0:
2982 case 1:
2983 return output_387_reg_move (insn, operands);
2984
2985 case 2:
2986 return standard_80387_constant_opcode (operands[1]);
2987
2988 case 3:
2989 case 4:
2990 return "mov{q}\t{%1, %0|%0, %1}";
2991
2992 case 5:
2993 return "movabs{q}\t{%1, %0|%0, %1}";
2994
2995 case 6:
2996 return "#";
2997
2998 case 7:
2999 return standard_sse_constant_opcode (insn, operands[1]);
3000
3001 case 8:
3002 case 9:
3003 case 10:
3004 switch (get_attr_mode (insn))
3005 {
3006 case MODE_V2DF:
3007 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3008 return "%vmovapd\t{%1, %0|%0, %1}";
3009 case MODE_V4SF:
3010 return "%vmovaps\t{%1, %0|%0, %1}";
3011
3012 case MODE_DI:
3013 return "%vmovq\t{%1, %0|%0, %1}";
3014 case MODE_DF:
3015 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3016 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3017 return "%vmovsd\t{%1, %0|%0, %1}";
3018 case MODE_V1DF:
3019 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3020 case MODE_V2SF:
3021 return "%vmovlps\t{%1, %d0|%d0, %1}";
3022 default:
3023 gcc_unreachable ();
3024 }
3025
3026 case 11:
3027 case 12:
3028 /* Handle broken assemblers that require movd instead of movq. */
3029 return "%vmovd\t{%1, %0|%0, %1}";
3030
3031 default:
3032 gcc_unreachable();
3033 }
3034 }
3035 [(set (attr "type")
3036 (cond [(eq_attr "alternative" "0,1,2")
3037 (const_string "fmov")
3038 (eq_attr "alternative" "3,4,5")
3039 (const_string "imov")
3040 (eq_attr "alternative" "6")
3041 (const_string "multi")
3042 (eq_attr "alternative" "7")
3043 (const_string "sselog1")
3044 ]
3045 (const_string "ssemov")))
3046 (set (attr "modrm")
3047 (if_then_else
3048 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3049 (const_string "0")
3050 (const_string "*")))
3051 (set (attr "length_immediate")
3052 (if_then_else
3053 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3054 (const_string "8")
3055 (const_string "*")))
3056 (set (attr "prefix")
3057 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3058 (const_string "orig")
3059 (const_string "maybe_vex")))
3060 (set (attr "prefix_data16")
3061 (if_then_else (eq_attr "mode" "V1DF")
3062 (const_string "1")
3063 (const_string "*")))
3064 (set (attr "mode")
3065 (cond [(eq_attr "alternative" "0,1,2")
3066 (const_string "DF")
3067 (eq_attr "alternative" "3,4,5,6,11,12")
3068 (const_string "DI")
3069
3070 /* xorps is one byte shorter. */
3071 (eq_attr "alternative" "7")
3072 (cond [(match_test "optimize_function_for_size_p (cfun)")
3073 (const_string "V4SF")
3074 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3075 (const_string "TI")
3076 ]
3077 (const_string "V2DF"))
3078
3079 /* For architectures resolving dependencies on
3080 whole SSE registers use APD move to break dependency
3081 chains, otherwise use short move to avoid extra work.
3082
3083 movaps encodes one byte shorter. */
3084 (eq_attr "alternative" "8")
3085 (cond
3086 [(match_test "optimize_function_for_size_p (cfun)")
3087 (const_string "V4SF")
3088 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3089 (const_string "V2DF")
3090 ]
3091 (const_string "DF"))
3092 /* For architectures resolving dependencies on register
3093 parts we may avoid extra work to zero out upper part
3094 of register. */
3095 (eq_attr "alternative" "9")
3096 (if_then_else
3097 (match_test "TARGET_SSE_SPLIT_REGS")
3098 (const_string "V1DF")
3099 (const_string "DF"))
3100 ]
3101 (const_string "DF")))])
3102
3103 ;; Possible store forwarding (partial memory) stall in alternative 4.
3104 (define_insn "*movdf_internal"
3105 [(set (match_operand:DF 0 "nonimmediate_operand"
3106 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3107 (match_operand:DF 1 "general_operand"
3108 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3109 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3110 && (!can_create_pseudo_p ()
3111 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3112 || GET_CODE (operands[1]) != CONST_DOUBLE
3113 || (optimize_function_for_size_p (cfun)
3114 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3115 && standard_80387_constant_p (operands[1]) > 0)
3116 || (TARGET_SSE2 && TARGET_SSE_MATH
3117 && standard_sse_constant_p (operands[1])))
3118 && !memory_operand (operands[0], DFmode))
3119 || (!TARGET_MEMORY_MISMATCH_STALL
3120 && memory_operand (operands[0], DFmode)))"
3121 {
3122 switch (which_alternative)
3123 {
3124 case 0:
3125 case 1:
3126 return output_387_reg_move (insn, operands);
3127
3128 case 2:
3129 return standard_80387_constant_opcode (operands[1]);
3130
3131 case 3:
3132 case 4:
3133 return "#";
3134
3135 case 5:
3136 case 9:
3137 return standard_sse_constant_opcode (insn, operands[1]);
3138
3139 case 6:
3140 case 7:
3141 case 8:
3142 case 10:
3143 case 11:
3144 case 12:
3145 switch (get_attr_mode (insn))
3146 {
3147 case MODE_V2DF:
3148 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3149 return "%vmovapd\t{%1, %0|%0, %1}";
3150 case MODE_V4SF:
3151 return "%vmovaps\t{%1, %0|%0, %1}";
3152
3153 case MODE_DI:
3154 return "%vmovq\t{%1, %0|%0, %1}";
3155 case MODE_DF:
3156 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3157 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3158 return "%vmovsd\t{%1, %0|%0, %1}";
3159 case MODE_V1DF:
3160 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3161 case MODE_V2SF:
3162 return "%vmovlps\t{%1, %d0|%d0, %1}";
3163 default:
3164 gcc_unreachable ();
3165 }
3166
3167 default:
3168 gcc_unreachable ();
3169 }
3170 }
3171 [(set (attr "isa")
3172 (if_then_else (eq_attr "alternative" "5,6,7,8")
3173 (const_string "sse2")
3174 (const_string "*")))
3175 (set (attr "type")
3176 (cond [(eq_attr "alternative" "0,1,2")
3177 (const_string "fmov")
3178 (eq_attr "alternative" "3,4")
3179 (const_string "multi")
3180 (eq_attr "alternative" "5,9")
3181 (const_string "sselog1")
3182 ]
3183 (const_string "ssemov")))
3184 (set (attr "prefix")
3185 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3186 (const_string "orig")
3187 (const_string "maybe_vex")))
3188 (set (attr "prefix_data16")
3189 (if_then_else (eq_attr "mode" "V1DF")
3190 (const_string "1")
3191 (const_string "*")))
3192 (set (attr "mode")
3193 (cond [(eq_attr "alternative" "0,1,2")
3194 (const_string "DF")
3195 (eq_attr "alternative" "3,4")
3196 (const_string "SI")
3197
3198 /* For SSE1, we have many fewer alternatives. */
3199 (not (match_test "TARGET_SSE2"))
3200 (if_then_else
3201 (eq_attr "alternative" "5,6,9,10")
3202 (const_string "V4SF")
3203 (const_string "V2SF"))
3204
3205 /* xorps is one byte shorter. */
3206 (eq_attr "alternative" "5,9")
3207 (cond [(match_test "optimize_function_for_size_p (cfun)")
3208 (const_string "V4SF")
3209 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3210 (const_string "TI")
3211 ]
3212 (const_string "V2DF"))
3213
3214 /* For architectures resolving dependencies on
3215 whole SSE registers use APD move to break dependency
3216 chains, otherwise use short move to avoid extra work.
3217
3218 movaps encodes one byte shorter. */
3219 (eq_attr "alternative" "6,10")
3220 (cond
3221 [(match_test "optimize_function_for_size_p (cfun)")
3222 (const_string "V4SF")
3223 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3224 (const_string "V2DF")
3225 ]
3226 (const_string "DF"))
3227 /* For architectures resolving dependencies on register
3228 parts we may avoid extra work to zero out upper part
3229 of register. */
3230 (eq_attr "alternative" "7,11")
3231 (if_then_else
3232 (match_test "TARGET_SSE_SPLIT_REGS")
3233 (const_string "V1DF")
3234 (const_string "DF"))
3235 ]
3236 (const_string "DF")))])
3237
3238 (define_insn "*movsf_internal"
3239 [(set (match_operand:SF 0 "nonimmediate_operand"
3240 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3241 (match_operand:SF 1 "general_operand"
3242 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3243 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3244 && (!can_create_pseudo_p ()
3245 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3246 || GET_CODE (operands[1]) != CONST_DOUBLE
3247 || (optimize_function_for_size_p (cfun)
3248 && ((!TARGET_SSE_MATH
3249 && standard_80387_constant_p (operands[1]) > 0)
3250 || (TARGET_SSE_MATH
3251 && standard_sse_constant_p (operands[1]))))
3252 || memory_operand (operands[0], SFmode))"
3253 {
3254 switch (which_alternative)
3255 {
3256 case 0:
3257 case 1:
3258 return output_387_reg_move (insn, operands);
3259
3260 case 2:
3261 return standard_80387_constant_opcode (operands[1]);
3262
3263 case 3:
3264 case 4:
3265 return "mov{l}\t{%1, %0|%0, %1}";
3266
3267 case 5:
3268 return standard_sse_constant_opcode (insn, operands[1]);
3269
3270 case 6:
3271 if (get_attr_mode (insn) == MODE_V4SF)
3272 return "%vmovaps\t{%1, %0|%0, %1}";
3273 if (TARGET_AVX)
3274 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3275
3276 case 7:
3277 case 8:
3278 return "%vmovss\t{%1, %0|%0, %1}";
3279
3280 case 9:
3281 case 10:
3282 case 14:
3283 case 15:
3284 return "movd\t{%1, %0|%0, %1}";
3285
3286 case 11:
3287 return "movq\t{%1, %0|%0, %1}";
3288
3289 case 12:
3290 case 13:
3291 return "%vmovd\t{%1, %0|%0, %1}";
3292
3293 default:
3294 gcc_unreachable ();
3295 }
3296 }
3297 [(set (attr "type")
3298 (cond [(eq_attr "alternative" "0,1,2")
3299 (const_string "fmov")
3300 (eq_attr "alternative" "3,4")
3301 (const_string "multi")
3302 (eq_attr "alternative" "5")
3303 (const_string "sselog1")
3304 (eq_attr "alternative" "9,10,11,14,15")
3305 (const_string "mmxmov")
3306 ]
3307 (const_string "ssemov")))
3308 (set (attr "prefix")
3309 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3310 (const_string "maybe_vex")
3311 (const_string "orig")))
3312 (set (attr "mode")
3313 (cond [(eq_attr "alternative" "3,4,9,10")
3314 (const_string "SI")
3315 (eq_attr "alternative" "5")
3316 (if_then_else
3317 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3318 (match_test "TARGET_SSE2"))
3319 (not (match_test "optimize_function_for_size_p (cfun)")))
3320 (const_string "TI")
3321 (const_string "V4SF"))
3322 /* For architectures resolving dependencies on
3323 whole SSE registers use APS move to break dependency
3324 chains, otherwise use short move to avoid extra work.
3325
3326 Do the same for architectures resolving dependencies on
3327 the parts. While in DF mode it is better to always handle
3328 just register parts, the SF mode is different due to lack
3329 of instructions to load just part of the register. It is
3330 better to maintain the whole registers in single format
3331 to avoid problems on using packed logical operations. */
3332 (eq_attr "alternative" "6")
3333 (if_then_else
3334 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3335 (match_test "TARGET_SSE_SPLIT_REGS"))
3336 (const_string "V4SF")
3337 (const_string "SF"))
3338 (eq_attr "alternative" "11")
3339 (const_string "DI")]
3340 (const_string "SF")))])
3341
3342 (define_split
3343 [(set (match_operand 0 "any_fp_register_operand" "")
3344 (match_operand 1 "memory_operand" ""))]
3345 "reload_completed
3346 && (GET_MODE (operands[0]) == TFmode
3347 || GET_MODE (operands[0]) == XFmode
3348 || GET_MODE (operands[0]) == DFmode
3349 || GET_MODE (operands[0]) == SFmode)
3350 && (operands[2] = find_constant_src (insn))"
3351 [(set (match_dup 0) (match_dup 2))]
3352 {
3353 rtx c = operands[2];
3354 int r = REGNO (operands[0]);
3355
3356 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3357 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3358 FAIL;
3359 })
3360
3361 (define_split
3362 [(set (match_operand 0 "any_fp_register_operand" "")
3363 (float_extend (match_operand 1 "memory_operand" "")))]
3364 "reload_completed
3365 && (GET_MODE (operands[0]) == TFmode
3366 || GET_MODE (operands[0]) == XFmode
3367 || GET_MODE (operands[0]) == DFmode)
3368 && (operands[2] = find_constant_src (insn))"
3369 [(set (match_dup 0) (match_dup 2))]
3370 {
3371 rtx c = operands[2];
3372 int r = REGNO (operands[0]);
3373
3374 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3375 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3376 FAIL;
3377 })
3378
3379 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3380 (define_split
3381 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3382 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3383 "reload_completed
3384 && (standard_80387_constant_p (operands[1]) == 8
3385 || standard_80387_constant_p (operands[1]) == 9)"
3386 [(set (match_dup 0)(match_dup 1))
3387 (set (match_dup 0)
3388 (neg:X87MODEF (match_dup 0)))]
3389 {
3390 REAL_VALUE_TYPE r;
3391
3392 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3393 if (real_isnegzero (&r))
3394 operands[1] = CONST0_RTX (<MODE>mode);
3395 else
3396 operands[1] = CONST1_RTX (<MODE>mode);
3397 })
3398
3399 (define_split
3400 [(set (match_operand 0 "nonimmediate_operand" "")
3401 (match_operand 1 "general_operand" ""))]
3402 "reload_completed
3403 && (GET_MODE (operands[0]) == TFmode
3404 || GET_MODE (operands[0]) == XFmode
3405 || GET_MODE (operands[0]) == DFmode)
3406 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3407 [(const_int 0)]
3408 "ix86_split_long_move (operands); DONE;")
3409
3410 (define_insn "swapxf"
3411 [(set (match_operand:XF 0 "register_operand" "+f")
3412 (match_operand:XF 1 "register_operand" "+f"))
3413 (set (match_dup 1)
3414 (match_dup 0))]
3415 "TARGET_80387"
3416 {
3417 if (STACK_TOP_P (operands[0]))
3418 return "fxch\t%1";
3419 else
3420 return "fxch\t%0";
3421 }
3422 [(set_attr "type" "fxch")
3423 (set_attr "mode" "XF")])
3424
3425 (define_insn "*swap<mode>"
3426 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3427 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3428 (set (match_dup 1)
3429 (match_dup 0))]
3430 "TARGET_80387 || reload_completed"
3431 {
3432 if (STACK_TOP_P (operands[0]))
3433 return "fxch\t%1";
3434 else
3435 return "fxch\t%0";
3436 }
3437 [(set_attr "type" "fxch")
3438 (set_attr "mode" "<MODE>")])
3439 \f
3440 ;; Zero extension instructions
3441
3442 (define_expand "zero_extendsidi2"
3443 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3444 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3445 ""
3446 {
3447 if (!TARGET_64BIT)
3448 {
3449 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3450 DONE;
3451 }
3452 })
3453
3454 (define_insn "*zero_extendsidi2_rex64"
3455 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3456 (zero_extend:DI
3457 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3458 "TARGET_64BIT"
3459 "@
3460 mov\t{%k1, %k0|%k0, %k1}
3461 #
3462 movd\t{%1, %0|%0, %1}
3463 movd\t{%1, %0|%0, %1}
3464 %vmovd\t{%1, %0|%0, %1}
3465 %vmovd\t{%1, %0|%0, %1}"
3466 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3467 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3468 (set_attr "prefix_0f" "0,*,*,*,*,*")
3469 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3470
3471 (define_split
3472 [(set (match_operand:DI 0 "memory_operand" "")
3473 (zero_extend:DI (match_dup 0)))]
3474 "TARGET_64BIT"
3475 [(set (match_dup 4) (const_int 0))]
3476 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3477
3478 ;; %%% Kill me once multi-word ops are sane.
3479 (define_insn "zero_extendsidi2_1"
3480 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3481 (zero_extend:DI
3482 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3483 (clobber (reg:CC FLAGS_REG))]
3484 "!TARGET_64BIT"
3485 "@
3486 #
3487 #
3488 #
3489 movd\t{%1, %0|%0, %1}
3490 movd\t{%1, %0|%0, %1}
3491 %vmovd\t{%1, %0|%0, %1}
3492 %vmovd\t{%1, %0|%0, %1}"
3493 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3494 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3495 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3496 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3497
3498 (define_split
3499 [(set (match_operand:DI 0 "register_operand" "")
3500 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3501 (clobber (reg:CC FLAGS_REG))]
3502 "!TARGET_64BIT && reload_completed
3503 && true_regnum (operands[0]) == true_regnum (operands[1])"
3504 [(set (match_dup 4) (const_int 0))]
3505 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3506
3507 (define_split
3508 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3509 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3510 (clobber (reg:CC FLAGS_REG))]
3511 "!TARGET_64BIT && reload_completed
3512 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3513 [(set (match_dup 3) (match_dup 1))
3514 (set (match_dup 4) (const_int 0))]
3515 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3516
3517 (define_insn "zero_extend<mode>di2"
3518 [(set (match_operand:DI 0 "register_operand" "=r")
3519 (zero_extend:DI
3520 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3521 "TARGET_64BIT"
3522 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3523 [(set_attr "type" "imovx")
3524 (set_attr "mode" "SI")])
3525
3526 (define_expand "zero_extendhisi2"
3527 [(set (match_operand:SI 0 "register_operand" "")
3528 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3529 ""
3530 {
3531 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3532 {
3533 operands[1] = force_reg (HImode, operands[1]);
3534 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3535 DONE;
3536 }
3537 })
3538
3539 (define_insn_and_split "zero_extendhisi2_and"
3540 [(set (match_operand:SI 0 "register_operand" "=r")
3541 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3542 (clobber (reg:CC FLAGS_REG))]
3543 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3544 "#"
3545 "&& reload_completed"
3546 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3547 (clobber (reg:CC FLAGS_REG))])]
3548 ""
3549 [(set_attr "type" "alu1")
3550 (set_attr "mode" "SI")])
3551
3552 (define_insn "*zero_extendhisi2_movzwl"
3553 [(set (match_operand:SI 0 "register_operand" "=r")
3554 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3555 "!TARGET_ZERO_EXTEND_WITH_AND
3556 || optimize_function_for_size_p (cfun)"
3557 "movz{wl|x}\t{%1, %0|%0, %1}"
3558 [(set_attr "type" "imovx")
3559 (set_attr "mode" "SI")])
3560
3561 (define_expand "zero_extendqi<mode>2"
3562 [(parallel
3563 [(set (match_operand:SWI24 0 "register_operand" "")
3564 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3565 (clobber (reg:CC FLAGS_REG))])])
3566
3567 (define_insn "*zero_extendqi<mode>2_and"
3568 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3569 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3570 (clobber (reg:CC FLAGS_REG))]
3571 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3572 "#"
3573 [(set_attr "type" "alu1")
3574 (set_attr "mode" "<MODE>")])
3575
3576 ;; When source and destination does not overlap, clear destination
3577 ;; first and then do the movb
3578 (define_split
3579 [(set (match_operand:SWI24 0 "register_operand" "")
3580 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3581 (clobber (reg:CC FLAGS_REG))]
3582 "reload_completed
3583 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3584 && ANY_QI_REG_P (operands[0])
3585 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3586 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3587 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3588 {
3589 operands[2] = gen_lowpart (QImode, operands[0]);
3590 ix86_expand_clear (operands[0]);
3591 })
3592
3593 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3594 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3595 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3596 (clobber (reg:CC FLAGS_REG))]
3597 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3598 "#"
3599 [(set_attr "type" "imovx,alu1")
3600 (set_attr "mode" "<MODE>")])
3601
3602 ;; For the movzbl case strip only the clobber
3603 (define_split
3604 [(set (match_operand:SWI24 0 "register_operand" "")
3605 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3606 (clobber (reg:CC FLAGS_REG))]
3607 "reload_completed
3608 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3609 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3610 [(set (match_dup 0)
3611 (zero_extend:SWI24 (match_dup 1)))])
3612
3613 ; zero extend to SImode to avoid partial register stalls
3614 (define_insn "*zero_extendqi<mode>2_movzbl"
3615 [(set (match_operand:SWI24 0 "register_operand" "=r")
3616 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3617 "reload_completed
3618 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3619 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3620 [(set_attr "type" "imovx")
3621 (set_attr "mode" "SI")])
3622
3623 ;; Rest is handled by single and.
3624 (define_split
3625 [(set (match_operand:SWI24 0 "register_operand" "")
3626 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3627 (clobber (reg:CC FLAGS_REG))]
3628 "reload_completed
3629 && true_regnum (operands[0]) == true_regnum (operands[1])"
3630 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3631 (clobber (reg:CC FLAGS_REG))])])
3632 \f
3633 ;; Sign extension instructions
3634
3635 (define_expand "extendsidi2"
3636 [(set (match_operand:DI 0 "register_operand" "")
3637 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3638 ""
3639 {
3640 if (!TARGET_64BIT)
3641 {
3642 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3643 DONE;
3644 }
3645 })
3646
3647 (define_insn "*extendsidi2_rex64"
3648 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3649 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3650 "TARGET_64BIT"
3651 "@
3652 {cltq|cdqe}
3653 movs{lq|x}\t{%1, %0|%0, %1}"
3654 [(set_attr "type" "imovx")
3655 (set_attr "mode" "DI")
3656 (set_attr "prefix_0f" "0")
3657 (set_attr "modrm" "0,1")])
3658
3659 (define_insn "extendsidi2_1"
3660 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3661 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3662 (clobber (reg:CC FLAGS_REG))
3663 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3664 "!TARGET_64BIT"
3665 "#")
3666
3667 ;; Extend to memory case when source register does die.
3668 (define_split
3669 [(set (match_operand:DI 0 "memory_operand" "")
3670 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3671 (clobber (reg:CC FLAGS_REG))
3672 (clobber (match_operand:SI 2 "register_operand" ""))]
3673 "(reload_completed
3674 && dead_or_set_p (insn, operands[1])
3675 && !reg_mentioned_p (operands[1], operands[0]))"
3676 [(set (match_dup 3) (match_dup 1))
3677 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3678 (clobber (reg:CC FLAGS_REG))])
3679 (set (match_dup 4) (match_dup 1))]
3680 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3681
3682 ;; Extend to memory case when source register does not die.
3683 (define_split
3684 [(set (match_operand:DI 0 "memory_operand" "")
3685 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3686 (clobber (reg:CC FLAGS_REG))
3687 (clobber (match_operand:SI 2 "register_operand" ""))]
3688 "reload_completed"
3689 [(const_int 0)]
3690 {
3691 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3692
3693 emit_move_insn (operands[3], operands[1]);
3694
3695 /* Generate a cltd if possible and doing so it profitable. */
3696 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3697 && true_regnum (operands[1]) == AX_REG
3698 && true_regnum (operands[2]) == DX_REG)
3699 {
3700 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3701 }
3702 else
3703 {
3704 emit_move_insn (operands[2], operands[1]);
3705 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3706 }
3707 emit_move_insn (operands[4], operands[2]);
3708 DONE;
3709 })
3710
3711 ;; Extend to register case. Optimize case where source and destination
3712 ;; registers match and cases where we can use cltd.
3713 (define_split
3714 [(set (match_operand:DI 0 "register_operand" "")
3715 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3716 (clobber (reg:CC FLAGS_REG))
3717 (clobber (match_scratch:SI 2 ""))]
3718 "reload_completed"
3719 [(const_int 0)]
3720 {
3721 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3722
3723 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3724 emit_move_insn (operands[3], operands[1]);
3725
3726 /* Generate a cltd if possible and doing so it profitable. */
3727 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3728 && true_regnum (operands[3]) == AX_REG
3729 && true_regnum (operands[4]) == DX_REG)
3730 {
3731 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3732 DONE;
3733 }
3734
3735 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3736 emit_move_insn (operands[4], operands[1]);
3737
3738 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3739 DONE;
3740 })
3741
3742 (define_insn "extend<mode>di2"
3743 [(set (match_operand:DI 0 "register_operand" "=r")
3744 (sign_extend:DI
3745 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3746 "TARGET_64BIT"
3747 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3748 [(set_attr "type" "imovx")
3749 (set_attr "mode" "DI")])
3750
3751 (define_insn "extendhisi2"
3752 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3753 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3754 ""
3755 {
3756 switch (get_attr_prefix_0f (insn))
3757 {
3758 case 0:
3759 return "{cwtl|cwde}";
3760 default:
3761 return "movs{wl|x}\t{%1, %0|%0, %1}";
3762 }
3763 }
3764 [(set_attr "type" "imovx")
3765 (set_attr "mode" "SI")
3766 (set (attr "prefix_0f")
3767 ;; movsx is short decodable while cwtl is vector decoded.
3768 (if_then_else (and (eq_attr "cpu" "!k6")
3769 (eq_attr "alternative" "0"))
3770 (const_string "0")
3771 (const_string "1")))
3772 (set (attr "modrm")
3773 (if_then_else (eq_attr "prefix_0f" "0")
3774 (const_string "0")
3775 (const_string "1")))])
3776
3777 (define_insn "*extendhisi2_zext"
3778 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3779 (zero_extend:DI
3780 (sign_extend:SI
3781 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3782 "TARGET_64BIT"
3783 {
3784 switch (get_attr_prefix_0f (insn))
3785 {
3786 case 0:
3787 return "{cwtl|cwde}";
3788 default:
3789 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3790 }
3791 }
3792 [(set_attr "type" "imovx")
3793 (set_attr "mode" "SI")
3794 (set (attr "prefix_0f")
3795 ;; movsx is short decodable while cwtl is vector decoded.
3796 (if_then_else (and (eq_attr "cpu" "!k6")
3797 (eq_attr "alternative" "0"))
3798 (const_string "0")
3799 (const_string "1")))
3800 (set (attr "modrm")
3801 (if_then_else (eq_attr "prefix_0f" "0")
3802 (const_string "0")
3803 (const_string "1")))])
3804
3805 (define_insn "extendqisi2"
3806 [(set (match_operand:SI 0 "register_operand" "=r")
3807 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3808 ""
3809 "movs{bl|x}\t{%1, %0|%0, %1}"
3810 [(set_attr "type" "imovx")
3811 (set_attr "mode" "SI")])
3812
3813 (define_insn "*extendqisi2_zext"
3814 [(set (match_operand:DI 0 "register_operand" "=r")
3815 (zero_extend:DI
3816 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3817 "TARGET_64BIT"
3818 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3819 [(set_attr "type" "imovx")
3820 (set_attr "mode" "SI")])
3821
3822 (define_insn "extendqihi2"
3823 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3824 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3825 ""
3826 {
3827 switch (get_attr_prefix_0f (insn))
3828 {
3829 case 0:
3830 return "{cbtw|cbw}";
3831 default:
3832 return "movs{bw|x}\t{%1, %0|%0, %1}";
3833 }
3834 }
3835 [(set_attr "type" "imovx")
3836 (set_attr "mode" "HI")
3837 (set (attr "prefix_0f")
3838 ;; movsx is short decodable while cwtl is vector decoded.
3839 (if_then_else (and (eq_attr "cpu" "!k6")
3840 (eq_attr "alternative" "0"))
3841 (const_string "0")
3842 (const_string "1")))
3843 (set (attr "modrm")
3844 (if_then_else (eq_attr "prefix_0f" "0")
3845 (const_string "0")
3846 (const_string "1")))])
3847 \f
3848 ;; Conversions between float and double.
3849
3850 ;; These are all no-ops in the model used for the 80387.
3851 ;; So just emit moves.
3852
3853 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3854 (define_split
3855 [(set (match_operand:DF 0 "push_operand" "")
3856 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3857 "reload_completed"
3858 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3859 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3860
3861 (define_split
3862 [(set (match_operand:XF 0 "push_operand" "")
3863 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3864 "reload_completed"
3865 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3866 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3867 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3868
3869 (define_expand "extendsfdf2"
3870 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3871 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3872 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3873 {
3874 /* ??? Needed for compress_float_constant since all fp constants
3875 are TARGET_LEGITIMATE_CONSTANT_P. */
3876 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3877 {
3878 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3879 && standard_80387_constant_p (operands[1]) > 0)
3880 {
3881 operands[1] = simplify_const_unary_operation
3882 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3883 emit_move_insn_1 (operands[0], operands[1]);
3884 DONE;
3885 }
3886 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3887 }
3888 })
3889
3890 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3891 cvtss2sd:
3892 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3893 cvtps2pd xmm2,xmm1
3894 We do the conversion post reload to avoid producing of 128bit spills
3895 that might lead to ICE on 32bit target. The sequence unlikely combine
3896 anyway. */
3897 (define_split
3898 [(set (match_operand:DF 0 "register_operand" "")
3899 (float_extend:DF
3900 (match_operand:SF 1 "nonimmediate_operand" "")))]
3901 "TARGET_USE_VECTOR_FP_CONVERTS
3902 && optimize_insn_for_speed_p ()
3903 && reload_completed && SSE_REG_P (operands[0])"
3904 [(set (match_dup 2)
3905 (float_extend:V2DF
3906 (vec_select:V2SF
3907 (match_dup 3)
3908 (parallel [(const_int 0) (const_int 1)]))))]
3909 {
3910 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3911 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3912 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3913 Try to avoid move when unpacking can be done in source. */
3914 if (REG_P (operands[1]))
3915 {
3916 /* If it is unsafe to overwrite upper half of source, we need
3917 to move to destination and unpack there. */
3918 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3919 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3920 && true_regnum (operands[0]) != true_regnum (operands[1]))
3921 {
3922 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3923 emit_move_insn (tmp, operands[1]);
3924 }
3925 else
3926 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3927 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3928 operands[3]));
3929 }
3930 else
3931 emit_insn (gen_vec_setv4sf_0 (operands[3],
3932 CONST0_RTX (V4SFmode), operands[1]));
3933 })
3934
3935 (define_insn "*extendsfdf2_mixed"
3936 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3937 (float_extend:DF
3938 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3939 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3940 {
3941 switch (which_alternative)
3942 {
3943 case 0:
3944 case 1:
3945 return output_387_reg_move (insn, operands);
3946
3947 case 2:
3948 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3949
3950 default:
3951 gcc_unreachable ();
3952 }
3953 }
3954 [(set_attr "type" "fmov,fmov,ssecvt")
3955 (set_attr "prefix" "orig,orig,maybe_vex")
3956 (set_attr "mode" "SF,XF,DF")])
3957
3958 (define_insn "*extendsfdf2_sse"
3959 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3960 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3961 "TARGET_SSE2 && TARGET_SSE_MATH"
3962 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3963 [(set_attr "type" "ssecvt")
3964 (set_attr "prefix" "maybe_vex")
3965 (set_attr "mode" "DF")])
3966
3967 (define_insn "*extendsfdf2_i387"
3968 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3969 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3970 "TARGET_80387"
3971 "* return output_387_reg_move (insn, operands);"
3972 [(set_attr "type" "fmov")
3973 (set_attr "mode" "SF,XF")])
3974
3975 (define_expand "extend<mode>xf2"
3976 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3977 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3978 "TARGET_80387"
3979 {
3980 /* ??? Needed for compress_float_constant since all fp constants
3981 are TARGET_LEGITIMATE_CONSTANT_P. */
3982 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3983 {
3984 if (standard_80387_constant_p (operands[1]) > 0)
3985 {
3986 operands[1] = simplify_const_unary_operation
3987 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3988 emit_move_insn_1 (operands[0], operands[1]);
3989 DONE;
3990 }
3991 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3992 }
3993 })
3994
3995 (define_insn "*extend<mode>xf2_i387"
3996 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3997 (float_extend:XF
3998 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3999 "TARGET_80387"
4000 "* return output_387_reg_move (insn, operands);"
4001 [(set_attr "type" "fmov")
4002 (set_attr "mode" "<MODE>,XF")])
4003
4004 ;; %%% This seems bad bad news.
4005 ;; This cannot output into an f-reg because there is no way to be sure
4006 ;; of truncating in that case. Otherwise this is just like a simple move
4007 ;; insn. So we pretend we can output to a reg in order to get better
4008 ;; register preferencing, but we really use a stack slot.
4009
4010 ;; Conversion from DFmode to SFmode.
4011
4012 (define_expand "truncdfsf2"
4013 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4014 (float_truncate:SF
4015 (match_operand:DF 1 "nonimmediate_operand" "")))]
4016 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4017 {
4018 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4019 ;
4020 else if (flag_unsafe_math_optimizations)
4021 ;
4022 else
4023 {
4024 enum ix86_stack_slot slot = (virtuals_instantiated
4025 ? SLOT_TEMP
4026 : SLOT_VIRTUAL);
4027 rtx temp = assign_386_stack_local (SFmode, slot);
4028 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4029 DONE;
4030 }
4031 })
4032
4033 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4034 cvtsd2ss:
4035 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4036 cvtpd2ps xmm2,xmm1
4037 We do the conversion post reload to avoid producing of 128bit spills
4038 that might lead to ICE on 32bit target. The sequence unlikely combine
4039 anyway. */
4040 (define_split
4041 [(set (match_operand:SF 0 "register_operand" "")
4042 (float_truncate:SF
4043 (match_operand:DF 1 "nonimmediate_operand" "")))]
4044 "TARGET_USE_VECTOR_FP_CONVERTS
4045 && optimize_insn_for_speed_p ()
4046 && reload_completed && SSE_REG_P (operands[0])"
4047 [(set (match_dup 2)
4048 (vec_concat:V4SF
4049 (float_truncate:V2SF
4050 (match_dup 4))
4051 (match_dup 3)))]
4052 {
4053 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4054 operands[3] = CONST0_RTX (V2SFmode);
4055 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4056 /* Use movsd for loading from memory, unpcklpd for registers.
4057 Try to avoid move when unpacking can be done in source, or SSE3
4058 movddup is available. */
4059 if (REG_P (operands[1]))
4060 {
4061 if (!TARGET_SSE3
4062 && true_regnum (operands[0]) != true_regnum (operands[1])
4063 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4064 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4065 {
4066 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4067 emit_move_insn (tmp, operands[1]);
4068 operands[1] = tmp;
4069 }
4070 else if (!TARGET_SSE3)
4071 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4072 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4073 }
4074 else
4075 emit_insn (gen_sse2_loadlpd (operands[4],
4076 CONST0_RTX (V2DFmode), operands[1]));
4077 })
4078
4079 (define_expand "truncdfsf2_with_temp"
4080 [(parallel [(set (match_operand:SF 0 "" "")
4081 (float_truncate:SF (match_operand:DF 1 "" "")))
4082 (clobber (match_operand:SF 2 "" ""))])])
4083
4084 (define_insn "*truncdfsf_fast_mixed"
4085 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4086 (float_truncate:SF
4087 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4088 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4089 {
4090 switch (which_alternative)
4091 {
4092 case 0:
4093 return output_387_reg_move (insn, operands);
4094 case 1:
4095 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4096 default:
4097 gcc_unreachable ();
4098 }
4099 }
4100 [(set_attr "type" "fmov,ssecvt")
4101 (set_attr "prefix" "orig,maybe_vex")
4102 (set_attr "mode" "SF")])
4103
4104 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4105 ;; because nothing we do here is unsafe.
4106 (define_insn "*truncdfsf_fast_sse"
4107 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4108 (float_truncate:SF
4109 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4110 "TARGET_SSE2 && TARGET_SSE_MATH"
4111 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4112 [(set_attr "type" "ssecvt")
4113 (set_attr "prefix" "maybe_vex")
4114 (set_attr "mode" "SF")])
4115
4116 (define_insn "*truncdfsf_fast_i387"
4117 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4118 (float_truncate:SF
4119 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4120 "TARGET_80387 && flag_unsafe_math_optimizations"
4121 "* return output_387_reg_move (insn, operands);"
4122 [(set_attr "type" "fmov")
4123 (set_attr "mode" "SF")])
4124
4125 (define_insn "*truncdfsf_mixed"
4126 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4127 (float_truncate:SF
4128 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4129 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4130 "TARGET_MIX_SSE_I387"
4131 {
4132 switch (which_alternative)
4133 {
4134 case 0:
4135 return output_387_reg_move (insn, operands);
4136 case 1:
4137 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4138
4139 default:
4140 return "#";
4141 }
4142 }
4143 [(set_attr "isa" "*,sse2,*,*,*")
4144 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4145 (set_attr "unit" "*,*,i387,i387,i387")
4146 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4147 (set_attr "mode" "SF")])
4148
4149 (define_insn "*truncdfsf_i387"
4150 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4151 (float_truncate:SF
4152 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4153 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4154 "TARGET_80387"
4155 {
4156 switch (which_alternative)
4157 {
4158 case 0:
4159 return output_387_reg_move (insn, operands);
4160
4161 default:
4162 return "#";
4163 }
4164 }
4165 [(set_attr "type" "fmov,multi,multi,multi")
4166 (set_attr "unit" "*,i387,i387,i387")
4167 (set_attr "mode" "SF")])
4168
4169 (define_insn "*truncdfsf2_i387_1"
4170 [(set (match_operand:SF 0 "memory_operand" "=m")
4171 (float_truncate:SF
4172 (match_operand:DF 1 "register_operand" "f")))]
4173 "TARGET_80387
4174 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4175 && !TARGET_MIX_SSE_I387"
4176 "* return output_387_reg_move (insn, operands);"
4177 [(set_attr "type" "fmov")
4178 (set_attr "mode" "SF")])
4179
4180 (define_split
4181 [(set (match_operand:SF 0 "register_operand" "")
4182 (float_truncate:SF
4183 (match_operand:DF 1 "fp_register_operand" "")))
4184 (clobber (match_operand 2 "" ""))]
4185 "reload_completed"
4186 [(set (match_dup 2) (match_dup 1))
4187 (set (match_dup 0) (match_dup 2))]
4188 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4189
4190 ;; Conversion from XFmode to {SF,DF}mode
4191
4192 (define_expand "truncxf<mode>2"
4193 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4194 (float_truncate:MODEF
4195 (match_operand:XF 1 "register_operand" "")))
4196 (clobber (match_dup 2))])]
4197 "TARGET_80387"
4198 {
4199 if (flag_unsafe_math_optimizations)
4200 {
4201 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4202 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4203 if (reg != operands[0])
4204 emit_move_insn (operands[0], reg);
4205 DONE;
4206 }
4207 else
4208 {
4209 enum ix86_stack_slot slot = (virtuals_instantiated
4210 ? SLOT_TEMP
4211 : SLOT_VIRTUAL);
4212 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4213 }
4214 })
4215
4216 (define_insn "*truncxfsf2_mixed"
4217 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4218 (float_truncate:SF
4219 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4220 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4221 "TARGET_80387"
4222 {
4223 gcc_assert (!which_alternative);
4224 return output_387_reg_move (insn, operands);
4225 }
4226 [(set_attr "type" "fmov,multi,multi,multi")
4227 (set_attr "unit" "*,i387,i387,i387")
4228 (set_attr "mode" "SF")])
4229
4230 (define_insn "*truncxfdf2_mixed"
4231 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4232 (float_truncate:DF
4233 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4234 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4235 "TARGET_80387"
4236 {
4237 gcc_assert (!which_alternative);
4238 return output_387_reg_move (insn, operands);
4239 }
4240 [(set_attr "isa" "*,*,sse2,*")
4241 (set_attr "type" "fmov,multi,multi,multi")
4242 (set_attr "unit" "*,i387,i387,i387")
4243 (set_attr "mode" "DF")])
4244
4245 (define_insn "truncxf<mode>2_i387_noop"
4246 [(set (match_operand:MODEF 0 "register_operand" "=f")
4247 (float_truncate:MODEF
4248 (match_operand:XF 1 "register_operand" "f")))]
4249 "TARGET_80387 && flag_unsafe_math_optimizations"
4250 "* return output_387_reg_move (insn, operands);"
4251 [(set_attr "type" "fmov")
4252 (set_attr "mode" "<MODE>")])
4253
4254 (define_insn "*truncxf<mode>2_i387"
4255 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4256 (float_truncate:MODEF
4257 (match_operand:XF 1 "register_operand" "f")))]
4258 "TARGET_80387"
4259 "* return output_387_reg_move (insn, operands);"
4260 [(set_attr "type" "fmov")
4261 (set_attr "mode" "<MODE>")])
4262
4263 (define_split
4264 [(set (match_operand:MODEF 0 "register_operand" "")
4265 (float_truncate:MODEF
4266 (match_operand:XF 1 "register_operand" "")))
4267 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4268 "TARGET_80387 && reload_completed"
4269 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4270 (set (match_dup 0) (match_dup 2))])
4271
4272 (define_split
4273 [(set (match_operand:MODEF 0 "memory_operand" "")
4274 (float_truncate:MODEF
4275 (match_operand:XF 1 "register_operand" "")))
4276 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4277 "TARGET_80387"
4278 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4279 \f
4280 ;; Signed conversion to DImode.
4281
4282 (define_expand "fix_truncxfdi2"
4283 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4284 (fix:DI (match_operand:XF 1 "register_operand" "")))
4285 (clobber (reg:CC FLAGS_REG))])]
4286 "TARGET_80387"
4287 {
4288 if (TARGET_FISTTP)
4289 {
4290 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4291 DONE;
4292 }
4293 })
4294
4295 (define_expand "fix_trunc<mode>di2"
4296 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4297 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4298 (clobber (reg:CC FLAGS_REG))])]
4299 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4300 {
4301 if (TARGET_FISTTP
4302 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4303 {
4304 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4305 DONE;
4306 }
4307 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4308 {
4309 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4310 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4311 if (out != operands[0])
4312 emit_move_insn (operands[0], out);
4313 DONE;
4314 }
4315 })
4316
4317 ;; Signed conversion to SImode.
4318
4319 (define_expand "fix_truncxfsi2"
4320 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4321 (fix:SI (match_operand:XF 1 "register_operand" "")))
4322 (clobber (reg:CC FLAGS_REG))])]
4323 "TARGET_80387"
4324 {
4325 if (TARGET_FISTTP)
4326 {
4327 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4328 DONE;
4329 }
4330 })
4331
4332 (define_expand "fix_trunc<mode>si2"
4333 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4334 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4335 (clobber (reg:CC FLAGS_REG))])]
4336 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4337 {
4338 if (TARGET_FISTTP
4339 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4340 {
4341 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4342 DONE;
4343 }
4344 if (SSE_FLOAT_MODE_P (<MODE>mode))
4345 {
4346 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4347 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4348 if (out != operands[0])
4349 emit_move_insn (operands[0], out);
4350 DONE;
4351 }
4352 })
4353
4354 ;; Signed conversion to HImode.
4355
4356 (define_expand "fix_trunc<mode>hi2"
4357 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4358 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4359 (clobber (reg:CC FLAGS_REG))])]
4360 "TARGET_80387
4361 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4362 {
4363 if (TARGET_FISTTP)
4364 {
4365 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4366 DONE;
4367 }
4368 })
4369
4370 ;; Unsigned conversion to SImode.
4371
4372 (define_expand "fixuns_trunc<mode>si2"
4373 [(parallel
4374 [(set (match_operand:SI 0 "register_operand" "")
4375 (unsigned_fix:SI
4376 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4377 (use (match_dup 2))
4378 (clobber (match_scratch:<ssevecmode> 3 ""))
4379 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4380 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4381 {
4382 enum machine_mode mode = <MODE>mode;
4383 enum machine_mode vecmode = <ssevecmode>mode;
4384 REAL_VALUE_TYPE TWO31r;
4385 rtx two31;
4386
4387 if (optimize_insn_for_size_p ())
4388 FAIL;
4389
4390 real_ldexp (&TWO31r, &dconst1, 31);
4391 two31 = const_double_from_real_value (TWO31r, mode);
4392 two31 = ix86_build_const_vector (vecmode, true, two31);
4393 operands[2] = force_reg (vecmode, two31);
4394 })
4395
4396 (define_insn_and_split "*fixuns_trunc<mode>_1"
4397 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4398 (unsigned_fix:SI
4399 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4400 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4401 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4402 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4403 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4404 && optimize_function_for_speed_p (cfun)"
4405 "#"
4406 "&& reload_completed"
4407 [(const_int 0)]
4408 {
4409 ix86_split_convert_uns_si_sse (operands);
4410 DONE;
4411 })
4412
4413 ;; Unsigned conversion to HImode.
4414 ;; Without these patterns, we'll try the unsigned SI conversion which
4415 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4416
4417 (define_expand "fixuns_trunc<mode>hi2"
4418 [(set (match_dup 2)
4419 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4420 (set (match_operand:HI 0 "nonimmediate_operand" "")
4421 (subreg:HI (match_dup 2) 0))]
4422 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4423 "operands[2] = gen_reg_rtx (SImode);")
4424
4425 ;; When SSE is available, it is always faster to use it!
4426 (define_insn "fix_trunc<mode>di_sse"
4427 [(set (match_operand:DI 0 "register_operand" "=r,r")
4428 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4429 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4430 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4431 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4432 [(set_attr "type" "sseicvt")
4433 (set_attr "prefix" "maybe_vex")
4434 (set_attr "prefix_rex" "1")
4435 (set_attr "mode" "<MODE>")
4436 (set_attr "athlon_decode" "double,vector")
4437 (set_attr "amdfam10_decode" "double,double")
4438 (set_attr "bdver1_decode" "double,double")])
4439
4440 (define_insn "fix_trunc<mode>si_sse"
4441 [(set (match_operand:SI 0 "register_operand" "=r,r")
4442 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4443 "SSE_FLOAT_MODE_P (<MODE>mode)
4444 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4445 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4446 [(set_attr "type" "sseicvt")
4447 (set_attr "prefix" "maybe_vex")
4448 (set_attr "mode" "<MODE>")
4449 (set_attr "athlon_decode" "double,vector")
4450 (set_attr "amdfam10_decode" "double,double")
4451 (set_attr "bdver1_decode" "double,double")])
4452
4453 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4454 (define_peephole2
4455 [(set (match_operand:MODEF 0 "register_operand" "")
4456 (match_operand:MODEF 1 "memory_operand" ""))
4457 (set (match_operand:SWI48x 2 "register_operand" "")
4458 (fix:SWI48x (match_dup 0)))]
4459 "TARGET_SHORTEN_X87_SSE
4460 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4461 && peep2_reg_dead_p (2, operands[0])"
4462 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4463
4464 ;; Avoid vector decoded forms of the instruction.
4465 (define_peephole2
4466 [(match_scratch:DF 2 "x")
4467 (set (match_operand:SWI48x 0 "register_operand" "")
4468 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4469 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4470 [(set (match_dup 2) (match_dup 1))
4471 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4472
4473 (define_peephole2
4474 [(match_scratch:SF 2 "x")
4475 (set (match_operand:SWI48x 0 "register_operand" "")
4476 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4477 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4478 [(set (match_dup 2) (match_dup 1))
4479 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4480
4481 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4482 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4483 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4484 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4485 && TARGET_FISTTP
4486 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4487 && (TARGET_64BIT || <MODE>mode != DImode))
4488 && TARGET_SSE_MATH)
4489 && can_create_pseudo_p ()"
4490 "#"
4491 "&& 1"
4492 [(const_int 0)]
4493 {
4494 if (memory_operand (operands[0], VOIDmode))
4495 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4496 else
4497 {
4498 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4499 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4500 operands[1],
4501 operands[2]));
4502 }
4503 DONE;
4504 }
4505 [(set_attr "type" "fisttp")
4506 (set_attr "mode" "<MODE>")])
4507
4508 (define_insn "fix_trunc<mode>_i387_fisttp"
4509 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4510 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4511 (clobber (match_scratch:XF 2 "=&1f"))]
4512 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4513 && TARGET_FISTTP
4514 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4515 && (TARGET_64BIT || <MODE>mode != DImode))
4516 && TARGET_SSE_MATH)"
4517 "* return output_fix_trunc (insn, operands, true);"
4518 [(set_attr "type" "fisttp")
4519 (set_attr "mode" "<MODE>")])
4520
4521 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4522 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4523 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4524 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4525 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4526 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4527 && TARGET_FISTTP
4528 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && (TARGET_64BIT || <MODE>mode != DImode))
4530 && TARGET_SSE_MATH)"
4531 "#"
4532 [(set_attr "type" "fisttp")
4533 (set_attr "mode" "<MODE>")])
4534
4535 (define_split
4536 [(set (match_operand:SWI248x 0 "register_operand" "")
4537 (fix:SWI248x (match_operand 1 "register_operand" "")))
4538 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4539 (clobber (match_scratch 3 ""))]
4540 "reload_completed"
4541 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4542 (clobber (match_dup 3))])
4543 (set (match_dup 0) (match_dup 2))])
4544
4545 (define_split
4546 [(set (match_operand:SWI248x 0 "memory_operand" "")
4547 (fix:SWI248x (match_operand 1 "register_operand" "")))
4548 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4549 (clobber (match_scratch 3 ""))]
4550 "reload_completed"
4551 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4552 (clobber (match_dup 3))])])
4553
4554 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4555 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4556 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4557 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4558 ;; function in i386.c.
4559 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4560 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4561 (fix:SWI248x (match_operand 1 "register_operand" "")))
4562 (clobber (reg:CC FLAGS_REG))]
4563 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4564 && !TARGET_FISTTP
4565 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4566 && (TARGET_64BIT || <MODE>mode != DImode))
4567 && can_create_pseudo_p ()"
4568 "#"
4569 "&& 1"
4570 [(const_int 0)]
4571 {
4572 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4573
4574 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4575 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4576 if (memory_operand (operands[0], VOIDmode))
4577 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4578 operands[2], operands[3]));
4579 else
4580 {
4581 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4582 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4583 operands[2], operands[3],
4584 operands[4]));
4585 }
4586 DONE;
4587 }
4588 [(set_attr "type" "fistp")
4589 (set_attr "i387_cw" "trunc")
4590 (set_attr "mode" "<MODE>")])
4591
4592 (define_insn "fix_truncdi_i387"
4593 [(set (match_operand:DI 0 "memory_operand" "=m")
4594 (fix:DI (match_operand 1 "register_operand" "f")))
4595 (use (match_operand:HI 2 "memory_operand" "m"))
4596 (use (match_operand:HI 3 "memory_operand" "m"))
4597 (clobber (match_scratch:XF 4 "=&1f"))]
4598 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4599 && !TARGET_FISTTP
4600 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4601 "* return output_fix_trunc (insn, operands, false);"
4602 [(set_attr "type" "fistp")
4603 (set_attr "i387_cw" "trunc")
4604 (set_attr "mode" "DI")])
4605
4606 (define_insn "fix_truncdi_i387_with_temp"
4607 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4608 (fix:DI (match_operand 1 "register_operand" "f,f")))
4609 (use (match_operand:HI 2 "memory_operand" "m,m"))
4610 (use (match_operand:HI 3 "memory_operand" "m,m"))
4611 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4612 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4613 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4614 && !TARGET_FISTTP
4615 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4616 "#"
4617 [(set_attr "type" "fistp")
4618 (set_attr "i387_cw" "trunc")
4619 (set_attr "mode" "DI")])
4620
4621 (define_split
4622 [(set (match_operand:DI 0 "register_operand" "")
4623 (fix:DI (match_operand 1 "register_operand" "")))
4624 (use (match_operand:HI 2 "memory_operand" ""))
4625 (use (match_operand:HI 3 "memory_operand" ""))
4626 (clobber (match_operand:DI 4 "memory_operand" ""))
4627 (clobber (match_scratch 5 ""))]
4628 "reload_completed"
4629 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4630 (use (match_dup 2))
4631 (use (match_dup 3))
4632 (clobber (match_dup 5))])
4633 (set (match_dup 0) (match_dup 4))])
4634
4635 (define_split
4636 [(set (match_operand:DI 0 "memory_operand" "")
4637 (fix:DI (match_operand 1 "register_operand" "")))
4638 (use (match_operand:HI 2 "memory_operand" ""))
4639 (use (match_operand:HI 3 "memory_operand" ""))
4640 (clobber (match_operand:DI 4 "memory_operand" ""))
4641 (clobber (match_scratch 5 ""))]
4642 "reload_completed"
4643 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4644 (use (match_dup 2))
4645 (use (match_dup 3))
4646 (clobber (match_dup 5))])])
4647
4648 (define_insn "fix_trunc<mode>_i387"
4649 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4650 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4651 (use (match_operand:HI 2 "memory_operand" "m"))
4652 (use (match_operand:HI 3 "memory_operand" "m"))]
4653 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4654 && !TARGET_FISTTP
4655 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4656 "* return output_fix_trunc (insn, operands, false);"
4657 [(set_attr "type" "fistp")
4658 (set_attr "i387_cw" "trunc")
4659 (set_attr "mode" "<MODE>")])
4660
4661 (define_insn "fix_trunc<mode>_i387_with_temp"
4662 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4663 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4664 (use (match_operand:HI 2 "memory_operand" "m,m"))
4665 (use (match_operand:HI 3 "memory_operand" "m,m"))
4666 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4667 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4668 && !TARGET_FISTTP
4669 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4670 "#"
4671 [(set_attr "type" "fistp")
4672 (set_attr "i387_cw" "trunc")
4673 (set_attr "mode" "<MODE>")])
4674
4675 (define_split
4676 [(set (match_operand:SWI24 0 "register_operand" "")
4677 (fix:SWI24 (match_operand 1 "register_operand" "")))
4678 (use (match_operand:HI 2 "memory_operand" ""))
4679 (use (match_operand:HI 3 "memory_operand" ""))
4680 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4681 "reload_completed"
4682 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4683 (use (match_dup 2))
4684 (use (match_dup 3))])
4685 (set (match_dup 0) (match_dup 4))])
4686
4687 (define_split
4688 [(set (match_operand:SWI24 0 "memory_operand" "")
4689 (fix:SWI24 (match_operand 1 "register_operand" "")))
4690 (use (match_operand:HI 2 "memory_operand" ""))
4691 (use (match_operand:HI 3 "memory_operand" ""))
4692 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4693 "reload_completed"
4694 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4695 (use (match_dup 2))
4696 (use (match_dup 3))])])
4697
4698 (define_insn "x86_fnstcw_1"
4699 [(set (match_operand:HI 0 "memory_operand" "=m")
4700 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4701 "TARGET_80387"
4702 "fnstcw\t%0"
4703 [(set (attr "length")
4704 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4705 (set_attr "mode" "HI")
4706 (set_attr "unit" "i387")
4707 (set_attr "bdver1_decode" "vector")])
4708
4709 (define_insn "x86_fldcw_1"
4710 [(set (reg:HI FPCR_REG)
4711 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4712 "TARGET_80387"
4713 "fldcw\t%0"
4714 [(set (attr "length")
4715 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4716 (set_attr "mode" "HI")
4717 (set_attr "unit" "i387")
4718 (set_attr "athlon_decode" "vector")
4719 (set_attr "amdfam10_decode" "vector")
4720 (set_attr "bdver1_decode" "vector")])
4721 \f
4722 ;; Conversion between fixed point and floating point.
4723
4724 ;; Even though we only accept memory inputs, the backend _really_
4725 ;; wants to be able to do this between registers.
4726
4727 (define_expand "floathi<mode>2"
4728 [(set (match_operand:X87MODEF 0 "register_operand" "")
4729 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4730 "TARGET_80387
4731 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4732 || TARGET_MIX_SSE_I387)")
4733
4734 ;; Pre-reload splitter to add memory clobber to the pattern.
4735 (define_insn_and_split "*floathi<mode>2_1"
4736 [(set (match_operand:X87MODEF 0 "register_operand" "")
4737 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4738 "TARGET_80387
4739 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4740 || TARGET_MIX_SSE_I387)
4741 && can_create_pseudo_p ()"
4742 "#"
4743 "&& 1"
4744 [(parallel [(set (match_dup 0)
4745 (float:X87MODEF (match_dup 1)))
4746 (clobber (match_dup 2))])]
4747 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4748
4749 (define_insn "*floathi<mode>2_i387_with_temp"
4750 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4751 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4752 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4753 "TARGET_80387
4754 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4755 || TARGET_MIX_SSE_I387)"
4756 "#"
4757 [(set_attr "type" "fmov,multi")
4758 (set_attr "mode" "<MODE>")
4759 (set_attr "unit" "*,i387")
4760 (set_attr "fp_int_src" "true")])
4761
4762 (define_insn "*floathi<mode>2_i387"
4763 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4764 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4765 "TARGET_80387
4766 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4767 || TARGET_MIX_SSE_I387)"
4768 "fild%Z1\t%1"
4769 [(set_attr "type" "fmov")
4770 (set_attr "mode" "<MODE>")
4771 (set_attr "fp_int_src" "true")])
4772
4773 (define_split
4774 [(set (match_operand:X87MODEF 0 "register_operand" "")
4775 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4776 (clobber (match_operand:HI 2 "memory_operand" ""))]
4777 "TARGET_80387
4778 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4779 || TARGET_MIX_SSE_I387)
4780 && reload_completed"
4781 [(set (match_dup 2) (match_dup 1))
4782 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4783
4784 (define_split
4785 [(set (match_operand:X87MODEF 0 "register_operand" "")
4786 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4787 (clobber (match_operand:HI 2 "memory_operand" ""))]
4788 "TARGET_80387
4789 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4790 || TARGET_MIX_SSE_I387)
4791 && reload_completed"
4792 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4793
4794 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4795 [(set (match_operand:X87MODEF 0 "register_operand" "")
4796 (float:X87MODEF
4797 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4798 "TARGET_80387
4799 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4800 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4801 {
4802 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4803 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4804 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4805 {
4806 rtx reg = gen_reg_rtx (XFmode);
4807 rtx (*insn)(rtx, rtx);
4808
4809 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4810
4811 if (<X87MODEF:MODE>mode == SFmode)
4812 insn = gen_truncxfsf2;
4813 else if (<X87MODEF:MODE>mode == DFmode)
4814 insn = gen_truncxfdf2;
4815 else
4816 gcc_unreachable ();
4817
4818 emit_insn (insn (operands[0], reg));
4819 DONE;
4820 }
4821 })
4822
4823 ;; Pre-reload splitter to add memory clobber to the pattern.
4824 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4825 [(set (match_operand:X87MODEF 0 "register_operand" "")
4826 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4827 "((TARGET_80387
4828 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4829 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4830 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4831 || TARGET_MIX_SSE_I387))
4832 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4833 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4834 && ((<SWI48x:MODE>mode == SImode
4835 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4836 && optimize_function_for_speed_p (cfun)
4837 && flag_trapping_math)
4838 || !(TARGET_INTER_UNIT_CONVERSIONS
4839 || optimize_function_for_size_p (cfun)))))
4840 && can_create_pseudo_p ()"
4841 "#"
4842 "&& 1"
4843 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4844 (clobber (match_dup 2))])]
4845 {
4846 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4847
4848 /* Avoid store forwarding (partial memory) stall penalty
4849 by passing DImode value through XMM registers. */
4850 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4851 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4852 && optimize_function_for_speed_p (cfun))
4853 {
4854 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4855 operands[1],
4856 operands[2]));
4857 DONE;
4858 }
4859 })
4860
4861 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4862 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4863 (float:MODEF
4864 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4865 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4866 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4867 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4868 "#"
4869 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4870 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4871 (set_attr "unit" "*,i387,*,*,*")
4872 (set_attr "athlon_decode" "*,*,double,direct,double")
4873 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4874 (set_attr "bdver1_decode" "*,*,double,direct,double")
4875 (set_attr "fp_int_src" "true")])
4876
4877 (define_insn "*floatsi<mode>2_vector_mixed"
4878 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4879 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4880 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4881 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4882 "@
4883 fild%Z1\t%1
4884 #"
4885 [(set_attr "type" "fmov,sseicvt")
4886 (set_attr "mode" "<MODE>,<ssevecmode>")
4887 (set_attr "unit" "i387,*")
4888 (set_attr "athlon_decode" "*,direct")
4889 (set_attr "amdfam10_decode" "*,double")
4890 (set_attr "bdver1_decode" "*,direct")
4891 (set_attr "fp_int_src" "true")])
4892
4893 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4894 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4895 (float:MODEF
4896 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4897 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4898 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4899 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4900 "#"
4901 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4902 (set_attr "mode" "<MODEF:MODE>")
4903 (set_attr "unit" "*,i387,*,*")
4904 (set_attr "athlon_decode" "*,*,double,direct")
4905 (set_attr "amdfam10_decode" "*,*,vector,double")
4906 (set_attr "bdver1_decode" "*,*,double,direct")
4907 (set_attr "fp_int_src" "true")])
4908
4909 (define_split
4910 [(set (match_operand:MODEF 0 "register_operand" "")
4911 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4912 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4913 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4914 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4915 && TARGET_INTER_UNIT_CONVERSIONS
4916 && reload_completed
4917 && (SSE_REG_P (operands[0])
4918 || (GET_CODE (operands[0]) == SUBREG
4919 && SSE_REG_P (operands[0])))"
4920 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4921
4922 (define_split
4923 [(set (match_operand:MODEF 0 "register_operand" "")
4924 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4925 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4926 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4927 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4928 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4929 && reload_completed
4930 && (SSE_REG_P (operands[0])
4931 || (GET_CODE (operands[0]) == SUBREG
4932 && SSE_REG_P (operands[0])))"
4933 [(set (match_dup 2) (match_dup 1))
4934 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4935
4936 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4937 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4938 (float:MODEF
4939 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4940 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4941 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4942 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4943 "@
4944 fild%Z1\t%1
4945 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4946 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4947 [(set_attr "type" "fmov,sseicvt,sseicvt")
4948 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4949 (set_attr "mode" "<MODEF:MODE>")
4950 (set (attr "prefix_rex")
4951 (if_then_else
4952 (and (eq_attr "prefix" "maybe_vex")
4953 (match_test "<SWI48x:MODE>mode == DImode"))
4954 (const_string "1")
4955 (const_string "*")))
4956 (set_attr "unit" "i387,*,*")
4957 (set_attr "athlon_decode" "*,double,direct")
4958 (set_attr "amdfam10_decode" "*,vector,double")
4959 (set_attr "bdver1_decode" "*,double,direct")
4960 (set_attr "fp_int_src" "true")])
4961
4962 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4963 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4964 (float:MODEF
4965 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4966 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4967 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4968 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4969 "@
4970 fild%Z1\t%1
4971 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4972 [(set_attr "type" "fmov,sseicvt")
4973 (set_attr "prefix" "orig,maybe_vex")
4974 (set_attr "mode" "<MODEF:MODE>")
4975 (set (attr "prefix_rex")
4976 (if_then_else
4977 (and (eq_attr "prefix" "maybe_vex")
4978 (match_test "<SWI48x:MODE>mode == DImode"))
4979 (const_string "1")
4980 (const_string "*")))
4981 (set_attr "athlon_decode" "*,direct")
4982 (set_attr "amdfam10_decode" "*,double")
4983 (set_attr "bdver1_decode" "*,direct")
4984 (set_attr "fp_int_src" "true")])
4985
4986 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4987 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4988 (float:MODEF
4989 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4990 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4991 "TARGET_SSE2 && TARGET_SSE_MATH
4992 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4993 "#"
4994 [(set_attr "type" "sseicvt")
4995 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4996 (set_attr "athlon_decode" "double,direct,double")
4997 (set_attr "amdfam10_decode" "vector,double,double")
4998 (set_attr "bdver1_decode" "double,direct,double")
4999 (set_attr "fp_int_src" "true")])
5000
5001 (define_insn "*floatsi<mode>2_vector_sse"
5002 [(set (match_operand:MODEF 0 "register_operand" "=x")
5003 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5004 "TARGET_SSE2 && TARGET_SSE_MATH
5005 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5006 "#"
5007 [(set_attr "type" "sseicvt")
5008 (set_attr "mode" "<MODE>")
5009 (set_attr "athlon_decode" "direct")
5010 (set_attr "amdfam10_decode" "double")
5011 (set_attr "bdver1_decode" "direct")
5012 (set_attr "fp_int_src" "true")])
5013
5014 (define_split
5015 [(set (match_operand:MODEF 0 "register_operand" "")
5016 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5017 (clobber (match_operand:SI 2 "memory_operand" ""))]
5018 "TARGET_SSE2 && TARGET_SSE_MATH
5019 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5020 && reload_completed
5021 && (SSE_REG_P (operands[0])
5022 || (GET_CODE (operands[0]) == SUBREG
5023 && SSE_REG_P (operands[0])))"
5024 [(const_int 0)]
5025 {
5026 rtx op1 = operands[1];
5027
5028 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5029 <MODE>mode, 0);
5030 if (GET_CODE (op1) == SUBREG)
5031 op1 = SUBREG_REG (op1);
5032
5033 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5034 {
5035 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5036 emit_insn (gen_sse2_loadld (operands[4],
5037 CONST0_RTX (V4SImode), operands[1]));
5038 }
5039 /* We can ignore possible trapping value in the
5040 high part of SSE register for non-trapping math. */
5041 else if (SSE_REG_P (op1) && !flag_trapping_math)
5042 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5043 else
5044 {
5045 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5046 emit_move_insn (operands[2], operands[1]);
5047 emit_insn (gen_sse2_loadld (operands[4],
5048 CONST0_RTX (V4SImode), operands[2]));
5049 }
5050 emit_insn
5051 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5052 DONE;
5053 })
5054
5055 (define_split
5056 [(set (match_operand:MODEF 0 "register_operand" "")
5057 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5058 (clobber (match_operand:SI 2 "memory_operand" ""))]
5059 "TARGET_SSE2 && TARGET_SSE_MATH
5060 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5061 && reload_completed
5062 && (SSE_REG_P (operands[0])
5063 || (GET_CODE (operands[0]) == SUBREG
5064 && SSE_REG_P (operands[0])))"
5065 [(const_int 0)]
5066 {
5067 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5068 <MODE>mode, 0);
5069 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5070
5071 emit_insn (gen_sse2_loadld (operands[4],
5072 CONST0_RTX (V4SImode), operands[1]));
5073 emit_insn
5074 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5075 DONE;
5076 })
5077
5078 (define_split
5079 [(set (match_operand:MODEF 0 "register_operand" "")
5080 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5081 "TARGET_SSE2 && TARGET_SSE_MATH
5082 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5083 && reload_completed
5084 && (SSE_REG_P (operands[0])
5085 || (GET_CODE (operands[0]) == SUBREG
5086 && SSE_REG_P (operands[0])))"
5087 [(const_int 0)]
5088 {
5089 rtx op1 = operands[1];
5090
5091 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5092 <MODE>mode, 0);
5093 if (GET_CODE (op1) == SUBREG)
5094 op1 = SUBREG_REG (op1);
5095
5096 if (GENERAL_REG_P (op1))
5097 {
5098 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5099 if (TARGET_INTER_UNIT_MOVES)
5100 emit_insn (gen_sse2_loadld (operands[4],
5101 CONST0_RTX (V4SImode), operands[1]));
5102 else
5103 {
5104 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5105 operands[1]);
5106 emit_insn (gen_sse2_loadld (operands[4],
5107 CONST0_RTX (V4SImode), operands[5]));
5108 ix86_free_from_memory (GET_MODE (operands[1]));
5109 }
5110 }
5111 /* We can ignore possible trapping value in the
5112 high part of SSE register for non-trapping math. */
5113 else if (SSE_REG_P (op1) && !flag_trapping_math)
5114 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5115 else
5116 gcc_unreachable ();
5117 emit_insn
5118 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5119 DONE;
5120 })
5121
5122 (define_split
5123 [(set (match_operand:MODEF 0 "register_operand" "")
5124 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5125 "TARGET_SSE2 && TARGET_SSE_MATH
5126 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5127 && reload_completed
5128 && (SSE_REG_P (operands[0])
5129 || (GET_CODE (operands[0]) == SUBREG
5130 && SSE_REG_P (operands[0])))"
5131 [(const_int 0)]
5132 {
5133 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5134 <MODE>mode, 0);
5135 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5136
5137 emit_insn (gen_sse2_loadld (operands[4],
5138 CONST0_RTX (V4SImode), operands[1]));
5139 emit_insn
5140 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5141 DONE;
5142 })
5143
5144 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5145 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5146 (float:MODEF
5147 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5148 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5149 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5150 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5151 "#"
5152 [(set_attr "type" "sseicvt")
5153 (set_attr "mode" "<MODEF:MODE>")
5154 (set_attr "athlon_decode" "double,direct")
5155 (set_attr "amdfam10_decode" "vector,double")
5156 (set_attr "bdver1_decode" "double,direct")
5157 (set_attr "fp_int_src" "true")])
5158
5159 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5160 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5161 (float:MODEF
5162 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5163 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5164 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5165 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5166 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5167 [(set_attr "type" "sseicvt")
5168 (set_attr "prefix" "maybe_vex")
5169 (set_attr "mode" "<MODEF:MODE>")
5170 (set (attr "prefix_rex")
5171 (if_then_else
5172 (and (eq_attr "prefix" "maybe_vex")
5173 (match_test "<SWI48x:MODE>mode == DImode"))
5174 (const_string "1")
5175 (const_string "*")))
5176 (set_attr "athlon_decode" "double,direct")
5177 (set_attr "amdfam10_decode" "vector,double")
5178 (set_attr "bdver1_decode" "double,direct")
5179 (set_attr "fp_int_src" "true")])
5180
5181 (define_split
5182 [(set (match_operand:MODEF 0 "register_operand" "")
5183 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5184 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5185 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5186 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5187 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5188 && reload_completed
5189 && (SSE_REG_P (operands[0])
5190 || (GET_CODE (operands[0]) == SUBREG
5191 && SSE_REG_P (operands[0])))"
5192 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5193
5194 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5195 [(set (match_operand:MODEF 0 "register_operand" "=x")
5196 (float:MODEF
5197 (match_operand:SWI48x 1 "memory_operand" "m")))]
5198 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5199 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5200 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5201 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5202 [(set_attr "type" "sseicvt")
5203 (set_attr "prefix" "maybe_vex")
5204 (set_attr "mode" "<MODEF:MODE>")
5205 (set (attr "prefix_rex")
5206 (if_then_else
5207 (and (eq_attr "prefix" "maybe_vex")
5208 (match_test "<SWI48x:MODE>mode == DImode"))
5209 (const_string "1")
5210 (const_string "*")))
5211 (set_attr "athlon_decode" "direct")
5212 (set_attr "amdfam10_decode" "double")
5213 (set_attr "bdver1_decode" "direct")
5214 (set_attr "fp_int_src" "true")])
5215
5216 (define_split
5217 [(set (match_operand:MODEF 0 "register_operand" "")
5218 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5219 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5220 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5221 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5222 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5223 && reload_completed
5224 && (SSE_REG_P (operands[0])
5225 || (GET_CODE (operands[0]) == SUBREG
5226 && SSE_REG_P (operands[0])))"
5227 [(set (match_dup 2) (match_dup 1))
5228 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5229
5230 (define_split
5231 [(set (match_operand:MODEF 0 "register_operand" "")
5232 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5233 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5234 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5235 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5236 && reload_completed
5237 && (SSE_REG_P (operands[0])
5238 || (GET_CODE (operands[0]) == SUBREG
5239 && SSE_REG_P (operands[0])))"
5240 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5241
5242 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5243 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5244 (float:X87MODEF
5245 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5246 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5247 "TARGET_80387
5248 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5249 "@
5250 fild%Z1\t%1
5251 #"
5252 [(set_attr "type" "fmov,multi")
5253 (set_attr "mode" "<X87MODEF:MODE>")
5254 (set_attr "unit" "*,i387")
5255 (set_attr "fp_int_src" "true")])
5256
5257 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5258 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5259 (float:X87MODEF
5260 (match_operand:SWI48x 1 "memory_operand" "m")))]
5261 "TARGET_80387
5262 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5263 "fild%Z1\t%1"
5264 [(set_attr "type" "fmov")
5265 (set_attr "mode" "<X87MODEF:MODE>")
5266 (set_attr "fp_int_src" "true")])
5267
5268 (define_split
5269 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5270 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5271 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5272 "TARGET_80387
5273 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5274 && reload_completed"
5275 [(set (match_dup 2) (match_dup 1))
5276 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5277
5278 (define_split
5279 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5280 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5281 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5282 "TARGET_80387
5283 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5284 && reload_completed"
5285 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5286
5287 ;; Avoid store forwarding (partial memory) stall penalty
5288 ;; by passing DImode value through XMM registers. */
5289
5290 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5291 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5292 (float:X87MODEF
5293 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5294 (clobber (match_scratch:V4SI 3 "=X,x"))
5295 (clobber (match_scratch:V4SI 4 "=X,x"))
5296 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5297 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5298 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5299 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5300 "#"
5301 [(set_attr "type" "multi")
5302 (set_attr "mode" "<X87MODEF:MODE>")
5303 (set_attr "unit" "i387")
5304 (set_attr "fp_int_src" "true")])
5305
5306 (define_split
5307 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5308 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5309 (clobber (match_scratch:V4SI 3 ""))
5310 (clobber (match_scratch:V4SI 4 ""))
5311 (clobber (match_operand:DI 2 "memory_operand" ""))]
5312 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5313 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5314 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5315 && reload_completed"
5316 [(set (match_dup 2) (match_dup 3))
5317 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5318 {
5319 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5320 Assemble the 64-bit DImode value in an xmm register. */
5321 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5322 gen_rtx_SUBREG (SImode, operands[1], 0)));
5323 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5324 gen_rtx_SUBREG (SImode, operands[1], 4)));
5325 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5326 operands[4]));
5327
5328 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5329 })
5330
5331 (define_split
5332 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5333 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5334 (clobber (match_scratch:V4SI 3 ""))
5335 (clobber (match_scratch:V4SI 4 ""))
5336 (clobber (match_operand:DI 2 "memory_operand" ""))]
5337 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5338 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5339 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5340 && reload_completed"
5341 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5342
5343 ;; Avoid store forwarding (partial memory) stall penalty by extending
5344 ;; SImode value to DImode through XMM register instead of pushing two
5345 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5346 ;; targets benefit from this optimization. Also note that fild
5347 ;; loads from memory only.
5348
5349 (define_insn "*floatunssi<mode>2_1"
5350 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5351 (unsigned_float:X87MODEF
5352 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5353 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5354 (clobber (match_scratch:SI 3 "=X,x"))]
5355 "!TARGET_64BIT
5356 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5357 && TARGET_SSE"
5358 "#"
5359 [(set_attr "type" "multi")
5360 (set_attr "mode" "<MODE>")])
5361
5362 (define_split
5363 [(set (match_operand:X87MODEF 0 "register_operand" "")
5364 (unsigned_float:X87MODEF
5365 (match_operand:SI 1 "register_operand" "")))
5366 (clobber (match_operand:DI 2 "memory_operand" ""))
5367 (clobber (match_scratch:SI 3 ""))]
5368 "!TARGET_64BIT
5369 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5370 && TARGET_SSE
5371 && reload_completed"
5372 [(set (match_dup 2) (match_dup 1))
5373 (set (match_dup 0)
5374 (float:X87MODEF (match_dup 2)))]
5375 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5376
5377 (define_split
5378 [(set (match_operand:X87MODEF 0 "register_operand" "")
5379 (unsigned_float:X87MODEF
5380 (match_operand:SI 1 "memory_operand" "")))
5381 (clobber (match_operand:DI 2 "memory_operand" ""))
5382 (clobber (match_scratch:SI 3 ""))]
5383 "!TARGET_64BIT
5384 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5385 && TARGET_SSE
5386 && reload_completed"
5387 [(set (match_dup 2) (match_dup 3))
5388 (set (match_dup 0)
5389 (float:X87MODEF (match_dup 2)))]
5390 {
5391 emit_move_insn (operands[3], operands[1]);
5392 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5393 })
5394
5395 (define_expand "floatunssi<mode>2"
5396 [(parallel
5397 [(set (match_operand:X87MODEF 0 "register_operand" "")
5398 (unsigned_float:X87MODEF
5399 (match_operand:SI 1 "nonimmediate_operand" "")))
5400 (clobber (match_dup 2))
5401 (clobber (match_scratch:SI 3 ""))])]
5402 "!TARGET_64BIT
5403 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5404 && TARGET_SSE)
5405 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5406 {
5407 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5408 {
5409 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5410 DONE;
5411 }
5412 else
5413 {
5414 enum ix86_stack_slot slot = (virtuals_instantiated
5415 ? SLOT_TEMP
5416 : SLOT_VIRTUAL);
5417 operands[2] = assign_386_stack_local (DImode, slot);
5418 }
5419 })
5420
5421 (define_expand "floatunsdisf2"
5422 [(use (match_operand:SF 0 "register_operand" ""))
5423 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5424 "TARGET_64BIT && TARGET_SSE_MATH"
5425 "x86_emit_floatuns (operands); DONE;")
5426
5427 (define_expand "floatunsdidf2"
5428 [(use (match_operand:DF 0 "register_operand" ""))
5429 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5430 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5431 && TARGET_SSE2 && TARGET_SSE_MATH"
5432 {
5433 if (TARGET_64BIT)
5434 x86_emit_floatuns (operands);
5435 else
5436 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5437 DONE;
5438 })
5439 \f
5440 ;; Add instructions
5441
5442 (define_expand "add<mode>3"
5443 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5444 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5445 (match_operand:SDWIM 2 "<general_operand>" "")))]
5446 ""
5447 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5448
5449 (define_insn_and_split "*add<dwi>3_doubleword"
5450 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5451 (plus:<DWI>
5452 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5453 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5454 (clobber (reg:CC FLAGS_REG))]
5455 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5456 "#"
5457 "reload_completed"
5458 [(parallel [(set (reg:CC FLAGS_REG)
5459 (unspec:CC [(match_dup 1) (match_dup 2)]
5460 UNSPEC_ADD_CARRY))
5461 (set (match_dup 0)
5462 (plus:DWIH (match_dup 1) (match_dup 2)))])
5463 (parallel [(set (match_dup 3)
5464 (plus:DWIH
5465 (match_dup 4)
5466 (plus:DWIH
5467 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5468 (match_dup 5))))
5469 (clobber (reg:CC FLAGS_REG))])]
5470 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5471
5472 (define_insn "*add<mode>3_cc"
5473 [(set (reg:CC FLAGS_REG)
5474 (unspec:CC
5475 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5476 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5477 UNSPEC_ADD_CARRY))
5478 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5479 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5480 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5481 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5482 [(set_attr "type" "alu")
5483 (set_attr "mode" "<MODE>")])
5484
5485 (define_insn "addqi3_cc"
5486 [(set (reg:CC FLAGS_REG)
5487 (unspec:CC
5488 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5489 (match_operand:QI 2 "general_operand" "qn,qm")]
5490 UNSPEC_ADD_CARRY))
5491 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5492 (plus:QI (match_dup 1) (match_dup 2)))]
5493 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5494 "add{b}\t{%2, %0|%0, %2}"
5495 [(set_attr "type" "alu")
5496 (set_attr "mode" "QI")])
5497
5498 (define_insn_and_split "*lea_1"
5499 [(set (match_operand:SI 0 "register_operand" "=r")
5500 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5501 "TARGET_64BIT"
5502 "lea{l}\t{%a1, %0|%0, %a1}"
5503 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5504 [(const_int 0)]
5505 {
5506 ix86_split_lea_for_addr (operands, SImode);
5507 DONE;
5508 }
5509 [(set_attr "type" "lea")
5510 (set_attr "mode" "SI")])
5511
5512 (define_insn_and_split "*lea<mode>_2"
5513 [(set (match_operand:SWI48 0 "register_operand" "=r")
5514 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5515 ""
5516 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5517 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5518 [(const_int 0)]
5519 {
5520 ix86_split_lea_for_addr (operands, <MODE>mode);
5521 DONE;
5522 }
5523 [(set_attr "type" "lea")
5524 (set_attr "mode" "<MODE>")])
5525
5526 (define_insn "*lea_3_zext"
5527 [(set (match_operand:DI 0 "register_operand" "=r")
5528 (zero_extend:DI
5529 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
5530 "TARGET_64BIT"
5531 "lea{l}\t{%a1, %k0|%k0, %a1}"
5532 [(set_attr "type" "lea")
5533 (set_attr "mode" "SI")])
5534
5535 (define_insn "*lea_4_zext"
5536 [(set (match_operand:DI 0 "register_operand" "=r")
5537 (zero_extend:DI
5538 (match_operand:SI 1 "lea_address_operand" "p")))]
5539 "TARGET_64BIT"
5540 "lea{l}\t{%a1, %k0|%k0, %a1}"
5541 [(set_attr "type" "lea")
5542 (set_attr "mode" "SI")])
5543
5544 (define_insn "*lea_5_zext"
5545 [(set (match_operand:DI 0 "register_operand" "=r")
5546 (and:DI
5547 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5548 (match_operand:DI 2 "const_32bit_mask" "n")))]
5549 "TARGET_64BIT"
5550 "lea{l}\t{%a1, %k0|%k0, %a1}"
5551 [(set_attr "type" "lea")
5552 (set_attr "mode" "SI")])
5553
5554 (define_insn "*lea_6_zext"
5555 [(set (match_operand:DI 0 "register_operand" "=r")
5556 (and:DI
5557 (match_operand:DI 1 "lea_address_operand" "p")
5558 (match_operand:DI 2 "const_32bit_mask" "n")))]
5559 "TARGET_64BIT"
5560 "lea{l}\t{%a1, %k0|%k0, %a1}"
5561 [(set_attr "type" "lea")
5562 (set_attr "mode" "SI")])
5563
5564 (define_insn "*add<mode>_1"
5565 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5566 (plus:SWI48
5567 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5568 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5569 (clobber (reg:CC FLAGS_REG))]
5570 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5571 {
5572 switch (get_attr_type (insn))
5573 {
5574 case TYPE_LEA:
5575 return "#";
5576
5577 case TYPE_INCDEC:
5578 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5579 if (operands[2] == const1_rtx)
5580 return "inc{<imodesuffix>}\t%0";
5581 else
5582 {
5583 gcc_assert (operands[2] == constm1_rtx);
5584 return "dec{<imodesuffix>}\t%0";
5585 }
5586
5587 default:
5588 /* For most processors, ADD is faster than LEA. This alternative
5589 was added to use ADD as much as possible. */
5590 if (which_alternative == 2)
5591 {
5592 rtx tmp;
5593 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5594 }
5595
5596 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5597 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5598 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5599
5600 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5601 }
5602 }
5603 [(set (attr "type")
5604 (cond [(eq_attr "alternative" "3")
5605 (const_string "lea")
5606 (match_operand:SWI48 2 "incdec_operand" "")
5607 (const_string "incdec")
5608 ]
5609 (const_string "alu")))
5610 (set (attr "length_immediate")
5611 (if_then_else
5612 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5613 (const_string "1")
5614 (const_string "*")))
5615 (set_attr "mode" "<MODE>")])
5616
5617 ;; It may seem that nonimmediate operand is proper one for operand 1.
5618 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5619 ;; we take care in ix86_binary_operator_ok to not allow two memory
5620 ;; operands so proper swapping will be done in reload. This allow
5621 ;; patterns constructed from addsi_1 to match.
5622
5623 (define_insn "addsi_1_zext"
5624 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5625 (zero_extend:DI
5626 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5627 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5628 (clobber (reg:CC FLAGS_REG))]
5629 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5630 {
5631 switch (get_attr_type (insn))
5632 {
5633 case TYPE_LEA:
5634 return "#";
5635
5636 case TYPE_INCDEC:
5637 if (operands[2] == const1_rtx)
5638 return "inc{l}\t%k0";
5639 else
5640 {
5641 gcc_assert (operands[2] == constm1_rtx);
5642 return "dec{l}\t%k0";
5643 }
5644
5645 default:
5646 /* For most processors, ADD is faster than LEA. This alternative
5647 was added to use ADD as much as possible. */
5648 if (which_alternative == 1)
5649 {
5650 rtx tmp;
5651 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5652 }
5653
5654 if (x86_maybe_negate_const_int (&operands[2], SImode))
5655 return "sub{l}\t{%2, %k0|%k0, %2}";
5656
5657 return "add{l}\t{%2, %k0|%k0, %2}";
5658 }
5659 }
5660 [(set (attr "type")
5661 (cond [(eq_attr "alternative" "2")
5662 (const_string "lea")
5663 (match_operand:SI 2 "incdec_operand" "")
5664 (const_string "incdec")
5665 ]
5666 (const_string "alu")))
5667 (set (attr "length_immediate")
5668 (if_then_else
5669 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5670 (const_string "1")
5671 (const_string "*")))
5672 (set_attr "mode" "SI")])
5673
5674 (define_insn "*addhi_1"
5675 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5676 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5677 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5678 (clobber (reg:CC FLAGS_REG))]
5679 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5680 {
5681 switch (get_attr_type (insn))
5682 {
5683 case TYPE_LEA:
5684 return "#";
5685
5686 case TYPE_INCDEC:
5687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5688 if (operands[2] == const1_rtx)
5689 return "inc{w}\t%0";
5690 else
5691 {
5692 gcc_assert (operands[2] == constm1_rtx);
5693 return "dec{w}\t%0";
5694 }
5695
5696 default:
5697 /* For most processors, ADD is faster than LEA. This alternative
5698 was added to use ADD as much as possible. */
5699 if (which_alternative == 2)
5700 {
5701 rtx tmp;
5702 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5703 }
5704
5705 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5706 if (x86_maybe_negate_const_int (&operands[2], HImode))
5707 return "sub{w}\t{%2, %0|%0, %2}";
5708
5709 return "add{w}\t{%2, %0|%0, %2}";
5710 }
5711 }
5712 [(set (attr "type")
5713 (cond [(eq_attr "alternative" "3")
5714 (const_string "lea")
5715 (match_operand:HI 2 "incdec_operand" "")
5716 (const_string "incdec")
5717 ]
5718 (const_string "alu")))
5719 (set (attr "length_immediate")
5720 (if_then_else
5721 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5722 (const_string "1")
5723 (const_string "*")))
5724 (set_attr "mode" "HI,HI,HI,SI")])
5725
5726 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5727 (define_insn "*addqi_1"
5728 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5729 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5730 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5731 (clobber (reg:CC FLAGS_REG))]
5732 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5733 {
5734 bool widen = (which_alternative == 3 || which_alternative == 4);
5735
5736 switch (get_attr_type (insn))
5737 {
5738 case TYPE_LEA:
5739 return "#";
5740
5741 case TYPE_INCDEC:
5742 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5743 if (operands[2] == const1_rtx)
5744 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5745 else
5746 {
5747 gcc_assert (operands[2] == constm1_rtx);
5748 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5749 }
5750
5751 default:
5752 /* For most processors, ADD is faster than LEA. These alternatives
5753 were added to use ADD as much as possible. */
5754 if (which_alternative == 2 || which_alternative == 4)
5755 {
5756 rtx tmp;
5757 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5758 }
5759
5760 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5761 if (x86_maybe_negate_const_int (&operands[2], QImode))
5762 {
5763 if (widen)
5764 return "sub{l}\t{%2, %k0|%k0, %2}";
5765 else
5766 return "sub{b}\t{%2, %0|%0, %2}";
5767 }
5768 if (widen)
5769 return "add{l}\t{%k2, %k0|%k0, %k2}";
5770 else
5771 return "add{b}\t{%2, %0|%0, %2}";
5772 }
5773 }
5774 [(set (attr "type")
5775 (cond [(eq_attr "alternative" "5")
5776 (const_string "lea")
5777 (match_operand:QI 2 "incdec_operand" "")
5778 (const_string "incdec")
5779 ]
5780 (const_string "alu")))
5781 (set (attr "length_immediate")
5782 (if_then_else
5783 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5784 (const_string "1")
5785 (const_string "*")))
5786 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5787
5788 (define_insn "*addqi_1_slp"
5789 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5790 (plus:QI (match_dup 0)
5791 (match_operand:QI 1 "general_operand" "qn,qm")))
5792 (clobber (reg:CC FLAGS_REG))]
5793 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5794 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5795 {
5796 switch (get_attr_type (insn))
5797 {
5798 case TYPE_INCDEC:
5799 if (operands[1] == const1_rtx)
5800 return "inc{b}\t%0";
5801 else
5802 {
5803 gcc_assert (operands[1] == constm1_rtx);
5804 return "dec{b}\t%0";
5805 }
5806
5807 default:
5808 if (x86_maybe_negate_const_int (&operands[1], QImode))
5809 return "sub{b}\t{%1, %0|%0, %1}";
5810
5811 return "add{b}\t{%1, %0|%0, %1}";
5812 }
5813 }
5814 [(set (attr "type")
5815 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5816 (const_string "incdec")
5817 (const_string "alu1")))
5818 (set (attr "memory")
5819 (if_then_else (match_operand 1 "memory_operand" "")
5820 (const_string "load")
5821 (const_string "none")))
5822 (set_attr "mode" "QI")])
5823
5824 ;; Split non destructive adds if we cannot use lea.
5825 (define_split
5826 [(set (match_operand:SWI48 0 "register_operand" "")
5827 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5828 (match_operand:SWI48 2 "nonmemory_operand" "")))
5829 (clobber (reg:CC FLAGS_REG))]
5830 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5831 [(set (match_dup 0) (match_dup 1))
5832 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5833 (clobber (reg:CC FLAGS_REG))])])
5834
5835 ;; Convert add to the lea pattern to avoid flags dependency.
5836 (define_split
5837 [(set (match_operand:SWI 0 "register_operand" "")
5838 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5839 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5840 (clobber (reg:CC FLAGS_REG))]
5841 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5842 [(const_int 0)]
5843 {
5844 enum machine_mode mode = <MODE>mode;
5845 rtx pat;
5846
5847 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5848 {
5849 mode = SImode;
5850 operands[0] = gen_lowpart (mode, operands[0]);
5851 operands[1] = gen_lowpart (mode, operands[1]);
5852 operands[2] = gen_lowpart (mode, operands[2]);
5853 }
5854
5855 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5856
5857 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5858 DONE;
5859 })
5860
5861 ;; Convert add to the lea pattern to avoid flags dependency.
5862 (define_split
5863 [(set (match_operand:DI 0 "register_operand" "")
5864 (zero_extend:DI
5865 (plus:SI (match_operand:SI 1 "register_operand" "")
5866 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5867 (clobber (reg:CC FLAGS_REG))]
5868 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5869 [(set (match_dup 0)
5870 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5871
5872 (define_insn "*add<mode>_2"
5873 [(set (reg FLAGS_REG)
5874 (compare
5875 (plus:SWI
5876 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5877 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5878 (const_int 0)))
5879 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5880 (plus:SWI (match_dup 1) (match_dup 2)))]
5881 "ix86_match_ccmode (insn, CCGOCmode)
5882 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5883 {
5884 switch (get_attr_type (insn))
5885 {
5886 case TYPE_INCDEC:
5887 if (operands[2] == const1_rtx)
5888 return "inc{<imodesuffix>}\t%0";
5889 else
5890 {
5891 gcc_assert (operands[2] == constm1_rtx);
5892 return "dec{<imodesuffix>}\t%0";
5893 }
5894
5895 default:
5896 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5897 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5898
5899 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5900 }
5901 }
5902 [(set (attr "type")
5903 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5904 (const_string "incdec")
5905 (const_string "alu")))
5906 (set (attr "length_immediate")
5907 (if_then_else
5908 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5909 (const_string "1")
5910 (const_string "*")))
5911 (set_attr "mode" "<MODE>")])
5912
5913 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5914 (define_insn "*addsi_2_zext"
5915 [(set (reg FLAGS_REG)
5916 (compare
5917 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5918 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5919 (const_int 0)))
5920 (set (match_operand:DI 0 "register_operand" "=r")
5921 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5922 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5923 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5924 {
5925 switch (get_attr_type (insn))
5926 {
5927 case TYPE_INCDEC:
5928 if (operands[2] == const1_rtx)
5929 return "inc{l}\t%k0";
5930 else
5931 {
5932 gcc_assert (operands[2] == constm1_rtx);
5933 return "dec{l}\t%k0";
5934 }
5935
5936 default:
5937 if (x86_maybe_negate_const_int (&operands[2], SImode))
5938 return "sub{l}\t{%2, %k0|%k0, %2}";
5939
5940 return "add{l}\t{%2, %k0|%k0, %2}";
5941 }
5942 }
5943 [(set (attr "type")
5944 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5945 (const_string "incdec")
5946 (const_string "alu")))
5947 (set (attr "length_immediate")
5948 (if_then_else
5949 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5950 (const_string "1")
5951 (const_string "*")))
5952 (set_attr "mode" "SI")])
5953
5954 (define_insn "*add<mode>_3"
5955 [(set (reg FLAGS_REG)
5956 (compare
5957 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5958 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5959 (clobber (match_scratch:SWI 0 "=<r>"))]
5960 "ix86_match_ccmode (insn, CCZmode)
5961 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5962 {
5963 switch (get_attr_type (insn))
5964 {
5965 case TYPE_INCDEC:
5966 if (operands[2] == const1_rtx)
5967 return "inc{<imodesuffix>}\t%0";
5968 else
5969 {
5970 gcc_assert (operands[2] == constm1_rtx);
5971 return "dec{<imodesuffix>}\t%0";
5972 }
5973
5974 default:
5975 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5976 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5977
5978 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5979 }
5980 }
5981 [(set (attr "type")
5982 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5983 (const_string "incdec")
5984 (const_string "alu")))
5985 (set (attr "length_immediate")
5986 (if_then_else
5987 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5988 (const_string "1")
5989 (const_string "*")))
5990 (set_attr "mode" "<MODE>")])
5991
5992 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5993 (define_insn "*addsi_3_zext"
5994 [(set (reg FLAGS_REG)
5995 (compare
5996 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5997 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5998 (set (match_operand:DI 0 "register_operand" "=r")
5999 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6000 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6001 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6002 {
6003 switch (get_attr_type (insn))
6004 {
6005 case TYPE_INCDEC:
6006 if (operands[2] == const1_rtx)
6007 return "inc{l}\t%k0";
6008 else
6009 {
6010 gcc_assert (operands[2] == constm1_rtx);
6011 return "dec{l}\t%k0";
6012 }
6013
6014 default:
6015 if (x86_maybe_negate_const_int (&operands[2], SImode))
6016 return "sub{l}\t{%2, %k0|%k0, %2}";
6017
6018 return "add{l}\t{%2, %k0|%k0, %2}";
6019 }
6020 }
6021 [(set (attr "type")
6022 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6023 (const_string "incdec")
6024 (const_string "alu")))
6025 (set (attr "length_immediate")
6026 (if_then_else
6027 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6028 (const_string "1")
6029 (const_string "*")))
6030 (set_attr "mode" "SI")])
6031
6032 ; For comparisons against 1, -1 and 128, we may generate better code
6033 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6034 ; is matched then. We can't accept general immediate, because for
6035 ; case of overflows, the result is messed up.
6036 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6037 ; only for comparisons not depending on it.
6038
6039 (define_insn "*adddi_4"
6040 [(set (reg FLAGS_REG)
6041 (compare
6042 (match_operand:DI 1 "nonimmediate_operand" "0")
6043 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6044 (clobber (match_scratch:DI 0 "=rm"))]
6045 "TARGET_64BIT
6046 && ix86_match_ccmode (insn, CCGCmode)"
6047 {
6048 switch (get_attr_type (insn))
6049 {
6050 case TYPE_INCDEC:
6051 if (operands[2] == constm1_rtx)
6052 return "inc{q}\t%0";
6053 else
6054 {
6055 gcc_assert (operands[2] == const1_rtx);
6056 return "dec{q}\t%0";
6057 }
6058
6059 default:
6060 if (x86_maybe_negate_const_int (&operands[2], DImode))
6061 return "add{q}\t{%2, %0|%0, %2}";
6062
6063 return "sub{q}\t{%2, %0|%0, %2}";
6064 }
6065 }
6066 [(set (attr "type")
6067 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6068 (const_string "incdec")
6069 (const_string "alu")))
6070 (set (attr "length_immediate")
6071 (if_then_else
6072 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6073 (const_string "1")
6074 (const_string "*")))
6075 (set_attr "mode" "DI")])
6076
6077 ; For comparisons against 1, -1 and 128, we may generate better code
6078 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6079 ; is matched then. We can't accept general immediate, because for
6080 ; case of overflows, the result is messed up.
6081 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6082 ; only for comparisons not depending on it.
6083
6084 (define_insn "*add<mode>_4"
6085 [(set (reg FLAGS_REG)
6086 (compare
6087 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6088 (match_operand:SWI124 2 "const_int_operand" "n")))
6089 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6090 "ix86_match_ccmode (insn, CCGCmode)"
6091 {
6092 switch (get_attr_type (insn))
6093 {
6094 case TYPE_INCDEC:
6095 if (operands[2] == constm1_rtx)
6096 return "inc{<imodesuffix>}\t%0";
6097 else
6098 {
6099 gcc_assert (operands[2] == const1_rtx);
6100 return "dec{<imodesuffix>}\t%0";
6101 }
6102
6103 default:
6104 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6105 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6106
6107 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6108 }
6109 }
6110 [(set (attr "type")
6111 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6112 (const_string "incdec")
6113 (const_string "alu")))
6114 (set (attr "length_immediate")
6115 (if_then_else
6116 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6117 (const_string "1")
6118 (const_string "*")))
6119 (set_attr "mode" "<MODE>")])
6120
6121 (define_insn "*add<mode>_5"
6122 [(set (reg FLAGS_REG)
6123 (compare
6124 (plus:SWI
6125 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6126 (match_operand:SWI 2 "<general_operand>" "<g>"))
6127 (const_int 0)))
6128 (clobber (match_scratch:SWI 0 "=<r>"))]
6129 "ix86_match_ccmode (insn, CCGOCmode)
6130 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6131 {
6132 switch (get_attr_type (insn))
6133 {
6134 case TYPE_INCDEC:
6135 if (operands[2] == const1_rtx)
6136 return "inc{<imodesuffix>}\t%0";
6137 else
6138 {
6139 gcc_assert (operands[2] == constm1_rtx);
6140 return "dec{<imodesuffix>}\t%0";
6141 }
6142
6143 default:
6144 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6145 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6146
6147 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6148 }
6149 }
6150 [(set (attr "type")
6151 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6152 (const_string "incdec")
6153 (const_string "alu")))
6154 (set (attr "length_immediate")
6155 (if_then_else
6156 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6157 (const_string "1")
6158 (const_string "*")))
6159 (set_attr "mode" "<MODE>")])
6160
6161 (define_insn "*addqi_ext_1_rex64"
6162 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6163 (const_int 8)
6164 (const_int 8))
6165 (plus:SI
6166 (zero_extract:SI
6167 (match_operand 1 "ext_register_operand" "0")
6168 (const_int 8)
6169 (const_int 8))
6170 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6171 (clobber (reg:CC FLAGS_REG))]
6172 "TARGET_64BIT"
6173 {
6174 switch (get_attr_type (insn))
6175 {
6176 case TYPE_INCDEC:
6177 if (operands[2] == const1_rtx)
6178 return "inc{b}\t%h0";
6179 else
6180 {
6181 gcc_assert (operands[2] == constm1_rtx);
6182 return "dec{b}\t%h0";
6183 }
6184
6185 default:
6186 return "add{b}\t{%2, %h0|%h0, %2}";
6187 }
6188 }
6189 [(set (attr "type")
6190 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6191 (const_string "incdec")
6192 (const_string "alu")))
6193 (set_attr "modrm" "1")
6194 (set_attr "mode" "QI")])
6195
6196 (define_insn "addqi_ext_1"
6197 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6198 (const_int 8)
6199 (const_int 8))
6200 (plus:SI
6201 (zero_extract:SI
6202 (match_operand 1 "ext_register_operand" "0")
6203 (const_int 8)
6204 (const_int 8))
6205 (match_operand:QI 2 "general_operand" "Qmn")))
6206 (clobber (reg:CC FLAGS_REG))]
6207 "!TARGET_64BIT"
6208 {
6209 switch (get_attr_type (insn))
6210 {
6211 case TYPE_INCDEC:
6212 if (operands[2] == const1_rtx)
6213 return "inc{b}\t%h0";
6214 else
6215 {
6216 gcc_assert (operands[2] == constm1_rtx);
6217 return "dec{b}\t%h0";
6218 }
6219
6220 default:
6221 return "add{b}\t{%2, %h0|%h0, %2}";
6222 }
6223 }
6224 [(set (attr "type")
6225 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6226 (const_string "incdec")
6227 (const_string "alu")))
6228 (set_attr "modrm" "1")
6229 (set_attr "mode" "QI")])
6230
6231 (define_insn "*addqi_ext_2"
6232 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6233 (const_int 8)
6234 (const_int 8))
6235 (plus:SI
6236 (zero_extract:SI
6237 (match_operand 1 "ext_register_operand" "%0")
6238 (const_int 8)
6239 (const_int 8))
6240 (zero_extract:SI
6241 (match_operand 2 "ext_register_operand" "Q")
6242 (const_int 8)
6243 (const_int 8))))
6244 (clobber (reg:CC FLAGS_REG))]
6245 ""
6246 "add{b}\t{%h2, %h0|%h0, %h2}"
6247 [(set_attr "type" "alu")
6248 (set_attr "mode" "QI")])
6249
6250 ;; The lea patterns for modes less than 32 bits need to be matched by
6251 ;; several insns converted to real lea by splitters.
6252
6253 (define_insn_and_split "*lea_general_1"
6254 [(set (match_operand 0 "register_operand" "=r")
6255 (plus (plus (match_operand 1 "index_register_operand" "l")
6256 (match_operand 2 "register_operand" "r"))
6257 (match_operand 3 "immediate_operand" "i")))]
6258 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6259 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6260 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6261 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6262 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6263 || GET_MODE (operands[3]) == VOIDmode)"
6264 "#"
6265 "&& reload_completed"
6266 [(const_int 0)]
6267 {
6268 enum machine_mode mode = SImode;
6269 rtx pat;
6270
6271 operands[0] = gen_lowpart (mode, operands[0]);
6272 operands[1] = gen_lowpart (mode, operands[1]);
6273 operands[2] = gen_lowpart (mode, operands[2]);
6274 operands[3] = gen_lowpart (mode, operands[3]);
6275
6276 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6277 operands[3]);
6278
6279 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6280 DONE;
6281 }
6282 [(set_attr "type" "lea")
6283 (set_attr "mode" "SI")])
6284
6285 (define_insn_and_split "*lea_general_2"
6286 [(set (match_operand 0 "register_operand" "=r")
6287 (plus (mult (match_operand 1 "index_register_operand" "l")
6288 (match_operand 2 "const248_operand" "n"))
6289 (match_operand 3 "nonmemory_operand" "ri")))]
6290 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6291 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6292 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6293 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6294 || GET_MODE (operands[3]) == VOIDmode)"
6295 "#"
6296 "&& reload_completed"
6297 [(const_int 0)]
6298 {
6299 enum machine_mode mode = SImode;
6300 rtx pat;
6301
6302 operands[0] = gen_lowpart (mode, operands[0]);
6303 operands[1] = gen_lowpart (mode, operands[1]);
6304 operands[3] = gen_lowpart (mode, operands[3]);
6305
6306 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6307 operands[3]);
6308
6309 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6310 DONE;
6311 }
6312 [(set_attr "type" "lea")
6313 (set_attr "mode" "SI")])
6314
6315 (define_insn_and_split "*lea_general_3"
6316 [(set (match_operand 0 "register_operand" "=r")
6317 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6318 (match_operand 2 "const248_operand" "n"))
6319 (match_operand 3 "register_operand" "r"))
6320 (match_operand 4 "immediate_operand" "i")))]
6321 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6322 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6323 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6324 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6325 "#"
6326 "&& reload_completed"
6327 [(const_int 0)]
6328 {
6329 enum machine_mode mode = SImode;
6330 rtx pat;
6331
6332 operands[0] = gen_lowpart (mode, operands[0]);
6333 operands[1] = gen_lowpart (mode, operands[1]);
6334 operands[3] = gen_lowpart (mode, operands[3]);
6335 operands[4] = gen_lowpart (mode, operands[4]);
6336
6337 pat = gen_rtx_PLUS (mode,
6338 gen_rtx_PLUS (mode,
6339 gen_rtx_MULT (mode, operands[1],
6340 operands[2]),
6341 operands[3]),
6342 operands[4]);
6343
6344 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6345 DONE;
6346 }
6347 [(set_attr "type" "lea")
6348 (set_attr "mode" "SI")])
6349
6350 (define_insn_and_split "*lea_general_4"
6351 [(set (match_operand 0 "register_operand" "=r")
6352 (any_or (ashift
6353 (match_operand 1 "index_register_operand" "l")
6354 (match_operand 2 "const_int_operand" "n"))
6355 (match_operand 3 "const_int_operand" "n")))]
6356 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6357 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6358 || GET_MODE (operands[0]) == SImode
6359 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6360 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6361 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6362 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6363 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6364 "#"
6365 "&& reload_completed"
6366 [(const_int 0)]
6367 {
6368 enum machine_mode mode = GET_MODE (operands[0]);
6369 rtx pat;
6370
6371 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6372 {
6373 mode = SImode;
6374 operands[0] = gen_lowpart (mode, operands[0]);
6375 operands[1] = gen_lowpart (mode, operands[1]);
6376 }
6377
6378 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6379
6380 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6381 INTVAL (operands[3]));
6382
6383 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6384 DONE;
6385 }
6386 [(set_attr "type" "lea")
6387 (set (attr "mode")
6388 (if_then_else (match_operand:DI 0 "" "")
6389 (const_string "DI")
6390 (const_string "SI")))])
6391 \f
6392 ;; Subtract instructions
6393
6394 (define_expand "sub<mode>3"
6395 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6396 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6397 (match_operand:SDWIM 2 "<general_operand>" "")))]
6398 ""
6399 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6400
6401 (define_insn_and_split "*sub<dwi>3_doubleword"
6402 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6403 (minus:<DWI>
6404 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6405 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6406 (clobber (reg:CC FLAGS_REG))]
6407 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6408 "#"
6409 "reload_completed"
6410 [(parallel [(set (reg:CC FLAGS_REG)
6411 (compare:CC (match_dup 1) (match_dup 2)))
6412 (set (match_dup 0)
6413 (minus:DWIH (match_dup 1) (match_dup 2)))])
6414 (parallel [(set (match_dup 3)
6415 (minus:DWIH
6416 (match_dup 4)
6417 (plus:DWIH
6418 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6419 (match_dup 5))))
6420 (clobber (reg:CC FLAGS_REG))])]
6421 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6422
6423 (define_insn "*sub<mode>_1"
6424 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6425 (minus:SWI
6426 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6427 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6428 (clobber (reg:CC FLAGS_REG))]
6429 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6430 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6431 [(set_attr "type" "alu")
6432 (set_attr "mode" "<MODE>")])
6433
6434 (define_insn "*subsi_1_zext"
6435 [(set (match_operand:DI 0 "register_operand" "=r")
6436 (zero_extend:DI
6437 (minus:SI (match_operand:SI 1 "register_operand" "0")
6438 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6439 (clobber (reg:CC FLAGS_REG))]
6440 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6441 "sub{l}\t{%2, %k0|%k0, %2}"
6442 [(set_attr "type" "alu")
6443 (set_attr "mode" "SI")])
6444
6445 (define_insn "*subqi_1_slp"
6446 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6447 (minus:QI (match_dup 0)
6448 (match_operand:QI 1 "general_operand" "qn,qm")))
6449 (clobber (reg:CC FLAGS_REG))]
6450 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6451 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6452 "sub{b}\t{%1, %0|%0, %1}"
6453 [(set_attr "type" "alu1")
6454 (set_attr "mode" "QI")])
6455
6456 (define_insn "*sub<mode>_2"
6457 [(set (reg FLAGS_REG)
6458 (compare
6459 (minus:SWI
6460 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6461 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6462 (const_int 0)))
6463 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6464 (minus:SWI (match_dup 1) (match_dup 2)))]
6465 "ix86_match_ccmode (insn, CCGOCmode)
6466 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6467 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6468 [(set_attr "type" "alu")
6469 (set_attr "mode" "<MODE>")])
6470
6471 (define_insn "*subsi_2_zext"
6472 [(set (reg FLAGS_REG)
6473 (compare
6474 (minus:SI (match_operand:SI 1 "register_operand" "0")
6475 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6476 (const_int 0)))
6477 (set (match_operand:DI 0 "register_operand" "=r")
6478 (zero_extend:DI
6479 (minus:SI (match_dup 1)
6480 (match_dup 2))))]
6481 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6482 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6483 "sub{l}\t{%2, %k0|%k0, %2}"
6484 [(set_attr "type" "alu")
6485 (set_attr "mode" "SI")])
6486
6487 (define_insn "*sub<mode>_3"
6488 [(set (reg FLAGS_REG)
6489 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6490 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6491 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6492 (minus:SWI (match_dup 1) (match_dup 2)))]
6493 "ix86_match_ccmode (insn, CCmode)
6494 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6495 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6496 [(set_attr "type" "alu")
6497 (set_attr "mode" "<MODE>")])
6498
6499 (define_insn "*subsi_3_zext"
6500 [(set (reg FLAGS_REG)
6501 (compare (match_operand:SI 1 "register_operand" "0")
6502 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6503 (set (match_operand:DI 0 "register_operand" "=r")
6504 (zero_extend:DI
6505 (minus:SI (match_dup 1)
6506 (match_dup 2))))]
6507 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6508 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6509 "sub{l}\t{%2, %1|%1, %2}"
6510 [(set_attr "type" "alu")
6511 (set_attr "mode" "SI")])
6512 \f
6513 ;; Add with carry and subtract with borrow
6514
6515 (define_expand "<plusminus_insn><mode>3_carry"
6516 [(parallel
6517 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6518 (plusminus:SWI
6519 (match_operand:SWI 1 "nonimmediate_operand" "")
6520 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6521 [(match_operand 3 "flags_reg_operand" "")
6522 (const_int 0)])
6523 (match_operand:SWI 2 "<general_operand>" ""))))
6524 (clobber (reg:CC FLAGS_REG))])]
6525 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6526
6527 (define_insn "*<plusminus_insn><mode>3_carry"
6528 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6529 (plusminus:SWI
6530 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6531 (plus:SWI
6532 (match_operator 3 "ix86_carry_flag_operator"
6533 [(reg FLAGS_REG) (const_int 0)])
6534 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6535 (clobber (reg:CC FLAGS_REG))]
6536 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6537 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6538 [(set_attr "type" "alu")
6539 (set_attr "use_carry" "1")
6540 (set_attr "pent_pair" "pu")
6541 (set_attr "mode" "<MODE>")])
6542
6543 (define_insn "*addsi3_carry_zext"
6544 [(set (match_operand:DI 0 "register_operand" "=r")
6545 (zero_extend:DI
6546 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6547 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6548 [(reg FLAGS_REG) (const_int 0)])
6549 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6550 (clobber (reg:CC FLAGS_REG))]
6551 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6552 "adc{l}\t{%2, %k0|%k0, %2}"
6553 [(set_attr "type" "alu")
6554 (set_attr "use_carry" "1")
6555 (set_attr "pent_pair" "pu")
6556 (set_attr "mode" "SI")])
6557
6558 (define_insn "*subsi3_carry_zext"
6559 [(set (match_operand:DI 0 "register_operand" "=r")
6560 (zero_extend:DI
6561 (minus:SI (match_operand:SI 1 "register_operand" "0")
6562 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6563 [(reg FLAGS_REG) (const_int 0)])
6564 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6565 (clobber (reg:CC FLAGS_REG))]
6566 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6567 "sbb{l}\t{%2, %k0|%k0, %2}"
6568 [(set_attr "type" "alu")
6569 (set_attr "pent_pair" "pu")
6570 (set_attr "mode" "SI")])
6571 \f
6572 ;; Overflow setting add and subtract instructions
6573
6574 (define_insn "*add<mode>3_cconly_overflow"
6575 [(set (reg:CCC FLAGS_REG)
6576 (compare:CCC
6577 (plus:SWI
6578 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6579 (match_operand:SWI 2 "<general_operand>" "<g>"))
6580 (match_dup 1)))
6581 (clobber (match_scratch:SWI 0 "=<r>"))]
6582 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6583 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6584 [(set_attr "type" "alu")
6585 (set_attr "mode" "<MODE>")])
6586
6587 (define_insn "*sub<mode>3_cconly_overflow"
6588 [(set (reg:CCC FLAGS_REG)
6589 (compare:CCC
6590 (minus:SWI
6591 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6592 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6593 (match_dup 0)))]
6594 ""
6595 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6596 [(set_attr "type" "icmp")
6597 (set_attr "mode" "<MODE>")])
6598
6599 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6600 [(set (reg:CCC FLAGS_REG)
6601 (compare:CCC
6602 (plusminus:SWI
6603 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6604 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6605 (match_dup 1)))
6606 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6607 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6608 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6609 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6610 [(set_attr "type" "alu")
6611 (set_attr "mode" "<MODE>")])
6612
6613 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6614 [(set (reg:CCC FLAGS_REG)
6615 (compare:CCC
6616 (plusminus:SI
6617 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6618 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6619 (match_dup 1)))
6620 (set (match_operand:DI 0 "register_operand" "=r")
6621 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6622 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6623 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6624 [(set_attr "type" "alu")
6625 (set_attr "mode" "SI")])
6626
6627 ;; The patterns that match these are at the end of this file.
6628
6629 (define_expand "<plusminus_insn>xf3"
6630 [(set (match_operand:XF 0 "register_operand" "")
6631 (plusminus:XF
6632 (match_operand:XF 1 "register_operand" "")
6633 (match_operand:XF 2 "register_operand" "")))]
6634 "TARGET_80387")
6635
6636 (define_expand "<plusminus_insn><mode>3"
6637 [(set (match_operand:MODEF 0 "register_operand" "")
6638 (plusminus:MODEF
6639 (match_operand:MODEF 1 "register_operand" "")
6640 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6641 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6642 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6643 \f
6644 ;; Multiply instructions
6645
6646 (define_expand "mul<mode>3"
6647 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6648 (mult:SWIM248
6649 (match_operand:SWIM248 1 "register_operand" "")
6650 (match_operand:SWIM248 2 "<general_operand>" "")))
6651 (clobber (reg:CC FLAGS_REG))])])
6652
6653 (define_expand "mulqi3"
6654 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6655 (mult:QI
6656 (match_operand:QI 1 "register_operand" "")
6657 (match_operand:QI 2 "nonimmediate_operand" "")))
6658 (clobber (reg:CC FLAGS_REG))])]
6659 "TARGET_QIMODE_MATH")
6660
6661 ;; On AMDFAM10
6662 ;; IMUL reg32/64, reg32/64, imm8 Direct
6663 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6664 ;; IMUL reg32/64, reg32/64, imm32 Direct
6665 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6666 ;; IMUL reg32/64, reg32/64 Direct
6667 ;; IMUL reg32/64, mem32/64 Direct
6668 ;;
6669 ;; On BDVER1, all above IMULs use DirectPath
6670
6671 (define_insn "*mul<mode>3_1"
6672 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6673 (mult:SWI48
6674 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6675 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6676 (clobber (reg:CC FLAGS_REG))]
6677 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6678 "@
6679 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6680 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6681 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6682 [(set_attr "type" "imul")
6683 (set_attr "prefix_0f" "0,0,1")
6684 (set (attr "athlon_decode")
6685 (cond [(eq_attr "cpu" "athlon")
6686 (const_string "vector")
6687 (eq_attr "alternative" "1")
6688 (const_string "vector")
6689 (and (eq_attr "alternative" "2")
6690 (match_operand 1 "memory_operand" ""))
6691 (const_string "vector")]
6692 (const_string "direct")))
6693 (set (attr "amdfam10_decode")
6694 (cond [(and (eq_attr "alternative" "0,1")
6695 (match_operand 1 "memory_operand" ""))
6696 (const_string "vector")]
6697 (const_string "direct")))
6698 (set_attr "bdver1_decode" "direct")
6699 (set_attr "mode" "<MODE>")])
6700
6701 (define_insn "*mulsi3_1_zext"
6702 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6703 (zero_extend:DI
6704 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6705 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6706 (clobber (reg:CC FLAGS_REG))]
6707 "TARGET_64BIT
6708 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6709 "@
6710 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6711 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6712 imul{l}\t{%2, %k0|%k0, %2}"
6713 [(set_attr "type" "imul")
6714 (set_attr "prefix_0f" "0,0,1")
6715 (set (attr "athlon_decode")
6716 (cond [(eq_attr "cpu" "athlon")
6717 (const_string "vector")
6718 (eq_attr "alternative" "1")
6719 (const_string "vector")
6720 (and (eq_attr "alternative" "2")
6721 (match_operand 1 "memory_operand" ""))
6722 (const_string "vector")]
6723 (const_string "direct")))
6724 (set (attr "amdfam10_decode")
6725 (cond [(and (eq_attr "alternative" "0,1")
6726 (match_operand 1 "memory_operand" ""))
6727 (const_string "vector")]
6728 (const_string "direct")))
6729 (set_attr "bdver1_decode" "direct")
6730 (set_attr "mode" "SI")])
6731
6732 ;; On AMDFAM10
6733 ;; IMUL reg16, reg16, imm8 VectorPath
6734 ;; IMUL reg16, mem16, imm8 VectorPath
6735 ;; IMUL reg16, reg16, imm16 VectorPath
6736 ;; IMUL reg16, mem16, imm16 VectorPath
6737 ;; IMUL reg16, reg16 Direct
6738 ;; IMUL reg16, mem16 Direct
6739 ;;
6740 ;; On BDVER1, all HI MULs use DoublePath
6741
6742 (define_insn "*mulhi3_1"
6743 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6744 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6745 (match_operand:HI 2 "general_operand" "K,n,mr")))
6746 (clobber (reg:CC FLAGS_REG))]
6747 "TARGET_HIMODE_MATH
6748 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6749 "@
6750 imul{w}\t{%2, %1, %0|%0, %1, %2}
6751 imul{w}\t{%2, %1, %0|%0, %1, %2}
6752 imul{w}\t{%2, %0|%0, %2}"
6753 [(set_attr "type" "imul")
6754 (set_attr "prefix_0f" "0,0,1")
6755 (set (attr "athlon_decode")
6756 (cond [(eq_attr "cpu" "athlon")
6757 (const_string "vector")
6758 (eq_attr "alternative" "1,2")
6759 (const_string "vector")]
6760 (const_string "direct")))
6761 (set (attr "amdfam10_decode")
6762 (cond [(eq_attr "alternative" "0,1")
6763 (const_string "vector")]
6764 (const_string "direct")))
6765 (set_attr "bdver1_decode" "double")
6766 (set_attr "mode" "HI")])
6767
6768 ;;On AMDFAM10 and BDVER1
6769 ;; MUL reg8 Direct
6770 ;; MUL mem8 Direct
6771
6772 (define_insn "*mulqi3_1"
6773 [(set (match_operand:QI 0 "register_operand" "=a")
6774 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6775 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6776 (clobber (reg:CC FLAGS_REG))]
6777 "TARGET_QIMODE_MATH
6778 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6779 "mul{b}\t%2"
6780 [(set_attr "type" "imul")
6781 (set_attr "length_immediate" "0")
6782 (set (attr "athlon_decode")
6783 (if_then_else (eq_attr "cpu" "athlon")
6784 (const_string "vector")
6785 (const_string "direct")))
6786 (set_attr "amdfam10_decode" "direct")
6787 (set_attr "bdver1_decode" "direct")
6788 (set_attr "mode" "QI")])
6789
6790 (define_expand "<u>mul<mode><dwi>3"
6791 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6792 (mult:<DWI>
6793 (any_extend:<DWI>
6794 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6795 (any_extend:<DWI>
6796 (match_operand:DWIH 2 "register_operand" ""))))
6797 (clobber (reg:CC FLAGS_REG))])])
6798
6799 (define_expand "<u>mulqihi3"
6800 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6801 (mult:HI
6802 (any_extend:HI
6803 (match_operand:QI 1 "nonimmediate_operand" ""))
6804 (any_extend:HI
6805 (match_operand:QI 2 "register_operand" ""))))
6806 (clobber (reg:CC FLAGS_REG))])]
6807 "TARGET_QIMODE_MATH")
6808
6809 (define_insn "*bmi2_umulditi3_1"
6810 [(set (match_operand:DI 0 "register_operand" "=r")
6811 (mult:DI
6812 (match_operand:DI 2 "nonimmediate_operand" "%d")
6813 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6814 (set (match_operand:DI 1 "register_operand" "=r")
6815 (truncate:DI
6816 (lshiftrt:TI
6817 (mult:TI (zero_extend:TI (match_dup 2))
6818 (zero_extend:TI (match_dup 3)))
6819 (const_int 64))))]
6820 "TARGET_64BIT && TARGET_BMI2
6821 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6822 "mulx\t{%3, %0, %1|%1, %0, %3}"
6823 [(set_attr "type" "imulx")
6824 (set_attr "prefix" "vex")
6825 (set_attr "mode" "DI")])
6826
6827 (define_insn "*bmi2_umulsidi3_1"
6828 [(set (match_operand:SI 0 "register_operand" "=r")
6829 (mult:SI
6830 (match_operand:SI 2 "nonimmediate_operand" "%d")
6831 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6832 (set (match_operand:SI 1 "register_operand" "=r")
6833 (truncate:SI
6834 (lshiftrt:DI
6835 (mult:DI (zero_extend:DI (match_dup 2))
6836 (zero_extend:DI (match_dup 3)))
6837 (const_int 32))))]
6838 "!TARGET_64BIT && TARGET_BMI2
6839 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6840 "mulx\t{%3, %0, %1|%1, %0, %3}"
6841 [(set_attr "type" "imulx")
6842 (set_attr "prefix" "vex")
6843 (set_attr "mode" "SI")])
6844
6845 (define_insn "*umul<mode><dwi>3_1"
6846 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6847 (mult:<DWI>
6848 (zero_extend:<DWI>
6849 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6850 (zero_extend:<DWI>
6851 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6852 (clobber (reg:CC FLAGS_REG))]
6853 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6854 "@
6855 mul{<imodesuffix>}\t%2
6856 #"
6857 [(set_attr "isa" "*,bmi2")
6858 (set_attr "type" "imul,imulx")
6859 (set_attr "length_immediate" "0,*")
6860 (set (attr "athlon_decode")
6861 (cond [(eq_attr "alternative" "0")
6862 (if_then_else (eq_attr "cpu" "athlon")
6863 (const_string "vector")
6864 (const_string "double"))]
6865 (const_string "*")))
6866 (set_attr "amdfam10_decode" "double,*")
6867 (set_attr "bdver1_decode" "direct,*")
6868 (set_attr "prefix" "orig,vex")
6869 (set_attr "mode" "<MODE>")])
6870
6871 ;; Convert mul to the mulx pattern to avoid flags dependency.
6872 (define_split
6873 [(set (match_operand:<DWI> 0 "register_operand" "")
6874 (mult:<DWI>
6875 (zero_extend:<DWI>
6876 (match_operand:DWIH 1 "register_operand" ""))
6877 (zero_extend:<DWI>
6878 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6879 (clobber (reg:CC FLAGS_REG))]
6880 "TARGET_BMI2 && reload_completed
6881 && true_regnum (operands[1]) == DX_REG"
6882 [(parallel [(set (match_dup 3)
6883 (mult:DWIH (match_dup 1) (match_dup 2)))
6884 (set (match_dup 4)
6885 (truncate:DWIH
6886 (lshiftrt:<DWI>
6887 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6888 (zero_extend:<DWI> (match_dup 2)))
6889 (match_dup 5))))])]
6890 {
6891 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6892
6893 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6894 })
6895
6896 (define_insn "*mul<mode><dwi>3_1"
6897 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6898 (mult:<DWI>
6899 (sign_extend:<DWI>
6900 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6901 (sign_extend:<DWI>
6902 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6903 (clobber (reg:CC FLAGS_REG))]
6904 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6905 "imul{<imodesuffix>}\t%2"
6906 [(set_attr "type" "imul")
6907 (set_attr "length_immediate" "0")
6908 (set (attr "athlon_decode")
6909 (if_then_else (eq_attr "cpu" "athlon")
6910 (const_string "vector")
6911 (const_string "double")))
6912 (set_attr "amdfam10_decode" "double")
6913 (set_attr "bdver1_decode" "direct")
6914 (set_attr "mode" "<MODE>")])
6915
6916 (define_insn "*<u>mulqihi3_1"
6917 [(set (match_operand:HI 0 "register_operand" "=a")
6918 (mult:HI
6919 (any_extend:HI
6920 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6921 (any_extend:HI
6922 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6923 (clobber (reg:CC FLAGS_REG))]
6924 "TARGET_QIMODE_MATH
6925 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6926 "<sgnprefix>mul{b}\t%2"
6927 [(set_attr "type" "imul")
6928 (set_attr "length_immediate" "0")
6929 (set (attr "athlon_decode")
6930 (if_then_else (eq_attr "cpu" "athlon")
6931 (const_string "vector")
6932 (const_string "direct")))
6933 (set_attr "amdfam10_decode" "direct")
6934 (set_attr "bdver1_decode" "direct")
6935 (set_attr "mode" "QI")])
6936
6937 (define_expand "<s>mul<mode>3_highpart"
6938 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6939 (truncate:SWI48
6940 (lshiftrt:<DWI>
6941 (mult:<DWI>
6942 (any_extend:<DWI>
6943 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6944 (any_extend:<DWI>
6945 (match_operand:SWI48 2 "register_operand" "")))
6946 (match_dup 4))))
6947 (clobber (match_scratch:SWI48 3 ""))
6948 (clobber (reg:CC FLAGS_REG))])]
6949 ""
6950 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6951
6952 (define_insn "*<s>muldi3_highpart_1"
6953 [(set (match_operand:DI 0 "register_operand" "=d")
6954 (truncate:DI
6955 (lshiftrt:TI
6956 (mult:TI
6957 (any_extend:TI
6958 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6959 (any_extend:TI
6960 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6961 (const_int 64))))
6962 (clobber (match_scratch:DI 3 "=1"))
6963 (clobber (reg:CC FLAGS_REG))]
6964 "TARGET_64BIT
6965 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6966 "<sgnprefix>mul{q}\t%2"
6967 [(set_attr "type" "imul")
6968 (set_attr "length_immediate" "0")
6969 (set (attr "athlon_decode")
6970 (if_then_else (eq_attr "cpu" "athlon")
6971 (const_string "vector")
6972 (const_string "double")))
6973 (set_attr "amdfam10_decode" "double")
6974 (set_attr "bdver1_decode" "direct")
6975 (set_attr "mode" "DI")])
6976
6977 (define_insn "*<s>mulsi3_highpart_1"
6978 [(set (match_operand:SI 0 "register_operand" "=d")
6979 (truncate:SI
6980 (lshiftrt:DI
6981 (mult:DI
6982 (any_extend:DI
6983 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6984 (any_extend:DI
6985 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6986 (const_int 32))))
6987 (clobber (match_scratch:SI 3 "=1"))
6988 (clobber (reg:CC FLAGS_REG))]
6989 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6990 "<sgnprefix>mul{l}\t%2"
6991 [(set_attr "type" "imul")
6992 (set_attr "length_immediate" "0")
6993 (set (attr "athlon_decode")
6994 (if_then_else (eq_attr "cpu" "athlon")
6995 (const_string "vector")
6996 (const_string "double")))
6997 (set_attr "amdfam10_decode" "double")
6998 (set_attr "bdver1_decode" "direct")
6999 (set_attr "mode" "SI")])
7000
7001 (define_insn "*<s>mulsi3_highpart_zext"
7002 [(set (match_operand:DI 0 "register_operand" "=d")
7003 (zero_extend:DI (truncate:SI
7004 (lshiftrt:DI
7005 (mult:DI (any_extend:DI
7006 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7007 (any_extend:DI
7008 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7009 (const_int 32)))))
7010 (clobber (match_scratch:SI 3 "=1"))
7011 (clobber (reg:CC FLAGS_REG))]
7012 "TARGET_64BIT
7013 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7014 "<sgnprefix>mul{l}\t%2"
7015 [(set_attr "type" "imul")
7016 (set_attr "length_immediate" "0")
7017 (set (attr "athlon_decode")
7018 (if_then_else (eq_attr "cpu" "athlon")
7019 (const_string "vector")
7020 (const_string "double")))
7021 (set_attr "amdfam10_decode" "double")
7022 (set_attr "bdver1_decode" "direct")
7023 (set_attr "mode" "SI")])
7024
7025 ;; The patterns that match these are at the end of this file.
7026
7027 (define_expand "mulxf3"
7028 [(set (match_operand:XF 0 "register_operand" "")
7029 (mult:XF (match_operand:XF 1 "register_operand" "")
7030 (match_operand:XF 2 "register_operand" "")))]
7031 "TARGET_80387")
7032
7033 (define_expand "mul<mode>3"
7034 [(set (match_operand:MODEF 0 "register_operand" "")
7035 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7036 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7037 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7038 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7039 \f
7040 ;; Divide instructions
7041
7042 ;; The patterns that match these are at the end of this file.
7043
7044 (define_expand "divxf3"
7045 [(set (match_operand:XF 0 "register_operand" "")
7046 (div:XF (match_operand:XF 1 "register_operand" "")
7047 (match_operand:XF 2 "register_operand" "")))]
7048 "TARGET_80387")
7049
7050 (define_expand "divdf3"
7051 [(set (match_operand:DF 0 "register_operand" "")
7052 (div:DF (match_operand:DF 1 "register_operand" "")
7053 (match_operand:DF 2 "nonimmediate_operand" "")))]
7054 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7055 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7056
7057 (define_expand "divsf3"
7058 [(set (match_operand:SF 0 "register_operand" "")
7059 (div:SF (match_operand:SF 1 "register_operand" "")
7060 (match_operand:SF 2 "nonimmediate_operand" "")))]
7061 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7062 || TARGET_SSE_MATH"
7063 {
7064 if (TARGET_SSE_MATH
7065 && TARGET_RECIP_DIV
7066 && optimize_insn_for_speed_p ()
7067 && flag_finite_math_only && !flag_trapping_math
7068 && flag_unsafe_math_optimizations)
7069 {
7070 ix86_emit_swdivsf (operands[0], operands[1],
7071 operands[2], SFmode);
7072 DONE;
7073 }
7074 })
7075 \f
7076 ;; Divmod instructions.
7077
7078 (define_expand "divmod<mode>4"
7079 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7080 (div:SWIM248
7081 (match_operand:SWIM248 1 "register_operand" "")
7082 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7083 (set (match_operand:SWIM248 3 "register_operand" "")
7084 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7085 (clobber (reg:CC FLAGS_REG))])])
7086
7087 ;; Split with 8bit unsigned divide:
7088 ;; if (dividend an divisor are in [0-255])
7089 ;; use 8bit unsigned integer divide
7090 ;; else
7091 ;; use original integer divide
7092 (define_split
7093 [(set (match_operand:SWI48 0 "register_operand" "")
7094 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7095 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7096 (set (match_operand:SWI48 1 "register_operand" "")
7097 (mod:SWI48 (match_dup 2) (match_dup 3)))
7098 (clobber (reg:CC FLAGS_REG))]
7099 "TARGET_USE_8BIT_IDIV
7100 && TARGET_QIMODE_MATH
7101 && can_create_pseudo_p ()
7102 && !optimize_insn_for_size_p ()"
7103 [(const_int 0)]
7104 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7105
7106 (define_insn_and_split "divmod<mode>4_1"
7107 [(set (match_operand:SWI48 0 "register_operand" "=a")
7108 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7109 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7110 (set (match_operand:SWI48 1 "register_operand" "=&d")
7111 (mod:SWI48 (match_dup 2) (match_dup 3)))
7112 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7113 (clobber (reg:CC FLAGS_REG))]
7114 ""
7115 "#"
7116 "reload_completed"
7117 [(parallel [(set (match_dup 1)
7118 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7119 (clobber (reg:CC FLAGS_REG))])
7120 (parallel [(set (match_dup 0)
7121 (div:SWI48 (match_dup 2) (match_dup 3)))
7122 (set (match_dup 1)
7123 (mod:SWI48 (match_dup 2) (match_dup 3)))
7124 (use (match_dup 1))
7125 (clobber (reg:CC FLAGS_REG))])]
7126 {
7127 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7128
7129 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7130 operands[4] = operands[2];
7131 else
7132 {
7133 /* Avoid use of cltd in favor of a mov+shift. */
7134 emit_move_insn (operands[1], operands[2]);
7135 operands[4] = operands[1];
7136 }
7137 }
7138 [(set_attr "type" "multi")
7139 (set_attr "mode" "<MODE>")])
7140
7141 (define_insn_and_split "*divmod<mode>4"
7142 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7143 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7144 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7145 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7146 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7147 (clobber (reg:CC FLAGS_REG))]
7148 ""
7149 "#"
7150 "reload_completed"
7151 [(parallel [(set (match_dup 1)
7152 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7153 (clobber (reg:CC FLAGS_REG))])
7154 (parallel [(set (match_dup 0)
7155 (div:SWIM248 (match_dup 2) (match_dup 3)))
7156 (set (match_dup 1)
7157 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7158 (use (match_dup 1))
7159 (clobber (reg:CC FLAGS_REG))])]
7160 {
7161 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7162
7163 if (<MODE>mode != HImode
7164 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7165 operands[4] = operands[2];
7166 else
7167 {
7168 /* Avoid use of cltd in favor of a mov+shift. */
7169 emit_move_insn (operands[1], operands[2]);
7170 operands[4] = operands[1];
7171 }
7172 }
7173 [(set_attr "type" "multi")
7174 (set_attr "mode" "<MODE>")])
7175
7176 (define_insn "*divmod<mode>4_noext"
7177 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7178 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7179 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7180 (set (match_operand:SWIM248 1 "register_operand" "=d")
7181 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7182 (use (match_operand:SWIM248 4 "register_operand" "1"))
7183 (clobber (reg:CC FLAGS_REG))]
7184 ""
7185 "idiv{<imodesuffix>}\t%3"
7186 [(set_attr "type" "idiv")
7187 (set_attr "mode" "<MODE>")])
7188
7189 (define_expand "divmodqi4"
7190 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7191 (div:QI
7192 (match_operand:QI 1 "register_operand" "")
7193 (match_operand:QI 2 "nonimmediate_operand" "")))
7194 (set (match_operand:QI 3 "register_operand" "")
7195 (mod:QI (match_dup 1) (match_dup 2)))
7196 (clobber (reg:CC FLAGS_REG))])]
7197 "TARGET_QIMODE_MATH"
7198 {
7199 rtx div, mod, insn;
7200 rtx tmp0, tmp1;
7201
7202 tmp0 = gen_reg_rtx (HImode);
7203 tmp1 = gen_reg_rtx (HImode);
7204
7205 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7206 in AX. */
7207 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7208 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7209
7210 /* Extract remainder from AH. */
7211 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7212 insn = emit_move_insn (operands[3], tmp1);
7213
7214 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7215 set_unique_reg_note (insn, REG_EQUAL, mod);
7216
7217 /* Extract quotient from AL. */
7218 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7219
7220 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7221 set_unique_reg_note (insn, REG_EQUAL, div);
7222
7223 DONE;
7224 })
7225
7226 ;; Divide AX by r/m8, with result stored in
7227 ;; AL <- Quotient
7228 ;; AH <- Remainder
7229 ;; Change div/mod to HImode and extend the second argument to HImode
7230 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7231 ;; combine may fail.
7232 (define_insn "divmodhiqi3"
7233 [(set (match_operand:HI 0 "register_operand" "=a")
7234 (ior:HI
7235 (ashift:HI
7236 (zero_extend:HI
7237 (truncate:QI
7238 (mod:HI (match_operand:HI 1 "register_operand" "0")
7239 (sign_extend:HI
7240 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7241 (const_int 8))
7242 (zero_extend:HI
7243 (truncate:QI
7244 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7245 (clobber (reg:CC FLAGS_REG))]
7246 "TARGET_QIMODE_MATH"
7247 "idiv{b}\t%2"
7248 [(set_attr "type" "idiv")
7249 (set_attr "mode" "QI")])
7250
7251 (define_expand "udivmod<mode>4"
7252 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7253 (udiv:SWIM248
7254 (match_operand:SWIM248 1 "register_operand" "")
7255 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7256 (set (match_operand:SWIM248 3 "register_operand" "")
7257 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7258 (clobber (reg:CC FLAGS_REG))])])
7259
7260 ;; Split with 8bit unsigned divide:
7261 ;; if (dividend an divisor are in [0-255])
7262 ;; use 8bit unsigned integer divide
7263 ;; else
7264 ;; use original integer divide
7265 (define_split
7266 [(set (match_operand:SWI48 0 "register_operand" "")
7267 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7268 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7269 (set (match_operand:SWI48 1 "register_operand" "")
7270 (umod:SWI48 (match_dup 2) (match_dup 3)))
7271 (clobber (reg:CC FLAGS_REG))]
7272 "TARGET_USE_8BIT_IDIV
7273 && TARGET_QIMODE_MATH
7274 && can_create_pseudo_p ()
7275 && !optimize_insn_for_size_p ()"
7276 [(const_int 0)]
7277 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7278
7279 (define_insn_and_split "udivmod<mode>4_1"
7280 [(set (match_operand:SWI48 0 "register_operand" "=a")
7281 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7282 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7283 (set (match_operand:SWI48 1 "register_operand" "=&d")
7284 (umod:SWI48 (match_dup 2) (match_dup 3)))
7285 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7286 (clobber (reg:CC FLAGS_REG))]
7287 ""
7288 "#"
7289 "reload_completed"
7290 [(set (match_dup 1) (const_int 0))
7291 (parallel [(set (match_dup 0)
7292 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7293 (set (match_dup 1)
7294 (umod:SWI48 (match_dup 2) (match_dup 3)))
7295 (use (match_dup 1))
7296 (clobber (reg:CC FLAGS_REG))])]
7297 ""
7298 [(set_attr "type" "multi")
7299 (set_attr "mode" "<MODE>")])
7300
7301 (define_insn_and_split "*udivmod<mode>4"
7302 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7303 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7304 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7305 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7306 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7307 (clobber (reg:CC FLAGS_REG))]
7308 ""
7309 "#"
7310 "reload_completed"
7311 [(set (match_dup 1) (const_int 0))
7312 (parallel [(set (match_dup 0)
7313 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7314 (set (match_dup 1)
7315 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7316 (use (match_dup 1))
7317 (clobber (reg:CC FLAGS_REG))])]
7318 ""
7319 [(set_attr "type" "multi")
7320 (set_attr "mode" "<MODE>")])
7321
7322 (define_insn "*udivmod<mode>4_noext"
7323 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7324 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7325 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7326 (set (match_operand:SWIM248 1 "register_operand" "=d")
7327 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7328 (use (match_operand:SWIM248 4 "register_operand" "1"))
7329 (clobber (reg:CC FLAGS_REG))]
7330 ""
7331 "div{<imodesuffix>}\t%3"
7332 [(set_attr "type" "idiv")
7333 (set_attr "mode" "<MODE>")])
7334
7335 (define_expand "udivmodqi4"
7336 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7337 (udiv:QI
7338 (match_operand:QI 1 "register_operand" "")
7339 (match_operand:QI 2 "nonimmediate_operand" "")))
7340 (set (match_operand:QI 3 "register_operand" "")
7341 (umod:QI (match_dup 1) (match_dup 2)))
7342 (clobber (reg:CC FLAGS_REG))])]
7343 "TARGET_QIMODE_MATH"
7344 {
7345 rtx div, mod, insn;
7346 rtx tmp0, tmp1;
7347
7348 tmp0 = gen_reg_rtx (HImode);
7349 tmp1 = gen_reg_rtx (HImode);
7350
7351 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7352 in AX. */
7353 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7354 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7355
7356 /* Extract remainder from AH. */
7357 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7358 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7359 insn = emit_move_insn (operands[3], tmp1);
7360
7361 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7362 set_unique_reg_note (insn, REG_EQUAL, mod);
7363
7364 /* Extract quotient from AL. */
7365 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7366
7367 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7368 set_unique_reg_note (insn, REG_EQUAL, div);
7369
7370 DONE;
7371 })
7372
7373 (define_insn "udivmodhiqi3"
7374 [(set (match_operand:HI 0 "register_operand" "=a")
7375 (ior:HI
7376 (ashift:HI
7377 (zero_extend:HI
7378 (truncate:QI
7379 (mod:HI (match_operand:HI 1 "register_operand" "0")
7380 (zero_extend:HI
7381 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7382 (const_int 8))
7383 (zero_extend:HI
7384 (truncate:QI
7385 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7386 (clobber (reg:CC FLAGS_REG))]
7387 "TARGET_QIMODE_MATH"
7388 "div{b}\t%2"
7389 [(set_attr "type" "idiv")
7390 (set_attr "mode" "QI")])
7391
7392 ;; We cannot use div/idiv for double division, because it causes
7393 ;; "division by zero" on the overflow and that's not what we expect
7394 ;; from truncate. Because true (non truncating) double division is
7395 ;; never generated, we can't create this insn anyway.
7396 ;
7397 ;(define_insn ""
7398 ; [(set (match_operand:SI 0 "register_operand" "=a")
7399 ; (truncate:SI
7400 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7401 ; (zero_extend:DI
7402 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7403 ; (set (match_operand:SI 3 "register_operand" "=d")
7404 ; (truncate:SI
7405 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7406 ; (clobber (reg:CC FLAGS_REG))]
7407 ; ""
7408 ; "div{l}\t{%2, %0|%0, %2}"
7409 ; [(set_attr "type" "idiv")])
7410 \f
7411 ;;- Logical AND instructions
7412
7413 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7414 ;; Note that this excludes ah.
7415
7416 (define_expand "testsi_ccno_1"
7417 [(set (reg:CCNO FLAGS_REG)
7418 (compare:CCNO
7419 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7420 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7421 (const_int 0)))])
7422
7423 (define_expand "testqi_ccz_1"
7424 [(set (reg:CCZ FLAGS_REG)
7425 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7426 (match_operand:QI 1 "nonmemory_operand" ""))
7427 (const_int 0)))])
7428
7429 (define_expand "testdi_ccno_1"
7430 [(set (reg:CCNO FLAGS_REG)
7431 (compare:CCNO
7432 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7433 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7434 (const_int 0)))]
7435 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7436
7437 (define_insn "*testdi_1"
7438 [(set (reg FLAGS_REG)
7439 (compare
7440 (and:DI
7441 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7442 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7443 (const_int 0)))]
7444 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7445 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7446 "@
7447 test{l}\t{%k1, %k0|%k0, %k1}
7448 test{l}\t{%k1, %k0|%k0, %k1}
7449 test{q}\t{%1, %0|%0, %1}
7450 test{q}\t{%1, %0|%0, %1}
7451 test{q}\t{%1, %0|%0, %1}"
7452 [(set_attr "type" "test")
7453 (set_attr "modrm" "0,1,0,1,1")
7454 (set_attr "mode" "SI,SI,DI,DI,DI")])
7455
7456 (define_insn "*testqi_1_maybe_si"
7457 [(set (reg FLAGS_REG)
7458 (compare
7459 (and:QI
7460 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7461 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7462 (const_int 0)))]
7463 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7464 && ix86_match_ccmode (insn,
7465 CONST_INT_P (operands[1])
7466 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7467 {
7468 if (which_alternative == 3)
7469 {
7470 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7471 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7472 return "test{l}\t{%1, %k0|%k0, %1}";
7473 }
7474 return "test{b}\t{%1, %0|%0, %1}";
7475 }
7476 [(set_attr "type" "test")
7477 (set_attr "modrm" "0,1,1,1")
7478 (set_attr "mode" "QI,QI,QI,SI")
7479 (set_attr "pent_pair" "uv,np,uv,np")])
7480
7481 (define_insn "*test<mode>_1"
7482 [(set (reg FLAGS_REG)
7483 (compare
7484 (and:SWI124
7485 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7486 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7487 (const_int 0)))]
7488 "ix86_match_ccmode (insn, CCNOmode)
7489 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7490 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7491 [(set_attr "type" "test")
7492 (set_attr "modrm" "0,1,1")
7493 (set_attr "mode" "<MODE>")
7494 (set_attr "pent_pair" "uv,np,uv")])
7495
7496 (define_expand "testqi_ext_ccno_0"
7497 [(set (reg:CCNO FLAGS_REG)
7498 (compare:CCNO
7499 (and:SI
7500 (zero_extract:SI
7501 (match_operand 0 "ext_register_operand" "")
7502 (const_int 8)
7503 (const_int 8))
7504 (match_operand 1 "const_int_operand" ""))
7505 (const_int 0)))])
7506
7507 (define_insn "*testqi_ext_0"
7508 [(set (reg FLAGS_REG)
7509 (compare
7510 (and:SI
7511 (zero_extract:SI
7512 (match_operand 0 "ext_register_operand" "Q")
7513 (const_int 8)
7514 (const_int 8))
7515 (match_operand 1 "const_int_operand" "n"))
7516 (const_int 0)))]
7517 "ix86_match_ccmode (insn, CCNOmode)"
7518 "test{b}\t{%1, %h0|%h0, %1}"
7519 [(set_attr "type" "test")
7520 (set_attr "mode" "QI")
7521 (set_attr "length_immediate" "1")
7522 (set_attr "modrm" "1")
7523 (set_attr "pent_pair" "np")])
7524
7525 (define_insn "*testqi_ext_1_rex64"
7526 [(set (reg FLAGS_REG)
7527 (compare
7528 (and:SI
7529 (zero_extract:SI
7530 (match_operand 0 "ext_register_operand" "Q")
7531 (const_int 8)
7532 (const_int 8))
7533 (zero_extend:SI
7534 (match_operand:QI 1 "register_operand" "Q")))
7535 (const_int 0)))]
7536 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7537 "test{b}\t{%1, %h0|%h0, %1}"
7538 [(set_attr "type" "test")
7539 (set_attr "mode" "QI")])
7540
7541 (define_insn "*testqi_ext_1"
7542 [(set (reg FLAGS_REG)
7543 (compare
7544 (and:SI
7545 (zero_extract:SI
7546 (match_operand 0 "ext_register_operand" "Q")
7547 (const_int 8)
7548 (const_int 8))
7549 (zero_extend:SI
7550 (match_operand:QI 1 "general_operand" "Qm")))
7551 (const_int 0)))]
7552 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7553 "test{b}\t{%1, %h0|%h0, %1}"
7554 [(set_attr "type" "test")
7555 (set_attr "mode" "QI")])
7556
7557 (define_insn "*testqi_ext_2"
7558 [(set (reg FLAGS_REG)
7559 (compare
7560 (and:SI
7561 (zero_extract:SI
7562 (match_operand 0 "ext_register_operand" "Q")
7563 (const_int 8)
7564 (const_int 8))
7565 (zero_extract:SI
7566 (match_operand 1 "ext_register_operand" "Q")
7567 (const_int 8)
7568 (const_int 8)))
7569 (const_int 0)))]
7570 "ix86_match_ccmode (insn, CCNOmode)"
7571 "test{b}\t{%h1, %h0|%h0, %h1}"
7572 [(set_attr "type" "test")
7573 (set_attr "mode" "QI")])
7574
7575 (define_insn "*testqi_ext_3_rex64"
7576 [(set (reg FLAGS_REG)
7577 (compare (zero_extract:DI
7578 (match_operand 0 "nonimmediate_operand" "rm")
7579 (match_operand:DI 1 "const_int_operand" "")
7580 (match_operand:DI 2 "const_int_operand" ""))
7581 (const_int 0)))]
7582 "TARGET_64BIT
7583 && ix86_match_ccmode (insn, CCNOmode)
7584 && INTVAL (operands[1]) > 0
7585 && INTVAL (operands[2]) >= 0
7586 /* Ensure that resulting mask is zero or sign extended operand. */
7587 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7588 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7589 && INTVAL (operands[1]) > 32))
7590 && (GET_MODE (operands[0]) == SImode
7591 || GET_MODE (operands[0]) == DImode
7592 || GET_MODE (operands[0]) == HImode
7593 || GET_MODE (operands[0]) == QImode)"
7594 "#")
7595
7596 ;; Combine likes to form bit extractions for some tests. Humor it.
7597 (define_insn "*testqi_ext_3"
7598 [(set (reg FLAGS_REG)
7599 (compare (zero_extract:SI
7600 (match_operand 0 "nonimmediate_operand" "rm")
7601 (match_operand:SI 1 "const_int_operand" "")
7602 (match_operand:SI 2 "const_int_operand" ""))
7603 (const_int 0)))]
7604 "ix86_match_ccmode (insn, CCNOmode)
7605 && INTVAL (operands[1]) > 0
7606 && INTVAL (operands[2]) >= 0
7607 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7608 && (GET_MODE (operands[0]) == SImode
7609 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7610 || GET_MODE (operands[0]) == HImode
7611 || GET_MODE (operands[0]) == QImode)"
7612 "#")
7613
7614 (define_split
7615 [(set (match_operand 0 "flags_reg_operand" "")
7616 (match_operator 1 "compare_operator"
7617 [(zero_extract
7618 (match_operand 2 "nonimmediate_operand" "")
7619 (match_operand 3 "const_int_operand" "")
7620 (match_operand 4 "const_int_operand" ""))
7621 (const_int 0)]))]
7622 "ix86_match_ccmode (insn, CCNOmode)"
7623 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7624 {
7625 rtx val = operands[2];
7626 HOST_WIDE_INT len = INTVAL (operands[3]);
7627 HOST_WIDE_INT pos = INTVAL (operands[4]);
7628 HOST_WIDE_INT mask;
7629 enum machine_mode mode, submode;
7630
7631 mode = GET_MODE (val);
7632 if (MEM_P (val))
7633 {
7634 /* ??? Combine likes to put non-volatile mem extractions in QImode
7635 no matter the size of the test. So find a mode that works. */
7636 if (! MEM_VOLATILE_P (val))
7637 {
7638 mode = smallest_mode_for_size (pos + len, MODE_INT);
7639 val = adjust_address (val, mode, 0);
7640 }
7641 }
7642 else if (GET_CODE (val) == SUBREG
7643 && (submode = GET_MODE (SUBREG_REG (val)),
7644 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7645 && pos + len <= GET_MODE_BITSIZE (submode)
7646 && GET_MODE_CLASS (submode) == MODE_INT)
7647 {
7648 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7649 mode = submode;
7650 val = SUBREG_REG (val);
7651 }
7652 else if (mode == HImode && pos + len <= 8)
7653 {
7654 /* Small HImode tests can be converted to QImode. */
7655 mode = QImode;
7656 val = gen_lowpart (QImode, val);
7657 }
7658
7659 if (len == HOST_BITS_PER_WIDE_INT)
7660 mask = -1;
7661 else
7662 mask = ((HOST_WIDE_INT)1 << len) - 1;
7663 mask <<= pos;
7664
7665 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7666 })
7667
7668 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7669 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7670 ;; this is relatively important trick.
7671 ;; Do the conversion only post-reload to avoid limiting of the register class
7672 ;; to QI regs.
7673 (define_split
7674 [(set (match_operand 0 "flags_reg_operand" "")
7675 (match_operator 1 "compare_operator"
7676 [(and (match_operand 2 "register_operand" "")
7677 (match_operand 3 "const_int_operand" ""))
7678 (const_int 0)]))]
7679 "reload_completed
7680 && QI_REG_P (operands[2])
7681 && GET_MODE (operands[2]) != QImode
7682 && ((ix86_match_ccmode (insn, CCZmode)
7683 && !(INTVAL (operands[3]) & ~(255 << 8)))
7684 || (ix86_match_ccmode (insn, CCNOmode)
7685 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7686 [(set (match_dup 0)
7687 (match_op_dup 1
7688 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7689 (match_dup 3))
7690 (const_int 0)]))]
7691 "operands[2] = gen_lowpart (SImode, operands[2]);
7692 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7693
7694 (define_split
7695 [(set (match_operand 0 "flags_reg_operand" "")
7696 (match_operator 1 "compare_operator"
7697 [(and (match_operand 2 "nonimmediate_operand" "")
7698 (match_operand 3 "const_int_operand" ""))
7699 (const_int 0)]))]
7700 "reload_completed
7701 && GET_MODE (operands[2]) != QImode
7702 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7703 && ((ix86_match_ccmode (insn, CCZmode)
7704 && !(INTVAL (operands[3]) & ~255))
7705 || (ix86_match_ccmode (insn, CCNOmode)
7706 && !(INTVAL (operands[3]) & ~127)))"
7707 [(set (match_dup 0)
7708 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7709 (const_int 0)]))]
7710 "operands[2] = gen_lowpart (QImode, operands[2]);
7711 operands[3] = gen_lowpart (QImode, operands[3]);")
7712
7713 ;; %%% This used to optimize known byte-wide and operations to memory,
7714 ;; and sometimes to QImode registers. If this is considered useful,
7715 ;; it should be done with splitters.
7716
7717 (define_expand "and<mode>3"
7718 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7719 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7720 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7721 ""
7722 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7723
7724 (define_insn "*anddi_1"
7725 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7726 (and:DI
7727 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7728 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7729 (clobber (reg:CC FLAGS_REG))]
7730 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7731 {
7732 switch (get_attr_type (insn))
7733 {
7734 case TYPE_IMOVX:
7735 {
7736 enum machine_mode mode;
7737
7738 gcc_assert (CONST_INT_P (operands[2]));
7739 if (INTVAL (operands[2]) == 0xff)
7740 mode = QImode;
7741 else
7742 {
7743 gcc_assert (INTVAL (operands[2]) == 0xffff);
7744 mode = HImode;
7745 }
7746
7747 operands[1] = gen_lowpart (mode, operands[1]);
7748 if (mode == QImode)
7749 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7750 else
7751 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7752 }
7753
7754 default:
7755 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7756 if (get_attr_mode (insn) == MODE_SI)
7757 return "and{l}\t{%k2, %k0|%k0, %k2}";
7758 else
7759 return "and{q}\t{%2, %0|%0, %2}";
7760 }
7761 }
7762 [(set_attr "type" "alu,alu,alu,imovx")
7763 (set_attr "length_immediate" "*,*,*,0")
7764 (set (attr "prefix_rex")
7765 (if_then_else
7766 (and (eq_attr "type" "imovx")
7767 (and (match_test "INTVAL (operands[2]) == 0xff")
7768 (match_operand 1 "ext_QIreg_operand" "")))
7769 (const_string "1")
7770 (const_string "*")))
7771 (set_attr "mode" "SI,DI,DI,SI")])
7772
7773 (define_insn "*andsi_1"
7774 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7775 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7776 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7777 (clobber (reg:CC FLAGS_REG))]
7778 "ix86_binary_operator_ok (AND, SImode, operands)"
7779 {
7780 switch (get_attr_type (insn))
7781 {
7782 case TYPE_IMOVX:
7783 {
7784 enum machine_mode mode;
7785
7786 gcc_assert (CONST_INT_P (operands[2]));
7787 if (INTVAL (operands[2]) == 0xff)
7788 mode = QImode;
7789 else
7790 {
7791 gcc_assert (INTVAL (operands[2]) == 0xffff);
7792 mode = HImode;
7793 }
7794
7795 operands[1] = gen_lowpart (mode, operands[1]);
7796 if (mode == QImode)
7797 return "movz{bl|x}\t{%1, %0|%0, %1}";
7798 else
7799 return "movz{wl|x}\t{%1, %0|%0, %1}";
7800 }
7801
7802 default:
7803 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7804 return "and{l}\t{%2, %0|%0, %2}";
7805 }
7806 }
7807 [(set_attr "type" "alu,alu,imovx")
7808 (set (attr "prefix_rex")
7809 (if_then_else
7810 (and (eq_attr "type" "imovx")
7811 (and (match_test "INTVAL (operands[2]) == 0xff")
7812 (match_operand 1 "ext_QIreg_operand" "")))
7813 (const_string "1")
7814 (const_string "*")))
7815 (set_attr "length_immediate" "*,*,0")
7816 (set_attr "mode" "SI")])
7817
7818 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7819 (define_insn "*andsi_1_zext"
7820 [(set (match_operand:DI 0 "register_operand" "=r")
7821 (zero_extend:DI
7822 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7823 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7824 (clobber (reg:CC FLAGS_REG))]
7825 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7826 "and{l}\t{%2, %k0|%k0, %2}"
7827 [(set_attr "type" "alu")
7828 (set_attr "mode" "SI")])
7829
7830 (define_insn "*andhi_1"
7831 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7832 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7833 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7834 (clobber (reg:CC FLAGS_REG))]
7835 "ix86_binary_operator_ok (AND, HImode, operands)"
7836 {
7837 switch (get_attr_type (insn))
7838 {
7839 case TYPE_IMOVX:
7840 gcc_assert (CONST_INT_P (operands[2]));
7841 gcc_assert (INTVAL (operands[2]) == 0xff);
7842 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7843
7844 default:
7845 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7846
7847 return "and{w}\t{%2, %0|%0, %2}";
7848 }
7849 }
7850 [(set_attr "type" "alu,alu,imovx")
7851 (set_attr "length_immediate" "*,*,0")
7852 (set (attr "prefix_rex")
7853 (if_then_else
7854 (and (eq_attr "type" "imovx")
7855 (match_operand 1 "ext_QIreg_operand" ""))
7856 (const_string "1")
7857 (const_string "*")))
7858 (set_attr "mode" "HI,HI,SI")])
7859
7860 ;; %%% Potential partial reg stall on alternative 2. What to do?
7861 (define_insn "*andqi_1"
7862 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7863 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7864 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7865 (clobber (reg:CC FLAGS_REG))]
7866 "ix86_binary_operator_ok (AND, QImode, operands)"
7867 "@
7868 and{b}\t{%2, %0|%0, %2}
7869 and{b}\t{%2, %0|%0, %2}
7870 and{l}\t{%k2, %k0|%k0, %k2}"
7871 [(set_attr "type" "alu")
7872 (set_attr "mode" "QI,QI,SI")])
7873
7874 (define_insn "*andqi_1_slp"
7875 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7876 (and:QI (match_dup 0)
7877 (match_operand:QI 1 "general_operand" "qn,qmn")))
7878 (clobber (reg:CC FLAGS_REG))]
7879 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7880 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7881 "and{b}\t{%1, %0|%0, %1}"
7882 [(set_attr "type" "alu1")
7883 (set_attr "mode" "QI")])
7884
7885 (define_split
7886 [(set (match_operand 0 "register_operand" "")
7887 (and (match_dup 0)
7888 (const_int -65536)))
7889 (clobber (reg:CC FLAGS_REG))]
7890 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7891 || optimize_function_for_size_p (cfun)"
7892 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7893 "operands[1] = gen_lowpart (HImode, operands[0]);")
7894
7895 (define_split
7896 [(set (match_operand 0 "ext_register_operand" "")
7897 (and (match_dup 0)
7898 (const_int -256)))
7899 (clobber (reg:CC FLAGS_REG))]
7900 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7901 && reload_completed"
7902 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7903 "operands[1] = gen_lowpart (QImode, operands[0]);")
7904
7905 (define_split
7906 [(set (match_operand 0 "ext_register_operand" "")
7907 (and (match_dup 0)
7908 (const_int -65281)))
7909 (clobber (reg:CC FLAGS_REG))]
7910 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7911 && reload_completed"
7912 [(parallel [(set (zero_extract:SI (match_dup 0)
7913 (const_int 8)
7914 (const_int 8))
7915 (xor:SI
7916 (zero_extract:SI (match_dup 0)
7917 (const_int 8)
7918 (const_int 8))
7919 (zero_extract:SI (match_dup 0)
7920 (const_int 8)
7921 (const_int 8))))
7922 (clobber (reg:CC FLAGS_REG))])]
7923 "operands[0] = gen_lowpart (SImode, operands[0]);")
7924
7925 (define_insn "*anddi_2"
7926 [(set (reg FLAGS_REG)
7927 (compare
7928 (and:DI
7929 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7930 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7931 (const_int 0)))
7932 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7933 (and:DI (match_dup 1) (match_dup 2)))]
7934 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7935 && ix86_binary_operator_ok (AND, DImode, operands)"
7936 "@
7937 and{l}\t{%k2, %k0|%k0, %k2}
7938 and{q}\t{%2, %0|%0, %2}
7939 and{q}\t{%2, %0|%0, %2}"
7940 [(set_attr "type" "alu")
7941 (set_attr "mode" "SI,DI,DI")])
7942
7943 (define_insn "*andqi_2_maybe_si"
7944 [(set (reg FLAGS_REG)
7945 (compare (and:QI
7946 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7947 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7948 (const_int 0)))
7949 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7950 (and:QI (match_dup 1) (match_dup 2)))]
7951 "ix86_binary_operator_ok (AND, QImode, operands)
7952 && ix86_match_ccmode (insn,
7953 CONST_INT_P (operands[2])
7954 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7955 {
7956 if (which_alternative == 2)
7957 {
7958 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7959 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7960 return "and{l}\t{%2, %k0|%k0, %2}";
7961 }
7962 return "and{b}\t{%2, %0|%0, %2}";
7963 }
7964 [(set_attr "type" "alu")
7965 (set_attr "mode" "QI,QI,SI")])
7966
7967 (define_insn "*and<mode>_2"
7968 [(set (reg FLAGS_REG)
7969 (compare (and:SWI124
7970 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7971 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7972 (const_int 0)))
7973 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7974 (and:SWI124 (match_dup 1) (match_dup 2)))]
7975 "ix86_match_ccmode (insn, CCNOmode)
7976 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7977 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7978 [(set_attr "type" "alu")
7979 (set_attr "mode" "<MODE>")])
7980
7981 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7982 (define_insn "*andsi_2_zext"
7983 [(set (reg FLAGS_REG)
7984 (compare (and:SI
7985 (match_operand:SI 1 "nonimmediate_operand" "%0")
7986 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7987 (const_int 0)))
7988 (set (match_operand:DI 0 "register_operand" "=r")
7989 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7990 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7991 && ix86_binary_operator_ok (AND, SImode, operands)"
7992 "and{l}\t{%2, %k0|%k0, %2}"
7993 [(set_attr "type" "alu")
7994 (set_attr "mode" "SI")])
7995
7996 (define_insn "*andqi_2_slp"
7997 [(set (reg FLAGS_REG)
7998 (compare (and:QI
7999 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8000 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8001 (const_int 0)))
8002 (set (strict_low_part (match_dup 0))
8003 (and:QI (match_dup 0) (match_dup 1)))]
8004 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8005 && ix86_match_ccmode (insn, CCNOmode)
8006 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8007 "and{b}\t{%1, %0|%0, %1}"
8008 [(set_attr "type" "alu1")
8009 (set_attr "mode" "QI")])
8010
8011 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8012 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8013 ;; for a QImode operand, which of course failed.
8014 (define_insn "andqi_ext_0"
8015 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8016 (const_int 8)
8017 (const_int 8))
8018 (and:SI
8019 (zero_extract:SI
8020 (match_operand 1 "ext_register_operand" "0")
8021 (const_int 8)
8022 (const_int 8))
8023 (match_operand 2 "const_int_operand" "n")))
8024 (clobber (reg:CC FLAGS_REG))]
8025 ""
8026 "and{b}\t{%2, %h0|%h0, %2}"
8027 [(set_attr "type" "alu")
8028 (set_attr "length_immediate" "1")
8029 (set_attr "modrm" "1")
8030 (set_attr "mode" "QI")])
8031
8032 ;; Generated by peephole translating test to and. This shows up
8033 ;; often in fp comparisons.
8034 (define_insn "*andqi_ext_0_cc"
8035 [(set (reg FLAGS_REG)
8036 (compare
8037 (and:SI
8038 (zero_extract:SI
8039 (match_operand 1 "ext_register_operand" "0")
8040 (const_int 8)
8041 (const_int 8))
8042 (match_operand 2 "const_int_operand" "n"))
8043 (const_int 0)))
8044 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8045 (const_int 8)
8046 (const_int 8))
8047 (and:SI
8048 (zero_extract:SI
8049 (match_dup 1)
8050 (const_int 8)
8051 (const_int 8))
8052 (match_dup 2)))]
8053 "ix86_match_ccmode (insn, CCNOmode)"
8054 "and{b}\t{%2, %h0|%h0, %2}"
8055 [(set_attr "type" "alu")
8056 (set_attr "length_immediate" "1")
8057 (set_attr "modrm" "1")
8058 (set_attr "mode" "QI")])
8059
8060 (define_insn "*andqi_ext_1_rex64"
8061 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8062 (const_int 8)
8063 (const_int 8))
8064 (and:SI
8065 (zero_extract:SI
8066 (match_operand 1 "ext_register_operand" "0")
8067 (const_int 8)
8068 (const_int 8))
8069 (zero_extend:SI
8070 (match_operand 2 "ext_register_operand" "Q"))))
8071 (clobber (reg:CC FLAGS_REG))]
8072 "TARGET_64BIT"
8073 "and{b}\t{%2, %h0|%h0, %2}"
8074 [(set_attr "type" "alu")
8075 (set_attr "length_immediate" "0")
8076 (set_attr "mode" "QI")])
8077
8078 (define_insn "*andqi_ext_1"
8079 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8080 (const_int 8)
8081 (const_int 8))
8082 (and:SI
8083 (zero_extract:SI
8084 (match_operand 1 "ext_register_operand" "0")
8085 (const_int 8)
8086 (const_int 8))
8087 (zero_extend:SI
8088 (match_operand:QI 2 "general_operand" "Qm"))))
8089 (clobber (reg:CC FLAGS_REG))]
8090 "!TARGET_64BIT"
8091 "and{b}\t{%2, %h0|%h0, %2}"
8092 [(set_attr "type" "alu")
8093 (set_attr "length_immediate" "0")
8094 (set_attr "mode" "QI")])
8095
8096 (define_insn "*andqi_ext_2"
8097 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8098 (const_int 8)
8099 (const_int 8))
8100 (and:SI
8101 (zero_extract:SI
8102 (match_operand 1 "ext_register_operand" "%0")
8103 (const_int 8)
8104 (const_int 8))
8105 (zero_extract:SI
8106 (match_operand 2 "ext_register_operand" "Q")
8107 (const_int 8)
8108 (const_int 8))))
8109 (clobber (reg:CC FLAGS_REG))]
8110 ""
8111 "and{b}\t{%h2, %h0|%h0, %h2}"
8112 [(set_attr "type" "alu")
8113 (set_attr "length_immediate" "0")
8114 (set_attr "mode" "QI")])
8115
8116 ;; Convert wide AND instructions with immediate operand to shorter QImode
8117 ;; equivalents when possible.
8118 ;; Don't do the splitting with memory operands, since it introduces risk
8119 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8120 ;; for size, but that can (should?) be handled by generic code instead.
8121 (define_split
8122 [(set (match_operand 0 "register_operand" "")
8123 (and (match_operand 1 "register_operand" "")
8124 (match_operand 2 "const_int_operand" "")))
8125 (clobber (reg:CC FLAGS_REG))]
8126 "reload_completed
8127 && QI_REG_P (operands[0])
8128 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8129 && !(~INTVAL (operands[2]) & ~(255 << 8))
8130 && GET_MODE (operands[0]) != QImode"
8131 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8132 (and:SI (zero_extract:SI (match_dup 1)
8133 (const_int 8) (const_int 8))
8134 (match_dup 2)))
8135 (clobber (reg:CC FLAGS_REG))])]
8136 "operands[0] = gen_lowpart (SImode, operands[0]);
8137 operands[1] = gen_lowpart (SImode, operands[1]);
8138 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8139
8140 ;; Since AND can be encoded with sign extended immediate, this is only
8141 ;; profitable when 7th bit is not set.
8142 (define_split
8143 [(set (match_operand 0 "register_operand" "")
8144 (and (match_operand 1 "general_operand" "")
8145 (match_operand 2 "const_int_operand" "")))
8146 (clobber (reg:CC FLAGS_REG))]
8147 "reload_completed
8148 && ANY_QI_REG_P (operands[0])
8149 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8150 && !(~INTVAL (operands[2]) & ~255)
8151 && !(INTVAL (operands[2]) & 128)
8152 && GET_MODE (operands[0]) != QImode"
8153 [(parallel [(set (strict_low_part (match_dup 0))
8154 (and:QI (match_dup 1)
8155 (match_dup 2)))
8156 (clobber (reg:CC FLAGS_REG))])]
8157 "operands[0] = gen_lowpart (QImode, operands[0]);
8158 operands[1] = gen_lowpart (QImode, operands[1]);
8159 operands[2] = gen_lowpart (QImode, operands[2]);")
8160 \f
8161 ;; Logical inclusive and exclusive OR instructions
8162
8163 ;; %%% This used to optimize known byte-wide and operations to memory.
8164 ;; If this is considered useful, it should be done with splitters.
8165
8166 (define_expand "<code><mode>3"
8167 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8168 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8169 (match_operand:SWIM 2 "<general_operand>" "")))]
8170 ""
8171 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8172
8173 (define_insn "*<code><mode>_1"
8174 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8175 (any_or:SWI248
8176 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8177 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8178 (clobber (reg:CC FLAGS_REG))]
8179 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8180 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8181 [(set_attr "type" "alu")
8182 (set_attr "mode" "<MODE>")])
8183
8184 ;; %%% Potential partial reg stall on alternative 2. What to do?
8185 (define_insn "*<code>qi_1"
8186 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8187 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8188 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8189 (clobber (reg:CC FLAGS_REG))]
8190 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8191 "@
8192 <logic>{b}\t{%2, %0|%0, %2}
8193 <logic>{b}\t{%2, %0|%0, %2}
8194 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8195 [(set_attr "type" "alu")
8196 (set_attr "mode" "QI,QI,SI")])
8197
8198 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8199 (define_insn "*<code>si_1_zext"
8200 [(set (match_operand:DI 0 "register_operand" "=r")
8201 (zero_extend:DI
8202 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8203 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8204 (clobber (reg:CC FLAGS_REG))]
8205 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8206 "<logic>{l}\t{%2, %k0|%k0, %2}"
8207 [(set_attr "type" "alu")
8208 (set_attr "mode" "SI")])
8209
8210 (define_insn "*<code>si_1_zext_imm"
8211 [(set (match_operand:DI 0 "register_operand" "=r")
8212 (any_or:DI
8213 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8214 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8215 (clobber (reg:CC FLAGS_REG))]
8216 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8217 "<logic>{l}\t{%2, %k0|%k0, %2}"
8218 [(set_attr "type" "alu")
8219 (set_attr "mode" "SI")])
8220
8221 (define_insn "*<code>qi_1_slp"
8222 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8223 (any_or:QI (match_dup 0)
8224 (match_operand:QI 1 "general_operand" "qmn,qn")))
8225 (clobber (reg:CC FLAGS_REG))]
8226 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8227 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8228 "<logic>{b}\t{%1, %0|%0, %1}"
8229 [(set_attr "type" "alu1")
8230 (set_attr "mode" "QI")])
8231
8232 (define_insn "*<code><mode>_2"
8233 [(set (reg FLAGS_REG)
8234 (compare (any_or:SWI
8235 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8236 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8237 (const_int 0)))
8238 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8239 (any_or:SWI (match_dup 1) (match_dup 2)))]
8240 "ix86_match_ccmode (insn, CCNOmode)
8241 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8242 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8243 [(set_attr "type" "alu")
8244 (set_attr "mode" "<MODE>")])
8245
8246 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8247 ;; ??? Special case for immediate operand is missing - it is tricky.
8248 (define_insn "*<code>si_2_zext"
8249 [(set (reg FLAGS_REG)
8250 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8251 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8252 (const_int 0)))
8253 (set (match_operand:DI 0 "register_operand" "=r")
8254 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8255 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8256 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8257 "<logic>{l}\t{%2, %k0|%k0, %2}"
8258 [(set_attr "type" "alu")
8259 (set_attr "mode" "SI")])
8260
8261 (define_insn "*<code>si_2_zext_imm"
8262 [(set (reg FLAGS_REG)
8263 (compare (any_or:SI
8264 (match_operand:SI 1 "nonimmediate_operand" "%0")
8265 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8266 (const_int 0)))
8267 (set (match_operand:DI 0 "register_operand" "=r")
8268 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8269 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8270 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8271 "<logic>{l}\t{%2, %k0|%k0, %2}"
8272 [(set_attr "type" "alu")
8273 (set_attr "mode" "SI")])
8274
8275 (define_insn "*<code>qi_2_slp"
8276 [(set (reg FLAGS_REG)
8277 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8278 (match_operand:QI 1 "general_operand" "qmn,qn"))
8279 (const_int 0)))
8280 (set (strict_low_part (match_dup 0))
8281 (any_or:QI (match_dup 0) (match_dup 1)))]
8282 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8283 && ix86_match_ccmode (insn, CCNOmode)
8284 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8285 "<logic>{b}\t{%1, %0|%0, %1}"
8286 [(set_attr "type" "alu1")
8287 (set_attr "mode" "QI")])
8288
8289 (define_insn "*<code><mode>_3"
8290 [(set (reg FLAGS_REG)
8291 (compare (any_or:SWI
8292 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8293 (match_operand:SWI 2 "<general_operand>" "<g>"))
8294 (const_int 0)))
8295 (clobber (match_scratch:SWI 0 "=<r>"))]
8296 "ix86_match_ccmode (insn, CCNOmode)
8297 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8298 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8299 [(set_attr "type" "alu")
8300 (set_attr "mode" "<MODE>")])
8301
8302 (define_insn "*<code>qi_ext_0"
8303 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8304 (const_int 8)
8305 (const_int 8))
8306 (any_or:SI
8307 (zero_extract:SI
8308 (match_operand 1 "ext_register_operand" "0")
8309 (const_int 8)
8310 (const_int 8))
8311 (match_operand 2 "const_int_operand" "n")))
8312 (clobber (reg:CC FLAGS_REG))]
8313 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8314 "<logic>{b}\t{%2, %h0|%h0, %2}"
8315 [(set_attr "type" "alu")
8316 (set_attr "length_immediate" "1")
8317 (set_attr "modrm" "1")
8318 (set_attr "mode" "QI")])
8319
8320 (define_insn "*<code>qi_ext_1_rex64"
8321 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8322 (const_int 8)
8323 (const_int 8))
8324 (any_or:SI
8325 (zero_extract:SI
8326 (match_operand 1 "ext_register_operand" "0")
8327 (const_int 8)
8328 (const_int 8))
8329 (zero_extend:SI
8330 (match_operand 2 "ext_register_operand" "Q"))))
8331 (clobber (reg:CC FLAGS_REG))]
8332 "TARGET_64BIT
8333 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8334 "<logic>{b}\t{%2, %h0|%h0, %2}"
8335 [(set_attr "type" "alu")
8336 (set_attr "length_immediate" "0")
8337 (set_attr "mode" "QI")])
8338
8339 (define_insn "*<code>qi_ext_1"
8340 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8341 (const_int 8)
8342 (const_int 8))
8343 (any_or:SI
8344 (zero_extract:SI
8345 (match_operand 1 "ext_register_operand" "0")
8346 (const_int 8)
8347 (const_int 8))
8348 (zero_extend:SI
8349 (match_operand:QI 2 "general_operand" "Qm"))))
8350 (clobber (reg:CC FLAGS_REG))]
8351 "!TARGET_64BIT
8352 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8353 "<logic>{b}\t{%2, %h0|%h0, %2}"
8354 [(set_attr "type" "alu")
8355 (set_attr "length_immediate" "0")
8356 (set_attr "mode" "QI")])
8357
8358 (define_insn "*<code>qi_ext_2"
8359 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8360 (const_int 8)
8361 (const_int 8))
8362 (any_or:SI
8363 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8364 (const_int 8)
8365 (const_int 8))
8366 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8367 (const_int 8)
8368 (const_int 8))))
8369 (clobber (reg:CC FLAGS_REG))]
8370 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8371 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8372 [(set_attr "type" "alu")
8373 (set_attr "length_immediate" "0")
8374 (set_attr "mode" "QI")])
8375
8376 (define_split
8377 [(set (match_operand 0 "register_operand" "")
8378 (any_or (match_operand 1 "register_operand" "")
8379 (match_operand 2 "const_int_operand" "")))
8380 (clobber (reg:CC FLAGS_REG))]
8381 "reload_completed
8382 && QI_REG_P (operands[0])
8383 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8384 && !(INTVAL (operands[2]) & ~(255 << 8))
8385 && GET_MODE (operands[0]) != QImode"
8386 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8387 (any_or:SI (zero_extract:SI (match_dup 1)
8388 (const_int 8) (const_int 8))
8389 (match_dup 2)))
8390 (clobber (reg:CC FLAGS_REG))])]
8391 "operands[0] = gen_lowpart (SImode, operands[0]);
8392 operands[1] = gen_lowpart (SImode, operands[1]);
8393 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8394
8395 ;; Since OR can be encoded with sign extended immediate, this is only
8396 ;; profitable when 7th bit is set.
8397 (define_split
8398 [(set (match_operand 0 "register_operand" "")
8399 (any_or (match_operand 1 "general_operand" "")
8400 (match_operand 2 "const_int_operand" "")))
8401 (clobber (reg:CC FLAGS_REG))]
8402 "reload_completed
8403 && ANY_QI_REG_P (operands[0])
8404 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8405 && !(INTVAL (operands[2]) & ~255)
8406 && (INTVAL (operands[2]) & 128)
8407 && GET_MODE (operands[0]) != QImode"
8408 [(parallel [(set (strict_low_part (match_dup 0))
8409 (any_or:QI (match_dup 1)
8410 (match_dup 2)))
8411 (clobber (reg:CC FLAGS_REG))])]
8412 "operands[0] = gen_lowpart (QImode, operands[0]);
8413 operands[1] = gen_lowpart (QImode, operands[1]);
8414 operands[2] = gen_lowpart (QImode, operands[2]);")
8415
8416 (define_expand "xorqi_cc_ext_1"
8417 [(parallel [
8418 (set (reg:CCNO FLAGS_REG)
8419 (compare:CCNO
8420 (xor:SI
8421 (zero_extract:SI
8422 (match_operand 1 "ext_register_operand" "")
8423 (const_int 8)
8424 (const_int 8))
8425 (match_operand:QI 2 "general_operand" ""))
8426 (const_int 0)))
8427 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8428 (const_int 8)
8429 (const_int 8))
8430 (xor:SI
8431 (zero_extract:SI
8432 (match_dup 1)
8433 (const_int 8)
8434 (const_int 8))
8435 (match_dup 2)))])])
8436
8437 (define_insn "*xorqi_cc_ext_1_rex64"
8438 [(set (reg FLAGS_REG)
8439 (compare
8440 (xor:SI
8441 (zero_extract:SI
8442 (match_operand 1 "ext_register_operand" "0")
8443 (const_int 8)
8444 (const_int 8))
8445 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8446 (const_int 0)))
8447 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8448 (const_int 8)
8449 (const_int 8))
8450 (xor:SI
8451 (zero_extract:SI
8452 (match_dup 1)
8453 (const_int 8)
8454 (const_int 8))
8455 (match_dup 2)))]
8456 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8457 "xor{b}\t{%2, %h0|%h0, %2}"
8458 [(set_attr "type" "alu")
8459 (set_attr "modrm" "1")
8460 (set_attr "mode" "QI")])
8461
8462 (define_insn "*xorqi_cc_ext_1"
8463 [(set (reg FLAGS_REG)
8464 (compare
8465 (xor:SI
8466 (zero_extract:SI
8467 (match_operand 1 "ext_register_operand" "0")
8468 (const_int 8)
8469 (const_int 8))
8470 (match_operand:QI 2 "general_operand" "qmn"))
8471 (const_int 0)))
8472 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8473 (const_int 8)
8474 (const_int 8))
8475 (xor:SI
8476 (zero_extract:SI
8477 (match_dup 1)
8478 (const_int 8)
8479 (const_int 8))
8480 (match_dup 2)))]
8481 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8482 "xor{b}\t{%2, %h0|%h0, %2}"
8483 [(set_attr "type" "alu")
8484 (set_attr "modrm" "1")
8485 (set_attr "mode" "QI")])
8486 \f
8487 ;; Negation instructions
8488
8489 (define_expand "neg<mode>2"
8490 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8491 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8492 ""
8493 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8494
8495 (define_insn_and_split "*neg<dwi>2_doubleword"
8496 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8497 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8498 (clobber (reg:CC FLAGS_REG))]
8499 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8500 "#"
8501 "reload_completed"
8502 [(parallel
8503 [(set (reg:CCZ FLAGS_REG)
8504 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8505 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8506 (parallel
8507 [(set (match_dup 2)
8508 (plus:DWIH (match_dup 3)
8509 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8510 (const_int 0))))
8511 (clobber (reg:CC FLAGS_REG))])
8512 (parallel
8513 [(set (match_dup 2)
8514 (neg:DWIH (match_dup 2)))
8515 (clobber (reg:CC FLAGS_REG))])]
8516 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8517
8518 (define_insn "*neg<mode>2_1"
8519 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8520 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8521 (clobber (reg:CC FLAGS_REG))]
8522 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8523 "neg{<imodesuffix>}\t%0"
8524 [(set_attr "type" "negnot")
8525 (set_attr "mode" "<MODE>")])
8526
8527 ;; Combine is quite creative about this pattern.
8528 (define_insn "*negsi2_1_zext"
8529 [(set (match_operand:DI 0 "register_operand" "=r")
8530 (lshiftrt:DI
8531 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8532 (const_int 32)))
8533 (const_int 32)))
8534 (clobber (reg:CC FLAGS_REG))]
8535 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8536 "neg{l}\t%k0"
8537 [(set_attr "type" "negnot")
8538 (set_attr "mode" "SI")])
8539
8540 ;; The problem with neg is that it does not perform (compare x 0),
8541 ;; it really performs (compare 0 x), which leaves us with the zero
8542 ;; flag being the only useful item.
8543
8544 (define_insn "*neg<mode>2_cmpz"
8545 [(set (reg:CCZ FLAGS_REG)
8546 (compare:CCZ
8547 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8548 (const_int 0)))
8549 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8550 (neg:SWI (match_dup 1)))]
8551 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8552 "neg{<imodesuffix>}\t%0"
8553 [(set_attr "type" "negnot")
8554 (set_attr "mode" "<MODE>")])
8555
8556 (define_insn "*negsi2_cmpz_zext"
8557 [(set (reg:CCZ FLAGS_REG)
8558 (compare:CCZ
8559 (lshiftrt:DI
8560 (neg:DI (ashift:DI
8561 (match_operand:DI 1 "register_operand" "0")
8562 (const_int 32)))
8563 (const_int 32))
8564 (const_int 0)))
8565 (set (match_operand:DI 0 "register_operand" "=r")
8566 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8567 (const_int 32)))
8568 (const_int 32)))]
8569 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8570 "neg{l}\t%k0"
8571 [(set_attr "type" "negnot")
8572 (set_attr "mode" "SI")])
8573
8574 ;; Changing of sign for FP values is doable using integer unit too.
8575
8576 (define_expand "<code><mode>2"
8577 [(set (match_operand:X87MODEF 0 "register_operand" "")
8578 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8579 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8580 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8581
8582 (define_insn "*absneg<mode>2_mixed"
8583 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8584 (match_operator:MODEF 3 "absneg_operator"
8585 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8586 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8587 (clobber (reg:CC FLAGS_REG))]
8588 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8589 "#")
8590
8591 (define_insn "*absneg<mode>2_sse"
8592 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8593 (match_operator:MODEF 3 "absneg_operator"
8594 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8595 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8596 (clobber (reg:CC FLAGS_REG))]
8597 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8598 "#")
8599
8600 (define_insn "*absneg<mode>2_i387"
8601 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8602 (match_operator:X87MODEF 3 "absneg_operator"
8603 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8604 (use (match_operand 2 "" ""))
8605 (clobber (reg:CC FLAGS_REG))]
8606 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8607 "#")
8608
8609 (define_expand "<code>tf2"
8610 [(set (match_operand:TF 0 "register_operand" "")
8611 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8612 "TARGET_SSE2"
8613 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8614
8615 (define_insn "*absnegtf2_sse"
8616 [(set (match_operand:TF 0 "register_operand" "=x,x")
8617 (match_operator:TF 3 "absneg_operator"
8618 [(match_operand:TF 1 "register_operand" "0,x")]))
8619 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8620 (clobber (reg:CC FLAGS_REG))]
8621 "TARGET_SSE2"
8622 "#")
8623
8624 ;; Splitters for fp abs and neg.
8625
8626 (define_split
8627 [(set (match_operand 0 "fp_register_operand" "")
8628 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8629 (use (match_operand 2 "" ""))
8630 (clobber (reg:CC FLAGS_REG))]
8631 "reload_completed"
8632 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8633
8634 (define_split
8635 [(set (match_operand 0 "register_operand" "")
8636 (match_operator 3 "absneg_operator"
8637 [(match_operand 1 "register_operand" "")]))
8638 (use (match_operand 2 "nonimmediate_operand" ""))
8639 (clobber (reg:CC FLAGS_REG))]
8640 "reload_completed && SSE_REG_P (operands[0])"
8641 [(set (match_dup 0) (match_dup 3))]
8642 {
8643 enum machine_mode mode = GET_MODE (operands[0]);
8644 enum machine_mode vmode = GET_MODE (operands[2]);
8645 rtx tmp;
8646
8647 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8648 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8649 if (operands_match_p (operands[0], operands[2]))
8650 {
8651 tmp = operands[1];
8652 operands[1] = operands[2];
8653 operands[2] = tmp;
8654 }
8655 if (GET_CODE (operands[3]) == ABS)
8656 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8657 else
8658 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8659 operands[3] = tmp;
8660 })
8661
8662 (define_split
8663 [(set (match_operand:SF 0 "register_operand" "")
8664 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8665 (use (match_operand:V4SF 2 "" ""))
8666 (clobber (reg:CC FLAGS_REG))]
8667 "reload_completed"
8668 [(parallel [(set (match_dup 0) (match_dup 1))
8669 (clobber (reg:CC FLAGS_REG))])]
8670 {
8671 rtx tmp;
8672 operands[0] = gen_lowpart (SImode, operands[0]);
8673 if (GET_CODE (operands[1]) == ABS)
8674 {
8675 tmp = gen_int_mode (0x7fffffff, SImode);
8676 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8677 }
8678 else
8679 {
8680 tmp = gen_int_mode (0x80000000, SImode);
8681 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8682 }
8683 operands[1] = tmp;
8684 })
8685
8686 (define_split
8687 [(set (match_operand:DF 0 "register_operand" "")
8688 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8689 (use (match_operand 2 "" ""))
8690 (clobber (reg:CC FLAGS_REG))]
8691 "reload_completed"
8692 [(parallel [(set (match_dup 0) (match_dup 1))
8693 (clobber (reg:CC FLAGS_REG))])]
8694 {
8695 rtx tmp;
8696 if (TARGET_64BIT)
8697 {
8698 tmp = gen_lowpart (DImode, operands[0]);
8699 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8700 operands[0] = tmp;
8701
8702 if (GET_CODE (operands[1]) == ABS)
8703 tmp = const0_rtx;
8704 else
8705 tmp = gen_rtx_NOT (DImode, tmp);
8706 }
8707 else
8708 {
8709 operands[0] = gen_highpart (SImode, operands[0]);
8710 if (GET_CODE (operands[1]) == ABS)
8711 {
8712 tmp = gen_int_mode (0x7fffffff, SImode);
8713 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8714 }
8715 else
8716 {
8717 tmp = gen_int_mode (0x80000000, SImode);
8718 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8719 }
8720 }
8721 operands[1] = tmp;
8722 })
8723
8724 (define_split
8725 [(set (match_operand:XF 0 "register_operand" "")
8726 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8727 (use (match_operand 2 "" ""))
8728 (clobber (reg:CC FLAGS_REG))]
8729 "reload_completed"
8730 [(parallel [(set (match_dup 0) (match_dup 1))
8731 (clobber (reg:CC FLAGS_REG))])]
8732 {
8733 rtx tmp;
8734 operands[0] = gen_rtx_REG (SImode,
8735 true_regnum (operands[0])
8736 + (TARGET_64BIT ? 1 : 2));
8737 if (GET_CODE (operands[1]) == ABS)
8738 {
8739 tmp = GEN_INT (0x7fff);
8740 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8741 }
8742 else
8743 {
8744 tmp = GEN_INT (0x8000);
8745 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8746 }
8747 operands[1] = tmp;
8748 })
8749
8750 ;; Conditionalize these after reload. If they match before reload, we
8751 ;; lose the clobber and ability to use integer instructions.
8752
8753 (define_insn "*<code><mode>2_1"
8754 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8755 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8756 "TARGET_80387
8757 && (reload_completed
8758 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8759 "f<absneg_mnemonic>"
8760 [(set_attr "type" "fsgn")
8761 (set_attr "mode" "<MODE>")])
8762
8763 (define_insn "*<code>extendsfdf2"
8764 [(set (match_operand:DF 0 "register_operand" "=f")
8765 (absneg:DF (float_extend:DF
8766 (match_operand:SF 1 "register_operand" "0"))))]
8767 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8768 "f<absneg_mnemonic>"
8769 [(set_attr "type" "fsgn")
8770 (set_attr "mode" "DF")])
8771
8772 (define_insn "*<code>extendsfxf2"
8773 [(set (match_operand:XF 0 "register_operand" "=f")
8774 (absneg:XF (float_extend:XF
8775 (match_operand:SF 1 "register_operand" "0"))))]
8776 "TARGET_80387"
8777 "f<absneg_mnemonic>"
8778 [(set_attr "type" "fsgn")
8779 (set_attr "mode" "XF")])
8780
8781 (define_insn "*<code>extenddfxf2"
8782 [(set (match_operand:XF 0 "register_operand" "=f")
8783 (absneg:XF (float_extend:XF
8784 (match_operand:DF 1 "register_operand" "0"))))]
8785 "TARGET_80387"
8786 "f<absneg_mnemonic>"
8787 [(set_attr "type" "fsgn")
8788 (set_attr "mode" "XF")])
8789
8790 ;; Copysign instructions
8791
8792 (define_mode_iterator CSGNMODE [SF DF TF])
8793 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8794
8795 (define_expand "copysign<mode>3"
8796 [(match_operand:CSGNMODE 0 "register_operand" "")
8797 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8798 (match_operand:CSGNMODE 2 "register_operand" "")]
8799 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8800 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8801 "ix86_expand_copysign (operands); DONE;")
8802
8803 (define_insn_and_split "copysign<mode>3_const"
8804 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8805 (unspec:CSGNMODE
8806 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8807 (match_operand:CSGNMODE 2 "register_operand" "0")
8808 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8809 UNSPEC_COPYSIGN))]
8810 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8811 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8812 "#"
8813 "&& reload_completed"
8814 [(const_int 0)]
8815 "ix86_split_copysign_const (operands); DONE;")
8816
8817 (define_insn "copysign<mode>3_var"
8818 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8819 (unspec:CSGNMODE
8820 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8821 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8822 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8823 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8824 UNSPEC_COPYSIGN))
8825 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8826 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8827 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8828 "#")
8829
8830 (define_split
8831 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8832 (unspec:CSGNMODE
8833 [(match_operand:CSGNMODE 2 "register_operand" "")
8834 (match_operand:CSGNMODE 3 "register_operand" "")
8835 (match_operand:<CSGNVMODE> 4 "" "")
8836 (match_operand:<CSGNVMODE> 5 "" "")]
8837 UNSPEC_COPYSIGN))
8838 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8839 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8840 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8841 && reload_completed"
8842 [(const_int 0)]
8843 "ix86_split_copysign_var (operands); DONE;")
8844 \f
8845 ;; One complement instructions
8846
8847 (define_expand "one_cmpl<mode>2"
8848 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8849 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8850 ""
8851 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8852
8853 (define_insn "*one_cmpl<mode>2_1"
8854 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8855 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8856 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8857 "not{<imodesuffix>}\t%0"
8858 [(set_attr "type" "negnot")
8859 (set_attr "mode" "<MODE>")])
8860
8861 ;; %%% Potential partial reg stall on alternative 1. What to do?
8862 (define_insn "*one_cmplqi2_1"
8863 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8864 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8865 "ix86_unary_operator_ok (NOT, QImode, operands)"
8866 "@
8867 not{b}\t%0
8868 not{l}\t%k0"
8869 [(set_attr "type" "negnot")
8870 (set_attr "mode" "QI,SI")])
8871
8872 ;; ??? Currently never generated - xor is used instead.
8873 (define_insn "*one_cmplsi2_1_zext"
8874 [(set (match_operand:DI 0 "register_operand" "=r")
8875 (zero_extend:DI
8876 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8877 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8878 "not{l}\t%k0"
8879 [(set_attr "type" "negnot")
8880 (set_attr "mode" "SI")])
8881
8882 (define_insn "*one_cmpl<mode>2_2"
8883 [(set (reg FLAGS_REG)
8884 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8885 (const_int 0)))
8886 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8887 (not:SWI (match_dup 1)))]
8888 "ix86_match_ccmode (insn, CCNOmode)
8889 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8890 "#"
8891 [(set_attr "type" "alu1")
8892 (set_attr "mode" "<MODE>")])
8893
8894 (define_split
8895 [(set (match_operand 0 "flags_reg_operand" "")
8896 (match_operator 2 "compare_operator"
8897 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8898 (const_int 0)]))
8899 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8900 (not:SWI (match_dup 3)))]
8901 "ix86_match_ccmode (insn, CCNOmode)"
8902 [(parallel [(set (match_dup 0)
8903 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8904 (const_int 0)]))
8905 (set (match_dup 1)
8906 (xor:SWI (match_dup 3) (const_int -1)))])])
8907
8908 ;; ??? Currently never generated - xor is used instead.
8909 (define_insn "*one_cmplsi2_2_zext"
8910 [(set (reg FLAGS_REG)
8911 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8912 (const_int 0)))
8913 (set (match_operand:DI 0 "register_operand" "=r")
8914 (zero_extend:DI (not:SI (match_dup 1))))]
8915 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8916 && ix86_unary_operator_ok (NOT, SImode, operands)"
8917 "#"
8918 [(set_attr "type" "alu1")
8919 (set_attr "mode" "SI")])
8920
8921 (define_split
8922 [(set (match_operand 0 "flags_reg_operand" "")
8923 (match_operator 2 "compare_operator"
8924 [(not:SI (match_operand:SI 3 "register_operand" ""))
8925 (const_int 0)]))
8926 (set (match_operand:DI 1 "register_operand" "")
8927 (zero_extend:DI (not:SI (match_dup 3))))]
8928 "ix86_match_ccmode (insn, CCNOmode)"
8929 [(parallel [(set (match_dup 0)
8930 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8931 (const_int 0)]))
8932 (set (match_dup 1)
8933 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8934 \f
8935 ;; Shift instructions
8936
8937 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8938 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8939 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8940 ;; from the assembler input.
8941 ;;
8942 ;; This instruction shifts the target reg/mem as usual, but instead of
8943 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8944 ;; is a left shift double, bits are taken from the high order bits of
8945 ;; reg, else if the insn is a shift right double, bits are taken from the
8946 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8947 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8948 ;;
8949 ;; Since sh[lr]d does not change the `reg' operand, that is done
8950 ;; separately, making all shifts emit pairs of shift double and normal
8951 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8952 ;; support a 63 bit shift, each shift where the count is in a reg expands
8953 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8954 ;;
8955 ;; If the shift count is a constant, we need never emit more than one
8956 ;; shift pair, instead using moves and sign extension for counts greater
8957 ;; than 31.
8958
8959 (define_expand "ashl<mode>3"
8960 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8961 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8962 (match_operand:QI 2 "nonmemory_operand" "")))]
8963 ""
8964 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8965
8966 (define_insn "*ashl<mode>3_doubleword"
8967 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8968 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8969 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8970 (clobber (reg:CC FLAGS_REG))]
8971 ""
8972 "#"
8973 [(set_attr "type" "multi")])
8974
8975 (define_split
8976 [(set (match_operand:DWI 0 "register_operand" "")
8977 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8978 (match_operand:QI 2 "nonmemory_operand" "")))
8979 (clobber (reg:CC FLAGS_REG))]
8980 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8981 [(const_int 0)]
8982 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8983
8984 ;; By default we don't ask for a scratch register, because when DWImode
8985 ;; values are manipulated, registers are already at a premium. But if
8986 ;; we have one handy, we won't turn it away.
8987
8988 (define_peephole2
8989 [(match_scratch:DWIH 3 "r")
8990 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8991 (ashift:<DWI>
8992 (match_operand:<DWI> 1 "nonmemory_operand" "")
8993 (match_operand:QI 2 "nonmemory_operand" "")))
8994 (clobber (reg:CC FLAGS_REG))])
8995 (match_dup 3)]
8996 "TARGET_CMOVE"
8997 [(const_int 0)]
8998 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8999
9000 (define_insn "x86_64_shld"
9001 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9002 (ior:DI (ashift:DI (match_dup 0)
9003 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9004 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9005 (minus:QI (const_int 64) (match_dup 2)))))
9006 (clobber (reg:CC FLAGS_REG))]
9007 "TARGET_64BIT"
9008 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9009 [(set_attr "type" "ishift")
9010 (set_attr "prefix_0f" "1")
9011 (set_attr "mode" "DI")
9012 (set_attr "athlon_decode" "vector")
9013 (set_attr "amdfam10_decode" "vector")
9014 (set_attr "bdver1_decode" "vector")])
9015
9016 (define_insn "x86_shld"
9017 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9018 (ior:SI (ashift:SI (match_dup 0)
9019 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9020 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9021 (minus:QI (const_int 32) (match_dup 2)))))
9022 (clobber (reg:CC FLAGS_REG))]
9023 ""
9024 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9025 [(set_attr "type" "ishift")
9026 (set_attr "prefix_0f" "1")
9027 (set_attr "mode" "SI")
9028 (set_attr "pent_pair" "np")
9029 (set_attr "athlon_decode" "vector")
9030 (set_attr "amdfam10_decode" "vector")
9031 (set_attr "bdver1_decode" "vector")])
9032
9033 (define_expand "x86_shift<mode>_adj_1"
9034 [(set (reg:CCZ FLAGS_REG)
9035 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9036 (match_dup 4))
9037 (const_int 0)))
9038 (set (match_operand:SWI48 0 "register_operand" "")
9039 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9040 (match_operand:SWI48 1 "register_operand" "")
9041 (match_dup 0)))
9042 (set (match_dup 1)
9043 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9044 (match_operand:SWI48 3 "register_operand" "r")
9045 (match_dup 1)))]
9046 "TARGET_CMOVE"
9047 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9048
9049 (define_expand "x86_shift<mode>_adj_2"
9050 [(use (match_operand:SWI48 0 "register_operand" ""))
9051 (use (match_operand:SWI48 1 "register_operand" ""))
9052 (use (match_operand:QI 2 "register_operand" ""))]
9053 ""
9054 {
9055 rtx label = gen_label_rtx ();
9056 rtx tmp;
9057
9058 emit_insn (gen_testqi_ccz_1 (operands[2],
9059 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9060
9061 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9062 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9063 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9064 gen_rtx_LABEL_REF (VOIDmode, label),
9065 pc_rtx);
9066 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9067 JUMP_LABEL (tmp) = label;
9068
9069 emit_move_insn (operands[0], operands[1]);
9070 ix86_expand_clear (operands[1]);
9071
9072 emit_label (label);
9073 LABEL_NUSES (label) = 1;
9074
9075 DONE;
9076 })
9077
9078 ;; Avoid useless masking of count operand.
9079 (define_insn_and_split "*ashl<mode>3_mask"
9080 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9081 (ashift:SWI48
9082 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9083 (subreg:QI
9084 (and:SI
9085 (match_operand:SI 2 "nonimmediate_operand" "c")
9086 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9087 (clobber (reg:CC FLAGS_REG))]
9088 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9089 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9090 == GET_MODE_BITSIZE (<MODE>mode)-1"
9091 "#"
9092 "&& 1"
9093 [(parallel [(set (match_dup 0)
9094 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9095 (clobber (reg:CC FLAGS_REG))])]
9096 {
9097 if (can_create_pseudo_p ())
9098 operands [2] = force_reg (SImode, operands[2]);
9099
9100 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9101 }
9102 [(set_attr "type" "ishift")
9103 (set_attr "mode" "<MODE>")])
9104
9105 (define_insn "*bmi2_ashl<mode>3_1"
9106 [(set (match_operand:SWI48 0 "register_operand" "=r")
9107 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9108 (match_operand:SWI48 2 "register_operand" "r")))]
9109 "TARGET_BMI2"
9110 "shlx\t{%2, %1, %0|%0, %1, %2}"
9111 [(set_attr "type" "ishiftx")
9112 (set_attr "mode" "<MODE>")])
9113
9114 (define_insn "*ashl<mode>3_1"
9115 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9116 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9117 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9118 (clobber (reg:CC FLAGS_REG))]
9119 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9120 {
9121 switch (get_attr_type (insn))
9122 {
9123 case TYPE_LEA:
9124 case TYPE_ISHIFTX:
9125 return "#";
9126
9127 case TYPE_ALU:
9128 gcc_assert (operands[2] == const1_rtx);
9129 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9130 return "add{<imodesuffix>}\t%0, %0";
9131
9132 default:
9133 if (operands[2] == const1_rtx
9134 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9135 return "sal{<imodesuffix>}\t%0";
9136 else
9137 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9138 }
9139 }
9140 [(set_attr "isa" "*,*,bmi2")
9141 (set (attr "type")
9142 (cond [(eq_attr "alternative" "1")
9143 (const_string "lea")
9144 (eq_attr "alternative" "2")
9145 (const_string "ishiftx")
9146 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9147 (match_operand 0 "register_operand" ""))
9148 (match_operand 2 "const1_operand" ""))
9149 (const_string "alu")
9150 ]
9151 (const_string "ishift")))
9152 (set (attr "length_immediate")
9153 (if_then_else
9154 (ior (eq_attr "type" "alu")
9155 (and (eq_attr "type" "ishift")
9156 (and (match_operand 2 "const1_operand" "")
9157 (ior (match_test "TARGET_SHIFT1")
9158 (match_test "optimize_function_for_size_p (cfun)")))))
9159 (const_string "0")
9160 (const_string "*")))
9161 (set_attr "mode" "<MODE>")])
9162
9163 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9164 (define_split
9165 [(set (match_operand:SWI48 0 "register_operand" "")
9166 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9167 (match_operand:QI 2 "register_operand" "")))
9168 (clobber (reg:CC FLAGS_REG))]
9169 "TARGET_BMI2 && reload_completed"
9170 [(set (match_dup 0)
9171 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9172 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9173
9174 (define_insn "*bmi2_ashlsi3_1_zext"
9175 [(set (match_operand:DI 0 "register_operand" "=r")
9176 (zero_extend:DI
9177 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9178 (match_operand:SI 2 "register_operand" "r"))))]
9179 "TARGET_64BIT && TARGET_BMI2"
9180 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9181 [(set_attr "type" "ishiftx")
9182 (set_attr "mode" "SI")])
9183
9184 (define_insn "*ashlsi3_1_zext"
9185 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9186 (zero_extend:DI
9187 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9188 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9189 (clobber (reg:CC FLAGS_REG))]
9190 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9191 {
9192 switch (get_attr_type (insn))
9193 {
9194 case TYPE_LEA:
9195 case TYPE_ISHIFTX:
9196 return "#";
9197
9198 case TYPE_ALU:
9199 gcc_assert (operands[2] == const1_rtx);
9200 return "add{l}\t%k0, %k0";
9201
9202 default:
9203 if (operands[2] == const1_rtx
9204 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9205 return "sal{l}\t%k0";
9206 else
9207 return "sal{l}\t{%2, %k0|%k0, %2}";
9208 }
9209 }
9210 [(set_attr "isa" "*,*,bmi2")
9211 (set (attr "type")
9212 (cond [(eq_attr "alternative" "1")
9213 (const_string "lea")
9214 (eq_attr "alternative" "2")
9215 (const_string "ishiftx")
9216 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9217 (match_operand 2 "const1_operand" ""))
9218 (const_string "alu")
9219 ]
9220 (const_string "ishift")))
9221 (set (attr "length_immediate")
9222 (if_then_else
9223 (ior (eq_attr "type" "alu")
9224 (and (eq_attr "type" "ishift")
9225 (and (match_operand 2 "const1_operand" "")
9226 (ior (match_test "TARGET_SHIFT1")
9227 (match_test "optimize_function_for_size_p (cfun)")))))
9228 (const_string "0")
9229 (const_string "*")))
9230 (set_attr "mode" "SI")])
9231
9232 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9233 (define_split
9234 [(set (match_operand:DI 0 "register_operand" "")
9235 (zero_extend:DI
9236 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9237 (match_operand:QI 2 "register_operand" ""))))
9238 (clobber (reg:CC FLAGS_REG))]
9239 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9240 [(set (match_dup 0)
9241 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9242 "operands[2] = gen_lowpart (SImode, operands[2]);")
9243
9244 (define_insn "*ashlhi3_1"
9245 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9246 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9247 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9248 (clobber (reg:CC FLAGS_REG))]
9249 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9250 {
9251 switch (get_attr_type (insn))
9252 {
9253 case TYPE_LEA:
9254 return "#";
9255
9256 case TYPE_ALU:
9257 gcc_assert (operands[2] == const1_rtx);
9258 return "add{w}\t%0, %0";
9259
9260 default:
9261 if (operands[2] == const1_rtx
9262 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9263 return "sal{w}\t%0";
9264 else
9265 return "sal{w}\t{%2, %0|%0, %2}";
9266 }
9267 }
9268 [(set (attr "type")
9269 (cond [(eq_attr "alternative" "1")
9270 (const_string "lea")
9271 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9272 (match_operand 0 "register_operand" ""))
9273 (match_operand 2 "const1_operand" ""))
9274 (const_string "alu")
9275 ]
9276 (const_string "ishift")))
9277 (set (attr "length_immediate")
9278 (if_then_else
9279 (ior (eq_attr "type" "alu")
9280 (and (eq_attr "type" "ishift")
9281 (and (match_operand 2 "const1_operand" "")
9282 (ior (match_test "TARGET_SHIFT1")
9283 (match_test "optimize_function_for_size_p (cfun)")))))
9284 (const_string "0")
9285 (const_string "*")))
9286 (set_attr "mode" "HI,SI")])
9287
9288 ;; %%% Potential partial reg stall on alternative 1. What to do?
9289 (define_insn "*ashlqi3_1"
9290 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9291 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9292 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9293 (clobber (reg:CC FLAGS_REG))]
9294 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9295 {
9296 switch (get_attr_type (insn))
9297 {
9298 case TYPE_LEA:
9299 return "#";
9300
9301 case TYPE_ALU:
9302 gcc_assert (operands[2] == const1_rtx);
9303 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9304 return "add{l}\t%k0, %k0";
9305 else
9306 return "add{b}\t%0, %0";
9307
9308 default:
9309 if (operands[2] == const1_rtx
9310 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9311 {
9312 if (get_attr_mode (insn) == MODE_SI)
9313 return "sal{l}\t%k0";
9314 else
9315 return "sal{b}\t%0";
9316 }
9317 else
9318 {
9319 if (get_attr_mode (insn) == MODE_SI)
9320 return "sal{l}\t{%2, %k0|%k0, %2}";
9321 else
9322 return "sal{b}\t{%2, %0|%0, %2}";
9323 }
9324 }
9325 }
9326 [(set (attr "type")
9327 (cond [(eq_attr "alternative" "2")
9328 (const_string "lea")
9329 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9330 (match_operand 0 "register_operand" ""))
9331 (match_operand 2 "const1_operand" ""))
9332 (const_string "alu")
9333 ]
9334 (const_string "ishift")))
9335 (set (attr "length_immediate")
9336 (if_then_else
9337 (ior (eq_attr "type" "alu")
9338 (and (eq_attr "type" "ishift")
9339 (and (match_operand 2 "const1_operand" "")
9340 (ior (match_test "TARGET_SHIFT1")
9341 (match_test "optimize_function_for_size_p (cfun)")))))
9342 (const_string "0")
9343 (const_string "*")))
9344 (set_attr "mode" "QI,SI,SI")])
9345
9346 (define_insn "*ashlqi3_1_slp"
9347 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9348 (ashift:QI (match_dup 0)
9349 (match_operand:QI 1 "nonmemory_operand" "cI")))
9350 (clobber (reg:CC FLAGS_REG))]
9351 "(optimize_function_for_size_p (cfun)
9352 || !TARGET_PARTIAL_FLAG_REG_STALL
9353 || (operands[1] == const1_rtx
9354 && (TARGET_SHIFT1
9355 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9356 {
9357 switch (get_attr_type (insn))
9358 {
9359 case TYPE_ALU:
9360 gcc_assert (operands[1] == const1_rtx);
9361 return "add{b}\t%0, %0";
9362
9363 default:
9364 if (operands[1] == const1_rtx
9365 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9366 return "sal{b}\t%0";
9367 else
9368 return "sal{b}\t{%1, %0|%0, %1}";
9369 }
9370 }
9371 [(set (attr "type")
9372 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9373 (match_operand 0 "register_operand" ""))
9374 (match_operand 1 "const1_operand" ""))
9375 (const_string "alu")
9376 ]
9377 (const_string "ishift1")))
9378 (set (attr "length_immediate")
9379 (if_then_else
9380 (ior (eq_attr "type" "alu")
9381 (and (eq_attr "type" "ishift1")
9382 (and (match_operand 1 "const1_operand" "")
9383 (ior (match_test "TARGET_SHIFT1")
9384 (match_test "optimize_function_for_size_p (cfun)")))))
9385 (const_string "0")
9386 (const_string "*")))
9387 (set_attr "mode" "QI")])
9388
9389 ;; Convert ashift to the lea pattern to avoid flags dependency.
9390 (define_split
9391 [(set (match_operand 0 "register_operand" "")
9392 (ashift (match_operand 1 "index_register_operand" "")
9393 (match_operand:QI 2 "const_int_operand" "")))
9394 (clobber (reg:CC FLAGS_REG))]
9395 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9396 && reload_completed
9397 && true_regnum (operands[0]) != true_regnum (operands[1])"
9398 [(const_int 0)]
9399 {
9400 enum machine_mode mode = GET_MODE (operands[0]);
9401 rtx pat;
9402
9403 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9404 {
9405 mode = SImode;
9406 operands[0] = gen_lowpart (mode, operands[0]);
9407 operands[1] = gen_lowpart (mode, operands[1]);
9408 }
9409
9410 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9411
9412 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9413
9414 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9415 DONE;
9416 })
9417
9418 ;; Convert ashift to the lea pattern to avoid flags dependency.
9419 (define_split
9420 [(set (match_operand:DI 0 "register_operand" "")
9421 (zero_extend:DI
9422 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9423 (match_operand:QI 2 "const_int_operand" ""))))
9424 (clobber (reg:CC FLAGS_REG))]
9425 "TARGET_64BIT && reload_completed
9426 && true_regnum (operands[0]) != true_regnum (operands[1])"
9427 [(set (match_dup 0)
9428 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9429 {
9430 operands[1] = gen_lowpart (DImode, operands[1]);
9431 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9432 })
9433
9434 ;; This pattern can't accept a variable shift count, since shifts by
9435 ;; zero don't affect the flags. We assume that shifts by constant
9436 ;; zero are optimized away.
9437 (define_insn "*ashl<mode>3_cmp"
9438 [(set (reg FLAGS_REG)
9439 (compare
9440 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9441 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9442 (const_int 0)))
9443 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9444 (ashift:SWI (match_dup 1) (match_dup 2)))]
9445 "(optimize_function_for_size_p (cfun)
9446 || !TARGET_PARTIAL_FLAG_REG_STALL
9447 || (operands[2] == const1_rtx
9448 && (TARGET_SHIFT1
9449 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9450 && ix86_match_ccmode (insn, CCGOCmode)
9451 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9452 {
9453 switch (get_attr_type (insn))
9454 {
9455 case TYPE_ALU:
9456 gcc_assert (operands[2] == const1_rtx);
9457 return "add{<imodesuffix>}\t%0, %0";
9458
9459 default:
9460 if (operands[2] == const1_rtx
9461 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9462 return "sal{<imodesuffix>}\t%0";
9463 else
9464 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9465 }
9466 }
9467 [(set (attr "type")
9468 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9469 (match_operand 0 "register_operand" ""))
9470 (match_operand 2 "const1_operand" ""))
9471 (const_string "alu")
9472 ]
9473 (const_string "ishift")))
9474 (set (attr "length_immediate")
9475 (if_then_else
9476 (ior (eq_attr "type" "alu")
9477 (and (eq_attr "type" "ishift")
9478 (and (match_operand 2 "const1_operand" "")
9479 (ior (match_test "TARGET_SHIFT1")
9480 (match_test "optimize_function_for_size_p (cfun)")))))
9481 (const_string "0")
9482 (const_string "*")))
9483 (set_attr "mode" "<MODE>")])
9484
9485 (define_insn "*ashlsi3_cmp_zext"
9486 [(set (reg FLAGS_REG)
9487 (compare
9488 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9489 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9490 (const_int 0)))
9491 (set (match_operand:DI 0 "register_operand" "=r")
9492 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9493 "TARGET_64BIT
9494 && (optimize_function_for_size_p (cfun)
9495 || !TARGET_PARTIAL_FLAG_REG_STALL
9496 || (operands[2] == const1_rtx
9497 && (TARGET_SHIFT1
9498 || TARGET_DOUBLE_WITH_ADD)))
9499 && ix86_match_ccmode (insn, CCGOCmode)
9500 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9501 {
9502 switch (get_attr_type (insn))
9503 {
9504 case TYPE_ALU:
9505 gcc_assert (operands[2] == const1_rtx);
9506 return "add{l}\t%k0, %k0";
9507
9508 default:
9509 if (operands[2] == const1_rtx
9510 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9511 return "sal{l}\t%k0";
9512 else
9513 return "sal{l}\t{%2, %k0|%k0, %2}";
9514 }
9515 }
9516 [(set (attr "type")
9517 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9518 (match_operand 2 "const1_operand" ""))
9519 (const_string "alu")
9520 ]
9521 (const_string "ishift")))
9522 (set (attr "length_immediate")
9523 (if_then_else
9524 (ior (eq_attr "type" "alu")
9525 (and (eq_attr "type" "ishift")
9526 (and (match_operand 2 "const1_operand" "")
9527 (ior (match_test "TARGET_SHIFT1")
9528 (match_test "optimize_function_for_size_p (cfun)")))))
9529 (const_string "0")
9530 (const_string "*")))
9531 (set_attr "mode" "SI")])
9532
9533 (define_insn "*ashl<mode>3_cconly"
9534 [(set (reg FLAGS_REG)
9535 (compare
9536 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9537 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9538 (const_int 0)))
9539 (clobber (match_scratch:SWI 0 "=<r>"))]
9540 "(optimize_function_for_size_p (cfun)
9541 || !TARGET_PARTIAL_FLAG_REG_STALL
9542 || (operands[2] == const1_rtx
9543 && (TARGET_SHIFT1
9544 || TARGET_DOUBLE_WITH_ADD)))
9545 && ix86_match_ccmode (insn, CCGOCmode)"
9546 {
9547 switch (get_attr_type (insn))
9548 {
9549 case TYPE_ALU:
9550 gcc_assert (operands[2] == const1_rtx);
9551 return "add{<imodesuffix>}\t%0, %0";
9552
9553 default:
9554 if (operands[2] == const1_rtx
9555 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9556 return "sal{<imodesuffix>}\t%0";
9557 else
9558 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9559 }
9560 }
9561 [(set (attr "type")
9562 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9563 (match_operand 0 "register_operand" ""))
9564 (match_operand 2 "const1_operand" ""))
9565 (const_string "alu")
9566 ]
9567 (const_string "ishift")))
9568 (set (attr "length_immediate")
9569 (if_then_else
9570 (ior (eq_attr "type" "alu")
9571 (and (eq_attr "type" "ishift")
9572 (and (match_operand 2 "const1_operand" "")
9573 (ior (match_test "TARGET_SHIFT1")
9574 (match_test "optimize_function_for_size_p (cfun)")))))
9575 (const_string "0")
9576 (const_string "*")))
9577 (set_attr "mode" "<MODE>")])
9578
9579 ;; See comment above `ashl<mode>3' about how this works.
9580
9581 (define_expand "<shiftrt_insn><mode>3"
9582 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9583 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9584 (match_operand:QI 2 "nonmemory_operand" "")))]
9585 ""
9586 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9587
9588 ;; Avoid useless masking of count operand.
9589 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9590 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9591 (any_shiftrt:SWI48
9592 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9593 (subreg:QI
9594 (and:SI
9595 (match_operand:SI 2 "nonimmediate_operand" "c")
9596 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9597 (clobber (reg:CC FLAGS_REG))]
9598 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9599 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9600 == GET_MODE_BITSIZE (<MODE>mode)-1"
9601 "#"
9602 "&& 1"
9603 [(parallel [(set (match_dup 0)
9604 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9605 (clobber (reg:CC FLAGS_REG))])]
9606 {
9607 if (can_create_pseudo_p ())
9608 operands [2] = force_reg (SImode, operands[2]);
9609
9610 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9611 }
9612 [(set_attr "type" "ishift")
9613 (set_attr "mode" "<MODE>")])
9614
9615 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9616 [(set (match_operand:DWI 0 "register_operand" "=r")
9617 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9618 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9619 (clobber (reg:CC FLAGS_REG))]
9620 ""
9621 "#"
9622 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9623 [(const_int 0)]
9624 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9625 [(set_attr "type" "multi")])
9626
9627 ;; By default we don't ask for a scratch register, because when DWImode
9628 ;; values are manipulated, registers are already at a premium. But if
9629 ;; we have one handy, we won't turn it away.
9630
9631 (define_peephole2
9632 [(match_scratch:DWIH 3 "r")
9633 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9634 (any_shiftrt:<DWI>
9635 (match_operand:<DWI> 1 "register_operand" "")
9636 (match_operand:QI 2 "nonmemory_operand" "")))
9637 (clobber (reg:CC FLAGS_REG))])
9638 (match_dup 3)]
9639 "TARGET_CMOVE"
9640 [(const_int 0)]
9641 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9642
9643 (define_insn "x86_64_shrd"
9644 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9645 (ior:DI (ashiftrt:DI (match_dup 0)
9646 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9647 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9648 (minus:QI (const_int 64) (match_dup 2)))))
9649 (clobber (reg:CC FLAGS_REG))]
9650 "TARGET_64BIT"
9651 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9652 [(set_attr "type" "ishift")
9653 (set_attr "prefix_0f" "1")
9654 (set_attr "mode" "DI")
9655 (set_attr "athlon_decode" "vector")
9656 (set_attr "amdfam10_decode" "vector")
9657 (set_attr "bdver1_decode" "vector")])
9658
9659 (define_insn "x86_shrd"
9660 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9661 (ior:SI (ashiftrt:SI (match_dup 0)
9662 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9663 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9664 (minus:QI (const_int 32) (match_dup 2)))))
9665 (clobber (reg:CC FLAGS_REG))]
9666 ""
9667 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9668 [(set_attr "type" "ishift")
9669 (set_attr "prefix_0f" "1")
9670 (set_attr "mode" "SI")
9671 (set_attr "pent_pair" "np")
9672 (set_attr "athlon_decode" "vector")
9673 (set_attr "amdfam10_decode" "vector")
9674 (set_attr "bdver1_decode" "vector")])
9675
9676 (define_insn "ashrdi3_cvt"
9677 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9678 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9679 (match_operand:QI 2 "const_int_operand" "")))
9680 (clobber (reg:CC FLAGS_REG))]
9681 "TARGET_64BIT && INTVAL (operands[2]) == 63
9682 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9683 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9684 "@
9685 {cqto|cqo}
9686 sar{q}\t{%2, %0|%0, %2}"
9687 [(set_attr "type" "imovx,ishift")
9688 (set_attr "prefix_0f" "0,*")
9689 (set_attr "length_immediate" "0,*")
9690 (set_attr "modrm" "0,1")
9691 (set_attr "mode" "DI")])
9692
9693 (define_insn "ashrsi3_cvt"
9694 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9695 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9696 (match_operand:QI 2 "const_int_operand" "")))
9697 (clobber (reg:CC FLAGS_REG))]
9698 "INTVAL (operands[2]) == 31
9699 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9700 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9701 "@
9702 {cltd|cdq}
9703 sar{l}\t{%2, %0|%0, %2}"
9704 [(set_attr "type" "imovx,ishift")
9705 (set_attr "prefix_0f" "0,*")
9706 (set_attr "length_immediate" "0,*")
9707 (set_attr "modrm" "0,1")
9708 (set_attr "mode" "SI")])
9709
9710 (define_insn "*ashrsi3_cvt_zext"
9711 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9712 (zero_extend:DI
9713 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9714 (match_operand:QI 2 "const_int_operand" ""))))
9715 (clobber (reg:CC FLAGS_REG))]
9716 "TARGET_64BIT && INTVAL (operands[2]) == 31
9717 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9718 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9719 "@
9720 {cltd|cdq}
9721 sar{l}\t{%2, %k0|%k0, %2}"
9722 [(set_attr "type" "imovx,ishift")
9723 (set_attr "prefix_0f" "0,*")
9724 (set_attr "length_immediate" "0,*")
9725 (set_attr "modrm" "0,1")
9726 (set_attr "mode" "SI")])
9727
9728 (define_expand "x86_shift<mode>_adj_3"
9729 [(use (match_operand:SWI48 0 "register_operand" ""))
9730 (use (match_operand:SWI48 1 "register_operand" ""))
9731 (use (match_operand:QI 2 "register_operand" ""))]
9732 ""
9733 {
9734 rtx label = gen_label_rtx ();
9735 rtx tmp;
9736
9737 emit_insn (gen_testqi_ccz_1 (operands[2],
9738 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9739
9740 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9741 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9742 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9743 gen_rtx_LABEL_REF (VOIDmode, label),
9744 pc_rtx);
9745 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9746 JUMP_LABEL (tmp) = label;
9747
9748 emit_move_insn (operands[0], operands[1]);
9749 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9750 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9751 emit_label (label);
9752 LABEL_NUSES (label) = 1;
9753
9754 DONE;
9755 })
9756
9757 (define_insn "*bmi2_<shiftrt_insn><mode>3_1"
9758 [(set (match_operand:SWI48 0 "register_operand" "=r")
9759 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9760 (match_operand:SWI48 2 "register_operand" "r")))]
9761 "TARGET_BMI2"
9762 "<shiftrt>x\t{%2, %1, %0|%0, %1, %2}"
9763 [(set_attr "type" "ishiftx")
9764 (set_attr "mode" "<MODE>")])
9765
9766 (define_insn "*<shiftrt_insn><mode>3_1"
9767 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9768 (any_shiftrt:SWI48
9769 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9770 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9771 (clobber (reg:CC FLAGS_REG))]
9772 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9773 {
9774 switch (get_attr_type (insn))
9775 {
9776 case TYPE_ISHIFTX:
9777 return "#";
9778
9779 default:
9780 if (operands[2] == const1_rtx
9781 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9782 return "<shiftrt>{<imodesuffix>}\t%0";
9783 else
9784 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9785 }
9786 }
9787 [(set_attr "isa" "*,bmi2")
9788 (set_attr "type" "ishift,ishiftx")
9789 (set (attr "length_immediate")
9790 (if_then_else
9791 (and (match_operand 2 "const1_operand" "")
9792 (ior (match_test "TARGET_SHIFT1")
9793 (match_test "optimize_function_for_size_p (cfun)")))
9794 (const_string "0")
9795 (const_string "*")))
9796 (set_attr "mode" "<MODE>")])
9797
9798 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9799 (define_split
9800 [(set (match_operand:SWI48 0 "register_operand" "")
9801 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9802 (match_operand:QI 2 "register_operand" "")))
9803 (clobber (reg:CC FLAGS_REG))]
9804 "TARGET_BMI2 && reload_completed"
9805 [(set (match_dup 0)
9806 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9807 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9808
9809 (define_insn "*bmi2_<shiftrt_insn>si3_1_zext"
9810 [(set (match_operand:DI 0 "register_operand" "=r")
9811 (zero_extend:DI
9812 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9813 (match_operand:SI 2 "register_operand" "r"))))]
9814 "TARGET_64BIT && TARGET_BMI2"
9815 "<shiftrt>x\t{%2, %1, %k0|%k0, %1, %2}"
9816 [(set_attr "type" "ishiftx")
9817 (set_attr "mode" "SI")])
9818
9819 (define_insn "*<shiftrt_insn>si3_1_zext"
9820 [(set (match_operand:DI 0 "register_operand" "=r,r")
9821 (zero_extend:DI
9822 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9823 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9824 (clobber (reg:CC FLAGS_REG))]
9825 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9826 {
9827 switch (get_attr_type (insn))
9828 {
9829 case TYPE_ISHIFTX:
9830 return "#";
9831
9832 default:
9833 if (operands[2] == const1_rtx
9834 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9835 return "<shiftrt>{l}\t%k0";
9836 else
9837 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9838 }
9839 }
9840 [(set_attr "isa" "*,bmi2")
9841 (set_attr "type" "ishift,ishiftx")
9842 (set (attr "length_immediate")
9843 (if_then_else
9844 (and (match_operand 2 "const1_operand" "")
9845 (ior (match_test "TARGET_SHIFT1")
9846 (match_test "optimize_function_for_size_p (cfun)")))
9847 (const_string "0")
9848 (const_string "*")))
9849 (set_attr "mode" "SI")])
9850
9851 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9852 (define_split
9853 [(set (match_operand:DI 0 "register_operand" "")
9854 (zero_extend:DI
9855 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9856 (match_operand:QI 2 "register_operand" ""))))
9857 (clobber (reg:CC FLAGS_REG))]
9858 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9859 [(set (match_dup 0)
9860 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9861 "operands[2] = gen_lowpart (SImode, operands[2]);")
9862
9863 (define_insn "*<shiftrt_insn><mode>3_1"
9864 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9865 (any_shiftrt:SWI12
9866 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9867 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9868 (clobber (reg:CC FLAGS_REG))]
9869 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9870 {
9871 if (operands[2] == const1_rtx
9872 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9873 return "<shiftrt>{<imodesuffix>}\t%0";
9874 else
9875 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9876 }
9877 [(set_attr "type" "ishift")
9878 (set (attr "length_immediate")
9879 (if_then_else
9880 (and (match_operand 2 "const1_operand" "")
9881 (ior (match_test "TARGET_SHIFT1")
9882 (match_test "optimize_function_for_size_p (cfun)")))
9883 (const_string "0")
9884 (const_string "*")))
9885 (set_attr "mode" "<MODE>")])
9886
9887 (define_insn "*<shiftrt_insn>qi3_1_slp"
9888 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9889 (any_shiftrt:QI (match_dup 0)
9890 (match_operand:QI 1 "nonmemory_operand" "cI")))
9891 (clobber (reg:CC FLAGS_REG))]
9892 "(optimize_function_for_size_p (cfun)
9893 || !TARGET_PARTIAL_REG_STALL
9894 || (operands[1] == const1_rtx
9895 && TARGET_SHIFT1))"
9896 {
9897 if (operands[1] == const1_rtx
9898 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9899 return "<shiftrt>{b}\t%0";
9900 else
9901 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9902 }
9903 [(set_attr "type" "ishift1")
9904 (set (attr "length_immediate")
9905 (if_then_else
9906 (and (match_operand 1 "const1_operand" "")
9907 (ior (match_test "TARGET_SHIFT1")
9908 (match_test "optimize_function_for_size_p (cfun)")))
9909 (const_string "0")
9910 (const_string "*")))
9911 (set_attr "mode" "QI")])
9912
9913 ;; This pattern can't accept a variable shift count, since shifts by
9914 ;; zero don't affect the flags. We assume that shifts by constant
9915 ;; zero are optimized away.
9916 (define_insn "*<shiftrt_insn><mode>3_cmp"
9917 [(set (reg FLAGS_REG)
9918 (compare
9919 (any_shiftrt:SWI
9920 (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 (any_shiftrt: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 && ix86_match_ccmode (insn, CCGOCmode)
9930 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9931 {
9932 if (operands[2] == const1_rtx
9933 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9934 return "<shiftrt>{<imodesuffix>}\t%0";
9935 else
9936 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9937 }
9938 [(set_attr "type" "ishift")
9939 (set (attr "length_immediate")
9940 (if_then_else
9941 (and (match_operand 2 "const1_operand" "")
9942 (ior (match_test "TARGET_SHIFT1")
9943 (match_test "optimize_function_for_size_p (cfun)")))
9944 (const_string "0")
9945 (const_string "*")))
9946 (set_attr "mode" "<MODE>")])
9947
9948 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9949 [(set (reg FLAGS_REG)
9950 (compare
9951 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9952 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9953 (const_int 0)))
9954 (set (match_operand:DI 0 "register_operand" "=r")
9955 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9956 "TARGET_64BIT
9957 && (optimize_function_for_size_p (cfun)
9958 || !TARGET_PARTIAL_FLAG_REG_STALL
9959 || (operands[2] == const1_rtx
9960 && TARGET_SHIFT1))
9961 && ix86_match_ccmode (insn, CCGOCmode)
9962 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9963 {
9964 if (operands[2] == const1_rtx
9965 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9966 return "<shiftrt>{l}\t%k0";
9967 else
9968 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9969 }
9970 [(set_attr "type" "ishift")
9971 (set (attr "length_immediate")
9972 (if_then_else
9973 (and (match_operand 2 "const1_operand" "")
9974 (ior (match_test "TARGET_SHIFT1")
9975 (match_test "optimize_function_for_size_p (cfun)")))
9976 (const_string "0")
9977 (const_string "*")))
9978 (set_attr "mode" "SI")])
9979
9980 (define_insn "*<shiftrt_insn><mode>3_cconly"
9981 [(set (reg FLAGS_REG)
9982 (compare
9983 (any_shiftrt:SWI
9984 (match_operand:SWI 1 "register_operand" "0")
9985 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9986 (const_int 0)))
9987 (clobber (match_scratch:SWI 0 "=<r>"))]
9988 "(optimize_function_for_size_p (cfun)
9989 || !TARGET_PARTIAL_FLAG_REG_STALL
9990 || (operands[2] == const1_rtx
9991 && TARGET_SHIFT1))
9992 && ix86_match_ccmode (insn, CCGOCmode)"
9993 {
9994 if (operands[2] == const1_rtx
9995 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9996 return "<shiftrt>{<imodesuffix>}\t%0";
9997 else
9998 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9999 }
10000 [(set_attr "type" "ishift")
10001 (set (attr "length_immediate")
10002 (if_then_else
10003 (and (match_operand 2 "const1_operand" "")
10004 (ior (match_test "TARGET_SHIFT1")
10005 (match_test "optimize_function_for_size_p (cfun)")))
10006 (const_string "0")
10007 (const_string "*")))
10008 (set_attr "mode" "<MODE>")])
10009 \f
10010 ;; Rotate instructions
10011
10012 (define_expand "<rotate_insn>ti3"
10013 [(set (match_operand:TI 0 "register_operand" "")
10014 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10015 (match_operand:QI 2 "nonmemory_operand" "")))]
10016 "TARGET_64BIT"
10017 {
10018 if (const_1_to_63_operand (operands[2], VOIDmode))
10019 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10020 (operands[0], operands[1], operands[2]));
10021 else
10022 FAIL;
10023
10024 DONE;
10025 })
10026
10027 (define_expand "<rotate_insn>di3"
10028 [(set (match_operand:DI 0 "shiftdi_operand" "")
10029 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10030 (match_operand:QI 2 "nonmemory_operand" "")))]
10031 ""
10032 {
10033 if (TARGET_64BIT)
10034 ix86_expand_binary_operator (<CODE>, DImode, operands);
10035 else if (const_1_to_31_operand (operands[2], VOIDmode))
10036 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10037 (operands[0], operands[1], operands[2]));
10038 else
10039 FAIL;
10040
10041 DONE;
10042 })
10043
10044 (define_expand "<rotate_insn><mode>3"
10045 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10046 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10047 (match_operand:QI 2 "nonmemory_operand" "")))]
10048 ""
10049 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10050
10051 ;; Avoid useless masking of count operand.
10052 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10053 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10054 (any_rotate:SWI48
10055 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10056 (subreg:QI
10057 (and:SI
10058 (match_operand:SI 2 "nonimmediate_operand" "c")
10059 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10060 (clobber (reg:CC FLAGS_REG))]
10061 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10062 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10063 == GET_MODE_BITSIZE (<MODE>mode)-1"
10064 "#"
10065 "&& 1"
10066 [(parallel [(set (match_dup 0)
10067 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10068 (clobber (reg:CC FLAGS_REG))])]
10069 {
10070 if (can_create_pseudo_p ())
10071 operands [2] = force_reg (SImode, operands[2]);
10072
10073 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10074 }
10075 [(set_attr "type" "rotate")
10076 (set_attr "mode" "<MODE>")])
10077
10078 ;; Implement rotation using two double-precision
10079 ;; shift instructions and a scratch register.
10080
10081 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10082 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10083 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10084 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10085 (clobber (reg:CC FLAGS_REG))
10086 (clobber (match_scratch:DWIH 3 "=&r"))]
10087 ""
10088 "#"
10089 "reload_completed"
10090 [(set (match_dup 3) (match_dup 4))
10091 (parallel
10092 [(set (match_dup 4)
10093 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10094 (lshiftrt:DWIH (match_dup 5)
10095 (minus:QI (match_dup 6) (match_dup 2)))))
10096 (clobber (reg:CC FLAGS_REG))])
10097 (parallel
10098 [(set (match_dup 5)
10099 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10100 (lshiftrt:DWIH (match_dup 3)
10101 (minus:QI (match_dup 6) (match_dup 2)))))
10102 (clobber (reg:CC FLAGS_REG))])]
10103 {
10104 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10105
10106 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10107 })
10108
10109 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10110 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10111 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10112 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10113 (clobber (reg:CC FLAGS_REG))
10114 (clobber (match_scratch:DWIH 3 "=&r"))]
10115 ""
10116 "#"
10117 "reload_completed"
10118 [(set (match_dup 3) (match_dup 4))
10119 (parallel
10120 [(set (match_dup 4)
10121 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10122 (ashift:DWIH (match_dup 5)
10123 (minus:QI (match_dup 6) (match_dup 2)))))
10124 (clobber (reg:CC FLAGS_REG))])
10125 (parallel
10126 [(set (match_dup 5)
10127 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10128 (ashift:DWIH (match_dup 3)
10129 (minus:QI (match_dup 6) (match_dup 2)))))
10130 (clobber (reg:CC FLAGS_REG))])]
10131 {
10132 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10133
10134 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10135 })
10136
10137 (define_insn "*bmi2_rorx<mode>3_1"
10138 [(set (match_operand:SWI48 0 "register_operand" "=r")
10139 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10140 (match_operand:QI 2 "immediate_operand" "<S>")))]
10141 "TARGET_BMI2"
10142 "rorx\t{%2, %1, %0|%0, %1, %2}"
10143 [(set_attr "type" "rotatex")
10144 (set_attr "mode" "<MODE>")])
10145
10146 (define_insn "*<rotate_insn><mode>3_1"
10147 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10148 (any_rotate:SWI48
10149 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10150 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10151 (clobber (reg:CC FLAGS_REG))]
10152 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10153 {
10154 switch (get_attr_type (insn))
10155 {
10156 case TYPE_ROTATEX:
10157 return "#";
10158
10159 default:
10160 if (operands[2] == const1_rtx
10161 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10162 return "<rotate>{<imodesuffix>}\t%0";
10163 else
10164 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10165 }
10166 }
10167 [(set_attr "isa" "*,bmi2")
10168 (set_attr "type" "rotate,rotatex")
10169 (set (attr "length_immediate")
10170 (if_then_else
10171 (and (eq_attr "type" "rotate")
10172 (and (match_operand 2 "const1_operand" "")
10173 (ior (match_test "TARGET_SHIFT1")
10174 (match_test "optimize_function_for_size_p (cfun)"))))
10175 (const_string "0")
10176 (const_string "*")))
10177 (set_attr "mode" "<MODE>")])
10178
10179 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10180 (define_split
10181 [(set (match_operand:SWI48 0 "register_operand" "")
10182 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10183 (match_operand:QI 2 "immediate_operand" "")))
10184 (clobber (reg:CC FLAGS_REG))]
10185 "TARGET_BMI2 && reload_completed"
10186 [(set (match_dup 0)
10187 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10188 {
10189 operands[2]
10190 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10191 })
10192
10193 (define_split
10194 [(set (match_operand:SWI48 0 "register_operand" "")
10195 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10196 (match_operand:QI 2 "immediate_operand" "")))
10197 (clobber (reg:CC FLAGS_REG))]
10198 "TARGET_BMI2 && reload_completed"
10199 [(set (match_dup 0)
10200 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10201
10202 (define_insn "*bmi2_rorxsi3_1_zext"
10203 [(set (match_operand:DI 0 "register_operand" "=r")
10204 (zero_extend:DI
10205 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10206 (match_operand:QI 2 "immediate_operand" "I"))))]
10207 "TARGET_64BIT && TARGET_BMI2"
10208 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10209 [(set_attr "type" "rotatex")
10210 (set_attr "mode" "SI")])
10211
10212 (define_insn "*<rotate_insn>si3_1_zext"
10213 [(set (match_operand:DI 0 "register_operand" "=r,r")
10214 (zero_extend:DI
10215 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10216 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10217 (clobber (reg:CC FLAGS_REG))]
10218 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10219 {
10220 switch (get_attr_type (insn))
10221 {
10222 case TYPE_ROTATEX:
10223 return "#";
10224
10225 default:
10226 if (operands[2] == const1_rtx
10227 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10228 return "<rotate>{l}\t%k0";
10229 else
10230 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10231 }
10232 }
10233 [(set_attr "isa" "*,bmi2")
10234 (set_attr "type" "rotate,rotatex")
10235 (set (attr "length_immediate")
10236 (if_then_else
10237 (and (eq_attr "type" "rotate")
10238 (and (match_operand 2 "const1_operand" "")
10239 (ior (match_test "TARGET_SHIFT1")
10240 (match_test "optimize_function_for_size_p (cfun)"))))
10241 (const_string "0")
10242 (const_string "*")))
10243 (set_attr "mode" "SI")])
10244
10245 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10246 (define_split
10247 [(set (match_operand:DI 0 "register_operand" "")
10248 (zero_extend:DI
10249 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10250 (match_operand:QI 2 "immediate_operand" ""))))
10251 (clobber (reg:CC FLAGS_REG))]
10252 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10253 [(set (match_dup 0)
10254 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10255 {
10256 operands[2]
10257 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10258 })
10259
10260 (define_split
10261 [(set (match_operand:DI 0 "register_operand" "")
10262 (zero_extend:DI
10263 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10264 (match_operand:QI 2 "immediate_operand" ""))))
10265 (clobber (reg:CC FLAGS_REG))]
10266 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10267 [(set (match_dup 0)
10268 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10269
10270 (define_insn "*<rotate_insn><mode>3_1"
10271 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10272 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10273 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10274 (clobber (reg:CC FLAGS_REG))]
10275 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10276 {
10277 if (operands[2] == const1_rtx
10278 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10279 return "<rotate>{<imodesuffix>}\t%0";
10280 else
10281 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10282 }
10283 [(set_attr "type" "rotate")
10284 (set (attr "length_immediate")
10285 (if_then_else
10286 (and (match_operand 2 "const1_operand" "")
10287 (ior (match_test "TARGET_SHIFT1")
10288 (match_test "optimize_function_for_size_p (cfun)")))
10289 (const_string "0")
10290 (const_string "*")))
10291 (set_attr "mode" "<MODE>")])
10292
10293 (define_insn "*<rotate_insn>qi3_1_slp"
10294 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10295 (any_rotate:QI (match_dup 0)
10296 (match_operand:QI 1 "nonmemory_operand" "cI")))
10297 (clobber (reg:CC FLAGS_REG))]
10298 "(optimize_function_for_size_p (cfun)
10299 || !TARGET_PARTIAL_REG_STALL
10300 || (operands[1] == const1_rtx
10301 && TARGET_SHIFT1))"
10302 {
10303 if (operands[1] == const1_rtx
10304 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10305 return "<rotate>{b}\t%0";
10306 else
10307 return "<rotate>{b}\t{%1, %0|%0, %1}";
10308 }
10309 [(set_attr "type" "rotate1")
10310 (set (attr "length_immediate")
10311 (if_then_else
10312 (and (match_operand 1 "const1_operand" "")
10313 (ior (match_test "TARGET_SHIFT1")
10314 (match_test "optimize_function_for_size_p (cfun)")))
10315 (const_string "0")
10316 (const_string "*")))
10317 (set_attr "mode" "QI")])
10318
10319 (define_split
10320 [(set (match_operand:HI 0 "register_operand" "")
10321 (any_rotate:HI (match_dup 0) (const_int 8)))
10322 (clobber (reg:CC FLAGS_REG))]
10323 "reload_completed
10324 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10325 [(parallel [(set (strict_low_part (match_dup 0))
10326 (bswap:HI (match_dup 0)))
10327 (clobber (reg:CC FLAGS_REG))])])
10328 \f
10329 ;; Bit set / bit test instructions
10330
10331 (define_expand "extv"
10332 [(set (match_operand:SI 0 "register_operand" "")
10333 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10334 (match_operand:SI 2 "const8_operand" "")
10335 (match_operand:SI 3 "const8_operand" "")))]
10336 ""
10337 {
10338 /* Handle extractions from %ah et al. */
10339 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10340 FAIL;
10341
10342 /* From mips.md: extract_bit_field doesn't verify that our source
10343 matches the predicate, so check it again here. */
10344 if (! ext_register_operand (operands[1], VOIDmode))
10345 FAIL;
10346 })
10347
10348 (define_expand "extzv"
10349 [(set (match_operand:SI 0 "register_operand" "")
10350 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10351 (match_operand:SI 2 "const8_operand" "")
10352 (match_operand:SI 3 "const8_operand" "")))]
10353 ""
10354 {
10355 /* Handle extractions from %ah et al. */
10356 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10357 FAIL;
10358
10359 /* From mips.md: extract_bit_field doesn't verify that our source
10360 matches the predicate, so check it again here. */
10361 if (! ext_register_operand (operands[1], VOIDmode))
10362 FAIL;
10363 })
10364
10365 (define_expand "insv"
10366 [(set (zero_extract (match_operand 0 "register_operand" "")
10367 (match_operand 1 "const_int_operand" "")
10368 (match_operand 2 "const_int_operand" ""))
10369 (match_operand 3 "register_operand" ""))]
10370 ""
10371 {
10372 rtx (*gen_mov_insv_1) (rtx, rtx);
10373
10374 if (ix86_expand_pinsr (operands))
10375 DONE;
10376
10377 /* Handle insertions to %ah et al. */
10378 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10379 FAIL;
10380
10381 /* From mips.md: insert_bit_field doesn't verify that our source
10382 matches the predicate, so check it again here. */
10383 if (! ext_register_operand (operands[0], VOIDmode))
10384 FAIL;
10385
10386 gen_mov_insv_1 = (TARGET_64BIT
10387 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10388
10389 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10390 DONE;
10391 })
10392
10393 ;; %%% bts, btr, btc, bt.
10394 ;; In general these instructions are *slow* when applied to memory,
10395 ;; since they enforce atomic operation. When applied to registers,
10396 ;; it depends on the cpu implementation. They're never faster than
10397 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10398 ;; no point. But in 64-bit, we can't hold the relevant immediates
10399 ;; within the instruction itself, so operating on bits in the high
10400 ;; 32-bits of a register becomes easier.
10401 ;;
10402 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10403 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10404 ;; negdf respectively, so they can never be disabled entirely.
10405
10406 (define_insn "*btsq"
10407 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10408 (const_int 1)
10409 (match_operand:DI 1 "const_0_to_63_operand" ""))
10410 (const_int 1))
10411 (clobber (reg:CC FLAGS_REG))]
10412 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10413 "bts{q}\t{%1, %0|%0, %1}"
10414 [(set_attr "type" "alu1")
10415 (set_attr "prefix_0f" "1")
10416 (set_attr "mode" "DI")])
10417
10418 (define_insn "*btrq"
10419 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10420 (const_int 1)
10421 (match_operand:DI 1 "const_0_to_63_operand" ""))
10422 (const_int 0))
10423 (clobber (reg:CC FLAGS_REG))]
10424 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10425 "btr{q}\t{%1, %0|%0, %1}"
10426 [(set_attr "type" "alu1")
10427 (set_attr "prefix_0f" "1")
10428 (set_attr "mode" "DI")])
10429
10430 (define_insn "*btcq"
10431 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10432 (const_int 1)
10433 (match_operand:DI 1 "const_0_to_63_operand" ""))
10434 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10435 (clobber (reg:CC FLAGS_REG))]
10436 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10437 "btc{q}\t{%1, %0|%0, %1}"
10438 [(set_attr "type" "alu1")
10439 (set_attr "prefix_0f" "1")
10440 (set_attr "mode" "DI")])
10441
10442 ;; Allow Nocona to avoid these instructions if a register is available.
10443
10444 (define_peephole2
10445 [(match_scratch:DI 2 "r")
10446 (parallel [(set (zero_extract:DI
10447 (match_operand:DI 0 "register_operand" "")
10448 (const_int 1)
10449 (match_operand:DI 1 "const_0_to_63_operand" ""))
10450 (const_int 1))
10451 (clobber (reg:CC FLAGS_REG))])]
10452 "TARGET_64BIT && !TARGET_USE_BT"
10453 [(const_int 0)]
10454 {
10455 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10456 rtx op1;
10457
10458 if (HOST_BITS_PER_WIDE_INT >= 64)
10459 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10460 else if (i < HOST_BITS_PER_WIDE_INT)
10461 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10462 else
10463 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10464
10465 op1 = immed_double_const (lo, hi, DImode);
10466 if (i >= 31)
10467 {
10468 emit_move_insn (operands[2], op1);
10469 op1 = operands[2];
10470 }
10471
10472 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10473 DONE;
10474 })
10475
10476 (define_peephole2
10477 [(match_scratch:DI 2 "r")
10478 (parallel [(set (zero_extract:DI
10479 (match_operand:DI 0 "register_operand" "")
10480 (const_int 1)
10481 (match_operand:DI 1 "const_0_to_63_operand" ""))
10482 (const_int 0))
10483 (clobber (reg:CC FLAGS_REG))])]
10484 "TARGET_64BIT && !TARGET_USE_BT"
10485 [(const_int 0)]
10486 {
10487 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10488 rtx op1;
10489
10490 if (HOST_BITS_PER_WIDE_INT >= 64)
10491 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10492 else if (i < HOST_BITS_PER_WIDE_INT)
10493 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10494 else
10495 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10496
10497 op1 = immed_double_const (~lo, ~hi, DImode);
10498 if (i >= 32)
10499 {
10500 emit_move_insn (operands[2], op1);
10501 op1 = operands[2];
10502 }
10503
10504 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10505 DONE;
10506 })
10507
10508 (define_peephole2
10509 [(match_scratch:DI 2 "r")
10510 (parallel [(set (zero_extract:DI
10511 (match_operand:DI 0 "register_operand" "")
10512 (const_int 1)
10513 (match_operand:DI 1 "const_0_to_63_operand" ""))
10514 (not:DI (zero_extract:DI
10515 (match_dup 0) (const_int 1) (match_dup 1))))
10516 (clobber (reg:CC FLAGS_REG))])]
10517 "TARGET_64BIT && !TARGET_USE_BT"
10518 [(const_int 0)]
10519 {
10520 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10521 rtx op1;
10522
10523 if (HOST_BITS_PER_WIDE_INT >= 64)
10524 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10525 else if (i < HOST_BITS_PER_WIDE_INT)
10526 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10527 else
10528 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10529
10530 op1 = immed_double_const (lo, hi, DImode);
10531 if (i >= 31)
10532 {
10533 emit_move_insn (operands[2], op1);
10534 op1 = operands[2];
10535 }
10536
10537 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10538 DONE;
10539 })
10540
10541 (define_insn "*bt<mode>"
10542 [(set (reg:CCC FLAGS_REG)
10543 (compare:CCC
10544 (zero_extract:SWI48
10545 (match_operand:SWI48 0 "register_operand" "r")
10546 (const_int 1)
10547 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10548 (const_int 0)))]
10549 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10550 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10551 [(set_attr "type" "alu1")
10552 (set_attr "prefix_0f" "1")
10553 (set_attr "mode" "<MODE>")])
10554 \f
10555 ;; Store-flag instructions.
10556
10557 ;; For all sCOND expanders, also expand the compare or test insn that
10558 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10559
10560 (define_insn_and_split "*setcc_di_1"
10561 [(set (match_operand:DI 0 "register_operand" "=q")
10562 (match_operator:DI 1 "ix86_comparison_operator"
10563 [(reg FLAGS_REG) (const_int 0)]))]
10564 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10565 "#"
10566 "&& reload_completed"
10567 [(set (match_dup 2) (match_dup 1))
10568 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10569 {
10570 PUT_MODE (operands[1], QImode);
10571 operands[2] = gen_lowpart (QImode, operands[0]);
10572 })
10573
10574 (define_insn_and_split "*setcc_si_1_and"
10575 [(set (match_operand:SI 0 "register_operand" "=q")
10576 (match_operator:SI 1 "ix86_comparison_operator"
10577 [(reg FLAGS_REG) (const_int 0)]))
10578 (clobber (reg:CC FLAGS_REG))]
10579 "!TARGET_PARTIAL_REG_STALL
10580 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10581 "#"
10582 "&& reload_completed"
10583 [(set (match_dup 2) (match_dup 1))
10584 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10585 (clobber (reg:CC FLAGS_REG))])]
10586 {
10587 PUT_MODE (operands[1], QImode);
10588 operands[2] = gen_lowpart (QImode, operands[0]);
10589 })
10590
10591 (define_insn_and_split "*setcc_si_1_movzbl"
10592 [(set (match_operand:SI 0 "register_operand" "=q")
10593 (match_operator:SI 1 "ix86_comparison_operator"
10594 [(reg FLAGS_REG) (const_int 0)]))]
10595 "!TARGET_PARTIAL_REG_STALL
10596 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10597 "#"
10598 "&& reload_completed"
10599 [(set (match_dup 2) (match_dup 1))
10600 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10601 {
10602 PUT_MODE (operands[1], QImode);
10603 operands[2] = gen_lowpart (QImode, operands[0]);
10604 })
10605
10606 (define_insn "*setcc_qi"
10607 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10608 (match_operator:QI 1 "ix86_comparison_operator"
10609 [(reg FLAGS_REG) (const_int 0)]))]
10610 ""
10611 "set%C1\t%0"
10612 [(set_attr "type" "setcc")
10613 (set_attr "mode" "QI")])
10614
10615 (define_insn "*setcc_qi_slp"
10616 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10617 (match_operator:QI 1 "ix86_comparison_operator"
10618 [(reg FLAGS_REG) (const_int 0)]))]
10619 ""
10620 "set%C1\t%0"
10621 [(set_attr "type" "setcc")
10622 (set_attr "mode" "QI")])
10623
10624 ;; In general it is not safe to assume too much about CCmode registers,
10625 ;; so simplify-rtx stops when it sees a second one. Under certain
10626 ;; conditions this is safe on x86, so help combine not create
10627 ;;
10628 ;; seta %al
10629 ;; testb %al, %al
10630 ;; sete %al
10631
10632 (define_split
10633 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10634 (ne:QI (match_operator 1 "ix86_comparison_operator"
10635 [(reg FLAGS_REG) (const_int 0)])
10636 (const_int 0)))]
10637 ""
10638 [(set (match_dup 0) (match_dup 1))]
10639 "PUT_MODE (operands[1], QImode);")
10640
10641 (define_split
10642 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10643 (ne:QI (match_operator 1 "ix86_comparison_operator"
10644 [(reg FLAGS_REG) (const_int 0)])
10645 (const_int 0)))]
10646 ""
10647 [(set (match_dup 0) (match_dup 1))]
10648 "PUT_MODE (operands[1], QImode);")
10649
10650 (define_split
10651 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10652 (eq:QI (match_operator 1 "ix86_comparison_operator"
10653 [(reg FLAGS_REG) (const_int 0)])
10654 (const_int 0)))]
10655 ""
10656 [(set (match_dup 0) (match_dup 1))]
10657 {
10658 rtx new_op1 = copy_rtx (operands[1]);
10659 operands[1] = new_op1;
10660 PUT_MODE (new_op1, QImode);
10661 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10662 GET_MODE (XEXP (new_op1, 0))));
10663
10664 /* Make sure that (a) the CCmode we have for the flags is strong
10665 enough for the reversed compare or (b) we have a valid FP compare. */
10666 if (! ix86_comparison_operator (new_op1, VOIDmode))
10667 FAIL;
10668 })
10669
10670 (define_split
10671 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10672 (eq:QI (match_operator 1 "ix86_comparison_operator"
10673 [(reg FLAGS_REG) (const_int 0)])
10674 (const_int 0)))]
10675 ""
10676 [(set (match_dup 0) (match_dup 1))]
10677 {
10678 rtx new_op1 = copy_rtx (operands[1]);
10679 operands[1] = new_op1;
10680 PUT_MODE (new_op1, QImode);
10681 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10682 GET_MODE (XEXP (new_op1, 0))));
10683
10684 /* Make sure that (a) the CCmode we have for the flags is strong
10685 enough for the reversed compare or (b) we have a valid FP compare. */
10686 if (! ix86_comparison_operator (new_op1, VOIDmode))
10687 FAIL;
10688 })
10689
10690 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10691 ;; subsequent logical operations are used to imitate conditional moves.
10692 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10693 ;; it directly.
10694
10695 (define_insn "setcc_<mode>_sse"
10696 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10697 (match_operator:MODEF 3 "sse_comparison_operator"
10698 [(match_operand:MODEF 1 "register_operand" "0,x")
10699 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10700 "SSE_FLOAT_MODE_P (<MODE>mode)"
10701 "@
10702 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10703 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10704 [(set_attr "isa" "noavx,avx")
10705 (set_attr "type" "ssecmp")
10706 (set_attr "length_immediate" "1")
10707 (set_attr "prefix" "orig,vex")
10708 (set_attr "mode" "<MODE>")])
10709 \f
10710 ;; Basic conditional jump instructions.
10711 ;; We ignore the overflow flag for signed branch instructions.
10712
10713 (define_insn "*jcc_1"
10714 [(set (pc)
10715 (if_then_else (match_operator 1 "ix86_comparison_operator"
10716 [(reg FLAGS_REG) (const_int 0)])
10717 (label_ref (match_operand 0 "" ""))
10718 (pc)))]
10719 ""
10720 "%+j%C1\t%l0"
10721 [(set_attr "type" "ibr")
10722 (set_attr "modrm" "0")
10723 (set (attr "length")
10724 (if_then_else (and (ge (minus (match_dup 0) (pc))
10725 (const_int -126))
10726 (lt (minus (match_dup 0) (pc))
10727 (const_int 128)))
10728 (const_int 2)
10729 (const_int 6)))])
10730
10731 (define_insn "*jcc_2"
10732 [(set (pc)
10733 (if_then_else (match_operator 1 "ix86_comparison_operator"
10734 [(reg FLAGS_REG) (const_int 0)])
10735 (pc)
10736 (label_ref (match_operand 0 "" ""))))]
10737 ""
10738 "%+j%c1\t%l0"
10739 [(set_attr "type" "ibr")
10740 (set_attr "modrm" "0")
10741 (set (attr "length")
10742 (if_then_else (and (ge (minus (match_dup 0) (pc))
10743 (const_int -126))
10744 (lt (minus (match_dup 0) (pc))
10745 (const_int 128)))
10746 (const_int 2)
10747 (const_int 6)))])
10748
10749 ;; In general it is not safe to assume too much about CCmode registers,
10750 ;; so simplify-rtx stops when it sees a second one. Under certain
10751 ;; conditions this is safe on x86, so help combine not create
10752 ;;
10753 ;; seta %al
10754 ;; testb %al, %al
10755 ;; je Lfoo
10756
10757 (define_split
10758 [(set (pc)
10759 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10760 [(reg FLAGS_REG) (const_int 0)])
10761 (const_int 0))
10762 (label_ref (match_operand 1 "" ""))
10763 (pc)))]
10764 ""
10765 [(set (pc)
10766 (if_then_else (match_dup 0)
10767 (label_ref (match_dup 1))
10768 (pc)))]
10769 "PUT_MODE (operands[0], VOIDmode);")
10770
10771 (define_split
10772 [(set (pc)
10773 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10774 [(reg FLAGS_REG) (const_int 0)])
10775 (const_int 0))
10776 (label_ref (match_operand 1 "" ""))
10777 (pc)))]
10778 ""
10779 [(set (pc)
10780 (if_then_else (match_dup 0)
10781 (label_ref (match_dup 1))
10782 (pc)))]
10783 {
10784 rtx new_op0 = copy_rtx (operands[0]);
10785 operands[0] = new_op0;
10786 PUT_MODE (new_op0, VOIDmode);
10787 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10788 GET_MODE (XEXP (new_op0, 0))));
10789
10790 /* Make sure that (a) the CCmode we have for the flags is strong
10791 enough for the reversed compare or (b) we have a valid FP compare. */
10792 if (! ix86_comparison_operator (new_op0, VOIDmode))
10793 FAIL;
10794 })
10795
10796 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10797 ;; pass generates from shift insn with QImode operand. Actually, the mode
10798 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10799 ;; appropriate modulo of the bit offset value.
10800
10801 (define_insn_and_split "*jcc_bt<mode>"
10802 [(set (pc)
10803 (if_then_else (match_operator 0 "bt_comparison_operator"
10804 [(zero_extract:SWI48
10805 (match_operand:SWI48 1 "register_operand" "r")
10806 (const_int 1)
10807 (zero_extend:SI
10808 (match_operand:QI 2 "register_operand" "r")))
10809 (const_int 0)])
10810 (label_ref (match_operand 3 "" ""))
10811 (pc)))
10812 (clobber (reg:CC FLAGS_REG))]
10813 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10814 "#"
10815 "&& 1"
10816 [(set (reg:CCC FLAGS_REG)
10817 (compare:CCC
10818 (zero_extract:SWI48
10819 (match_dup 1)
10820 (const_int 1)
10821 (match_dup 2))
10822 (const_int 0)))
10823 (set (pc)
10824 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10825 (label_ref (match_dup 3))
10826 (pc)))]
10827 {
10828 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10829
10830 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10831 })
10832
10833 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10834 ;; also for DImode, this is what combine produces.
10835 (define_insn_and_split "*jcc_bt<mode>_mask"
10836 [(set (pc)
10837 (if_then_else (match_operator 0 "bt_comparison_operator"
10838 [(zero_extract:SWI48
10839 (match_operand:SWI48 1 "register_operand" "r")
10840 (const_int 1)
10841 (and:SI
10842 (match_operand:SI 2 "register_operand" "r")
10843 (match_operand:SI 3 "const_int_operand" "n")))])
10844 (label_ref (match_operand 4 "" ""))
10845 (pc)))
10846 (clobber (reg:CC FLAGS_REG))]
10847 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10848 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10849 == GET_MODE_BITSIZE (<MODE>mode)-1"
10850 "#"
10851 "&& 1"
10852 [(set (reg:CCC FLAGS_REG)
10853 (compare:CCC
10854 (zero_extract:SWI48
10855 (match_dup 1)
10856 (const_int 1)
10857 (match_dup 2))
10858 (const_int 0)))
10859 (set (pc)
10860 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10861 (label_ref (match_dup 4))
10862 (pc)))]
10863 {
10864 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10865
10866 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10867 })
10868
10869 (define_insn_and_split "*jcc_btsi_1"
10870 [(set (pc)
10871 (if_then_else (match_operator 0 "bt_comparison_operator"
10872 [(and:SI
10873 (lshiftrt:SI
10874 (match_operand:SI 1 "register_operand" "r")
10875 (match_operand:QI 2 "register_operand" "r"))
10876 (const_int 1))
10877 (const_int 0)])
10878 (label_ref (match_operand 3 "" ""))
10879 (pc)))
10880 (clobber (reg:CC FLAGS_REG))]
10881 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10882 "#"
10883 "&& 1"
10884 [(set (reg:CCC FLAGS_REG)
10885 (compare:CCC
10886 (zero_extract:SI
10887 (match_dup 1)
10888 (const_int 1)
10889 (match_dup 2))
10890 (const_int 0)))
10891 (set (pc)
10892 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10893 (label_ref (match_dup 3))
10894 (pc)))]
10895 {
10896 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10897
10898 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10899 })
10900
10901 ;; avoid useless masking of bit offset operand
10902 (define_insn_and_split "*jcc_btsi_mask_1"
10903 [(set (pc)
10904 (if_then_else
10905 (match_operator 0 "bt_comparison_operator"
10906 [(and:SI
10907 (lshiftrt:SI
10908 (match_operand:SI 1 "register_operand" "r")
10909 (subreg:QI
10910 (and:SI
10911 (match_operand:SI 2 "register_operand" "r")
10912 (match_operand:SI 3 "const_int_operand" "n")) 0))
10913 (const_int 1))
10914 (const_int 0)])
10915 (label_ref (match_operand 4 "" ""))
10916 (pc)))
10917 (clobber (reg:CC FLAGS_REG))]
10918 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10919 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10920 "#"
10921 "&& 1"
10922 [(set (reg:CCC FLAGS_REG)
10923 (compare:CCC
10924 (zero_extract:SI
10925 (match_dup 1)
10926 (const_int 1)
10927 (match_dup 2))
10928 (const_int 0)))
10929 (set (pc)
10930 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10931 (label_ref (match_dup 4))
10932 (pc)))]
10933 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10934
10935 ;; Define combination compare-and-branch fp compare instructions to help
10936 ;; combine.
10937
10938 (define_insn "*fp_jcc_1_387"
10939 [(set (pc)
10940 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10941 [(match_operand 1 "register_operand" "f")
10942 (match_operand 2 "nonimmediate_operand" "fm")])
10943 (label_ref (match_operand 3 "" ""))
10944 (pc)))
10945 (clobber (reg:CCFP FPSR_REG))
10946 (clobber (reg:CCFP FLAGS_REG))
10947 (clobber (match_scratch:HI 4 "=a"))]
10948 "TARGET_80387
10949 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10950 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10951 && SELECT_CC_MODE (GET_CODE (operands[0]),
10952 operands[1], operands[2]) == CCFPmode
10953 && !TARGET_CMOVE"
10954 "#")
10955
10956 (define_insn "*fp_jcc_1r_387"
10957 [(set (pc)
10958 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10959 [(match_operand 1 "register_operand" "f")
10960 (match_operand 2 "nonimmediate_operand" "fm")])
10961 (pc)
10962 (label_ref (match_operand 3 "" ""))))
10963 (clobber (reg:CCFP FPSR_REG))
10964 (clobber (reg:CCFP FLAGS_REG))
10965 (clobber (match_scratch:HI 4 "=a"))]
10966 "TARGET_80387
10967 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10968 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10969 && SELECT_CC_MODE (GET_CODE (operands[0]),
10970 operands[1], operands[2]) == CCFPmode
10971 && !TARGET_CMOVE"
10972 "#")
10973
10974 (define_insn "*fp_jcc_2_387"
10975 [(set (pc)
10976 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10977 [(match_operand 1 "register_operand" "f")
10978 (match_operand 2 "register_operand" "f")])
10979 (label_ref (match_operand 3 "" ""))
10980 (pc)))
10981 (clobber (reg:CCFP FPSR_REG))
10982 (clobber (reg:CCFP FLAGS_REG))
10983 (clobber (match_scratch:HI 4 "=a"))]
10984 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10985 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10986 && !TARGET_CMOVE"
10987 "#")
10988
10989 (define_insn "*fp_jcc_2r_387"
10990 [(set (pc)
10991 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10992 [(match_operand 1 "register_operand" "f")
10993 (match_operand 2 "register_operand" "f")])
10994 (pc)
10995 (label_ref (match_operand 3 "" ""))))
10996 (clobber (reg:CCFP FPSR_REG))
10997 (clobber (reg:CCFP FLAGS_REG))
10998 (clobber (match_scratch:HI 4 "=a"))]
10999 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11000 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11001 && !TARGET_CMOVE"
11002 "#")
11003
11004 (define_insn "*fp_jcc_3_387"
11005 [(set (pc)
11006 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11007 [(match_operand 1 "register_operand" "f")
11008 (match_operand 2 "const0_operand" "")])
11009 (label_ref (match_operand 3 "" ""))
11010 (pc)))
11011 (clobber (reg:CCFP FPSR_REG))
11012 (clobber (reg:CCFP FLAGS_REG))
11013 (clobber (match_scratch:HI 4 "=a"))]
11014 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11015 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11016 && SELECT_CC_MODE (GET_CODE (operands[0]),
11017 operands[1], operands[2]) == CCFPmode
11018 && !TARGET_CMOVE"
11019 "#")
11020
11021 (define_split
11022 [(set (pc)
11023 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11024 [(match_operand 1 "register_operand" "")
11025 (match_operand 2 "nonimmediate_operand" "")])
11026 (match_operand 3 "" "")
11027 (match_operand 4 "" "")))
11028 (clobber (reg:CCFP FPSR_REG))
11029 (clobber (reg:CCFP FLAGS_REG))]
11030 "reload_completed"
11031 [(const_int 0)]
11032 {
11033 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11034 operands[3], operands[4], NULL_RTX, NULL_RTX);
11035 DONE;
11036 })
11037
11038 (define_split
11039 [(set (pc)
11040 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11041 [(match_operand 1 "register_operand" "")
11042 (match_operand 2 "general_operand" "")])
11043 (match_operand 3 "" "")
11044 (match_operand 4 "" "")))
11045 (clobber (reg:CCFP FPSR_REG))
11046 (clobber (reg:CCFP FLAGS_REG))
11047 (clobber (match_scratch:HI 5 "=a"))]
11048 "reload_completed"
11049 [(const_int 0)]
11050 {
11051 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11052 operands[3], operands[4], operands[5], NULL_RTX);
11053 DONE;
11054 })
11055
11056 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11057 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11058 ;; with a precedence over other operators and is always put in the first
11059 ;; place. Swap condition and operands to match ficom instruction.
11060
11061 (define_insn "*fp_jcc_4_<mode>_387"
11062 [(set (pc)
11063 (if_then_else
11064 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11065 [(match_operator 1 "float_operator"
11066 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11067 (match_operand 3 "register_operand" "f,f")])
11068 (label_ref (match_operand 4 "" ""))
11069 (pc)))
11070 (clobber (reg:CCFP FPSR_REG))
11071 (clobber (reg:CCFP FLAGS_REG))
11072 (clobber (match_scratch:HI 5 "=a,a"))]
11073 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11074 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11075 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11076 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11077 && !TARGET_CMOVE"
11078 "#")
11079
11080 (define_split
11081 [(set (pc)
11082 (if_then_else
11083 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11084 [(match_operator 1 "float_operator"
11085 [(match_operand:SWI24 2 "memory_operand" "")])
11086 (match_operand 3 "register_operand" "")])
11087 (match_operand 4 "" "")
11088 (match_operand 5 "" "")))
11089 (clobber (reg:CCFP FPSR_REG))
11090 (clobber (reg:CCFP FLAGS_REG))
11091 (clobber (match_scratch:HI 6 "=a"))]
11092 "reload_completed"
11093 [(const_int 0)]
11094 {
11095 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11096
11097 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11098 operands[3], operands[7],
11099 operands[4], operands[5], operands[6], NULL_RTX);
11100 DONE;
11101 })
11102
11103 ;; %%% Kill this when reload knows how to do it.
11104 (define_split
11105 [(set (pc)
11106 (if_then_else
11107 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11108 [(match_operator 1 "float_operator"
11109 [(match_operand:SWI24 2 "register_operand" "")])
11110 (match_operand 3 "register_operand" "")])
11111 (match_operand 4 "" "")
11112 (match_operand 5 "" "")))
11113 (clobber (reg:CCFP FPSR_REG))
11114 (clobber (reg:CCFP FLAGS_REG))
11115 (clobber (match_scratch:HI 6 "=a"))]
11116 "reload_completed"
11117 [(const_int 0)]
11118 {
11119 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11120 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11121
11122 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11123 operands[3], operands[7],
11124 operands[4], operands[5], operands[6], operands[2]);
11125 DONE;
11126 })
11127 \f
11128 ;; Unconditional and other jump instructions
11129
11130 (define_insn "jump"
11131 [(set (pc)
11132 (label_ref (match_operand 0 "" "")))]
11133 ""
11134 "jmp\t%l0"
11135 [(set_attr "type" "ibr")
11136 (set (attr "length")
11137 (if_then_else (and (ge (minus (match_dup 0) (pc))
11138 (const_int -126))
11139 (lt (minus (match_dup 0) (pc))
11140 (const_int 128)))
11141 (const_int 2)
11142 (const_int 5)))
11143 (set_attr "modrm" "0")])
11144
11145 (define_expand "indirect_jump"
11146 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11147
11148 (define_insn "*indirect_jump"
11149 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11150 ""
11151 "jmp\t%A0"
11152 [(set_attr "type" "ibr")
11153 (set_attr "length_immediate" "0")])
11154
11155 (define_expand "tablejump"
11156 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11157 (use (label_ref (match_operand 1 "" "")))])]
11158 ""
11159 {
11160 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11161 relative. Convert the relative address to an absolute address. */
11162 if (flag_pic)
11163 {
11164 rtx op0, op1;
11165 enum rtx_code code;
11166
11167 /* We can't use @GOTOFF for text labels on VxWorks;
11168 see gotoff_operand. */
11169 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11170 {
11171 code = PLUS;
11172 op0 = operands[0];
11173 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11174 }
11175 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11176 {
11177 code = PLUS;
11178 op0 = operands[0];
11179 op1 = pic_offset_table_rtx;
11180 }
11181 else
11182 {
11183 code = MINUS;
11184 op0 = pic_offset_table_rtx;
11185 op1 = operands[0];
11186 }
11187
11188 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11189 OPTAB_DIRECT);
11190 }
11191 else if (TARGET_X32)
11192 operands[0] = convert_memory_address (Pmode, operands[0]);
11193 })
11194
11195 (define_insn "*tablejump_1"
11196 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11197 (use (label_ref (match_operand 1 "" "")))]
11198 ""
11199 "jmp\t%A0"
11200 [(set_attr "type" "ibr")
11201 (set_attr "length_immediate" "0")])
11202 \f
11203 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11204
11205 (define_peephole2
11206 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11207 (set (match_operand:QI 1 "register_operand" "")
11208 (match_operator:QI 2 "ix86_comparison_operator"
11209 [(reg FLAGS_REG) (const_int 0)]))
11210 (set (match_operand 3 "q_regs_operand" "")
11211 (zero_extend (match_dup 1)))]
11212 "(peep2_reg_dead_p (3, operands[1])
11213 || operands_match_p (operands[1], operands[3]))
11214 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11215 [(set (match_dup 4) (match_dup 0))
11216 (set (strict_low_part (match_dup 5))
11217 (match_dup 2))]
11218 {
11219 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11220 operands[5] = gen_lowpart (QImode, operands[3]);
11221 ix86_expand_clear (operands[3]);
11222 })
11223
11224 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11225
11226 (define_peephole2
11227 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11228 (set (match_operand:QI 1 "register_operand" "")
11229 (match_operator:QI 2 "ix86_comparison_operator"
11230 [(reg FLAGS_REG) (const_int 0)]))
11231 (parallel [(set (match_operand 3 "q_regs_operand" "")
11232 (zero_extend (match_dup 1)))
11233 (clobber (reg:CC FLAGS_REG))])]
11234 "(peep2_reg_dead_p (3, operands[1])
11235 || operands_match_p (operands[1], operands[3]))
11236 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11237 [(set (match_dup 4) (match_dup 0))
11238 (set (strict_low_part (match_dup 5))
11239 (match_dup 2))]
11240 {
11241 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11242 operands[5] = gen_lowpart (QImode, operands[3]);
11243 ix86_expand_clear (operands[3]);
11244 })
11245 \f
11246 ;; Call instructions.
11247
11248 ;; The predicates normally associated with named expanders are not properly
11249 ;; checked for calls. This is a bug in the generic code, but it isn't that
11250 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11251
11252 ;; P6 processors will jump to the address after the decrement when %esp
11253 ;; is used as a call operand, so they will execute return address as a code.
11254 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11255
11256 ;; Register constraint for call instruction.
11257 (define_mode_attr c [(SI "l") (DI "r")])
11258
11259 ;; Call subroutine returning no value.
11260
11261 (define_expand "call"
11262 [(call (match_operand:QI 0 "" "")
11263 (match_operand 1 "" ""))
11264 (use (match_operand 2 "" ""))]
11265 ""
11266 {
11267 ix86_expand_call (NULL, operands[0], operands[1],
11268 operands[2], NULL, false);
11269 DONE;
11270 })
11271
11272 (define_expand "sibcall"
11273 [(call (match_operand:QI 0 "" "")
11274 (match_operand 1 "" ""))
11275 (use (match_operand 2 "" ""))]
11276 ""
11277 {
11278 ix86_expand_call (NULL, operands[0], operands[1],
11279 operands[2], NULL, true);
11280 DONE;
11281 })
11282
11283 (define_insn_and_split "*call_vzeroupper"
11284 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11285 (match_operand 1 "" ""))
11286 (unspec [(match_operand 2 "const_int_operand" "")]
11287 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11288 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11289 "#"
11290 "&& reload_completed"
11291 [(const_int 0)]
11292 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11293 [(set_attr "type" "call")])
11294
11295 (define_insn "*call"
11296 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11297 (match_operand 1 "" ""))]
11298 "!SIBLING_CALL_P (insn)"
11299 "* return ix86_output_call_insn (insn, operands[0]);"
11300 [(set_attr "type" "call")])
11301
11302 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11303 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11304 (match_operand 1 "" ""))
11305 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11306 (clobber (reg:TI XMM6_REG))
11307 (clobber (reg:TI XMM7_REG))
11308 (clobber (reg:TI XMM8_REG))
11309 (clobber (reg:TI XMM9_REG))
11310 (clobber (reg:TI XMM10_REG))
11311 (clobber (reg:TI XMM11_REG))
11312 (clobber (reg:TI XMM12_REG))
11313 (clobber (reg:TI XMM13_REG))
11314 (clobber (reg:TI XMM14_REG))
11315 (clobber (reg:TI XMM15_REG))
11316 (clobber (reg:DI SI_REG))
11317 (clobber (reg:DI DI_REG))
11318 (unspec [(match_operand 2 "const_int_operand" "")]
11319 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11320 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11321 "#"
11322 "&& reload_completed"
11323 [(const_int 0)]
11324 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11325 [(set_attr "type" "call")])
11326
11327 (define_insn "*call_rex64_ms_sysv"
11328 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11329 (match_operand 1 "" ""))
11330 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11331 (clobber (reg:TI XMM6_REG))
11332 (clobber (reg:TI XMM7_REG))
11333 (clobber (reg:TI XMM8_REG))
11334 (clobber (reg:TI XMM9_REG))
11335 (clobber (reg:TI XMM10_REG))
11336 (clobber (reg:TI XMM11_REG))
11337 (clobber (reg:TI XMM12_REG))
11338 (clobber (reg:TI XMM13_REG))
11339 (clobber (reg:TI XMM14_REG))
11340 (clobber (reg:TI XMM15_REG))
11341 (clobber (reg:DI SI_REG))
11342 (clobber (reg:DI DI_REG))]
11343 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11344 "* return ix86_output_call_insn (insn, operands[0]);"
11345 [(set_attr "type" "call")])
11346
11347 (define_insn_and_split "*sibcall_vzeroupper"
11348 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11349 (match_operand 1 "" ""))
11350 (unspec [(match_operand 2 "const_int_operand" "")]
11351 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11352 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11353 "#"
11354 "&& reload_completed"
11355 [(const_int 0)]
11356 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11357 [(set_attr "type" "call")])
11358
11359 (define_insn "*sibcall"
11360 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11361 (match_operand 1 "" ""))]
11362 "SIBLING_CALL_P (insn)"
11363 "* return ix86_output_call_insn (insn, operands[0]);"
11364 [(set_attr "type" "call")])
11365
11366 (define_expand "call_pop"
11367 [(parallel [(call (match_operand:QI 0 "" "")
11368 (match_operand:SI 1 "" ""))
11369 (set (reg:SI SP_REG)
11370 (plus:SI (reg:SI SP_REG)
11371 (match_operand:SI 3 "" "")))])]
11372 "!TARGET_64BIT"
11373 {
11374 ix86_expand_call (NULL, operands[0], operands[1],
11375 operands[2], operands[3], false);
11376 DONE;
11377 })
11378
11379 (define_insn_and_split "*call_pop_vzeroupper"
11380 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11381 (match_operand:SI 1 "" ""))
11382 (set (reg:SI SP_REG)
11383 (plus:SI (reg:SI SP_REG)
11384 (match_operand:SI 2 "immediate_operand" "i")))
11385 (unspec [(match_operand 3 "const_int_operand" "")]
11386 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11387 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11388 "#"
11389 "&& reload_completed"
11390 [(const_int 0)]
11391 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11392 [(set_attr "type" "call")])
11393
11394 (define_insn "*call_pop"
11395 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11396 (match_operand 1 "" ""))
11397 (set (reg:SI SP_REG)
11398 (plus:SI (reg:SI SP_REG)
11399 (match_operand:SI 2 "immediate_operand" "i")))]
11400 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11401 "* return ix86_output_call_insn (insn, operands[0]);"
11402 [(set_attr "type" "call")])
11403
11404 (define_insn_and_split "*sibcall_pop_vzeroupper"
11405 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11406 (match_operand 1 "" ""))
11407 (set (reg:SI SP_REG)
11408 (plus:SI (reg:SI SP_REG)
11409 (match_operand:SI 2 "immediate_operand" "i")))
11410 (unspec [(match_operand 3 "const_int_operand" "")]
11411 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11412 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11413 "#"
11414 "&& reload_completed"
11415 [(const_int 0)]
11416 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11417 [(set_attr "type" "call")])
11418
11419 (define_insn "*sibcall_pop"
11420 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11421 (match_operand 1 "" ""))
11422 (set (reg:SI SP_REG)
11423 (plus:SI (reg:SI SP_REG)
11424 (match_operand:SI 2 "immediate_operand" "i")))]
11425 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11426 "* return ix86_output_call_insn (insn, operands[0]);"
11427 [(set_attr "type" "call")])
11428
11429 ;; Call subroutine, returning value in operand 0
11430
11431 (define_expand "call_value"
11432 [(set (match_operand 0 "" "")
11433 (call (match_operand:QI 1 "" "")
11434 (match_operand 2 "" "")))
11435 (use (match_operand 3 "" ""))]
11436 ""
11437 {
11438 ix86_expand_call (operands[0], operands[1], operands[2],
11439 operands[3], NULL, false);
11440 DONE;
11441 })
11442
11443 (define_expand "sibcall_value"
11444 [(set (match_operand 0 "" "")
11445 (call (match_operand:QI 1 "" "")
11446 (match_operand 2 "" "")))
11447 (use (match_operand 3 "" ""))]
11448 ""
11449 {
11450 ix86_expand_call (operands[0], operands[1], operands[2],
11451 operands[3], NULL, true);
11452 DONE;
11453 })
11454
11455 (define_insn_and_split "*call_value_vzeroupper"
11456 [(set (match_operand 0 "" "")
11457 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11458 (match_operand 2 "" "")))
11459 (unspec [(match_operand 3 "const_int_operand" "")]
11460 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11461 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11462 "#"
11463 "&& reload_completed"
11464 [(const_int 0)]
11465 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11466 [(set_attr "type" "callv")])
11467
11468 (define_insn "*call_value"
11469 [(set (match_operand 0 "" "")
11470 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11471 (match_operand 2 "" "")))]
11472 "!SIBLING_CALL_P (insn)"
11473 "* return ix86_output_call_insn (insn, operands[1]);"
11474 [(set_attr "type" "callv")])
11475
11476 (define_insn_and_split "*sibcall_value_vzeroupper"
11477 [(set (match_operand 0 "" "")
11478 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11479 (match_operand 2 "" "")))
11480 (unspec [(match_operand 3 "const_int_operand" "")]
11481 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11482 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11483 "#"
11484 "&& reload_completed"
11485 [(const_int 0)]
11486 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11487 [(set_attr "type" "callv")])
11488
11489 (define_insn "*sibcall_value"
11490 [(set (match_operand 0 "" "")
11491 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11492 (match_operand 2 "" "")))]
11493 "SIBLING_CALL_P (insn)"
11494 "* return ix86_output_call_insn (insn, operands[1]);"
11495 [(set_attr "type" "callv")])
11496
11497 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11498 [(set (match_operand 0 "" "")
11499 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11500 (match_operand 2 "" "")))
11501 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11502 (clobber (reg:TI XMM6_REG))
11503 (clobber (reg:TI XMM7_REG))
11504 (clobber (reg:TI XMM8_REG))
11505 (clobber (reg:TI XMM9_REG))
11506 (clobber (reg:TI XMM10_REG))
11507 (clobber (reg:TI XMM11_REG))
11508 (clobber (reg:TI XMM12_REG))
11509 (clobber (reg:TI XMM13_REG))
11510 (clobber (reg:TI XMM14_REG))
11511 (clobber (reg:TI XMM15_REG))
11512 (clobber (reg:DI SI_REG))
11513 (clobber (reg:DI DI_REG))
11514 (unspec [(match_operand 3 "const_int_operand" "")]
11515 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11516 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11517 "#"
11518 "&& reload_completed"
11519 [(const_int 0)]
11520 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11521 [(set_attr "type" "callv")])
11522
11523 (define_insn "*call_value_rex64_ms_sysv"
11524 [(set (match_operand 0 "" "")
11525 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11526 (match_operand 2 "" "")))
11527 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11528 (clobber (reg:TI XMM6_REG))
11529 (clobber (reg:TI XMM7_REG))
11530 (clobber (reg:TI XMM8_REG))
11531 (clobber (reg:TI XMM9_REG))
11532 (clobber (reg:TI XMM10_REG))
11533 (clobber (reg:TI XMM11_REG))
11534 (clobber (reg:TI XMM12_REG))
11535 (clobber (reg:TI XMM13_REG))
11536 (clobber (reg:TI XMM14_REG))
11537 (clobber (reg:TI XMM15_REG))
11538 (clobber (reg:DI SI_REG))
11539 (clobber (reg:DI DI_REG))]
11540 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11541 "* return ix86_output_call_insn (insn, operands[1]);"
11542 [(set_attr "type" "callv")])
11543
11544 (define_expand "call_value_pop"
11545 [(parallel [(set (match_operand 0 "" "")
11546 (call (match_operand:QI 1 "" "")
11547 (match_operand:SI 2 "" "")))
11548 (set (reg:SI SP_REG)
11549 (plus:SI (reg:SI SP_REG)
11550 (match_operand:SI 4 "" "")))])]
11551 "!TARGET_64BIT"
11552 {
11553 ix86_expand_call (operands[0], operands[1], operands[2],
11554 operands[3], operands[4], false);
11555 DONE;
11556 })
11557
11558 (define_insn_and_split "*call_value_pop_vzeroupper"
11559 [(set (match_operand 0 "" "")
11560 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11561 (match_operand 2 "" "")))
11562 (set (reg:SI SP_REG)
11563 (plus:SI (reg:SI SP_REG)
11564 (match_operand:SI 3 "immediate_operand" "i")))
11565 (unspec [(match_operand 4 "const_int_operand" "")]
11566 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11567 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11568 "#"
11569 "&& reload_completed"
11570 [(const_int 0)]
11571 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11572 [(set_attr "type" "callv")])
11573
11574 (define_insn "*call_value_pop"
11575 [(set (match_operand 0 "" "")
11576 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11577 (match_operand 2 "" "")))
11578 (set (reg:SI SP_REG)
11579 (plus:SI (reg:SI SP_REG)
11580 (match_operand:SI 3 "immediate_operand" "i")))]
11581 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11582 "* return ix86_output_call_insn (insn, operands[1]);"
11583 [(set_attr "type" "callv")])
11584
11585 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11586 [(set (match_operand 0 "" "")
11587 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11588 (match_operand 2 "" "")))
11589 (set (reg:SI SP_REG)
11590 (plus:SI (reg:SI SP_REG)
11591 (match_operand:SI 3 "immediate_operand" "i")))
11592 (unspec [(match_operand 4 "const_int_operand" "")]
11593 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11594 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11595 "#"
11596 "&& reload_completed"
11597 [(const_int 0)]
11598 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11599 [(set_attr "type" "callv")])
11600
11601 (define_insn "*sibcall_value_pop"
11602 [(set (match_operand 0 "" "")
11603 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11604 (match_operand 2 "" "")))
11605 (set (reg:SI SP_REG)
11606 (plus:SI (reg:SI SP_REG)
11607 (match_operand:SI 3 "immediate_operand" "i")))]
11608 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11609 "* return ix86_output_call_insn (insn, operands[1]);"
11610 [(set_attr "type" "callv")])
11611
11612 ;; Call subroutine returning any type.
11613
11614 (define_expand "untyped_call"
11615 [(parallel [(call (match_operand 0 "" "")
11616 (const_int 0))
11617 (match_operand 1 "" "")
11618 (match_operand 2 "" "")])]
11619 ""
11620 {
11621 int i;
11622
11623 /* In order to give reg-stack an easier job in validating two
11624 coprocessor registers as containing a possible return value,
11625 simply pretend the untyped call returns a complex long double
11626 value.
11627
11628 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11629 and should have the default ABI. */
11630
11631 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11632 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11633 operands[0], const0_rtx,
11634 GEN_INT ((TARGET_64BIT
11635 ? (ix86_abi == SYSV_ABI
11636 ? X86_64_SSE_REGPARM_MAX
11637 : X86_64_MS_SSE_REGPARM_MAX)
11638 : X86_32_SSE_REGPARM_MAX)
11639 - 1),
11640 NULL, false);
11641
11642 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11643 {
11644 rtx set = XVECEXP (operands[2], 0, i);
11645 emit_move_insn (SET_DEST (set), SET_SRC (set));
11646 }
11647
11648 /* The optimizer does not know that the call sets the function value
11649 registers we stored in the result block. We avoid problems by
11650 claiming that all hard registers are used and clobbered at this
11651 point. */
11652 emit_insn (gen_blockage ());
11653
11654 DONE;
11655 })
11656 \f
11657 ;; Prologue and epilogue instructions
11658
11659 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11660 ;; all of memory. This blocks insns from being moved across this point.
11661
11662 (define_insn "blockage"
11663 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11664 ""
11665 ""
11666 [(set_attr "length" "0")])
11667
11668 ;; Do not schedule instructions accessing memory across this point.
11669
11670 (define_expand "memory_blockage"
11671 [(set (match_dup 0)
11672 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11673 ""
11674 {
11675 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11676 MEM_VOLATILE_P (operands[0]) = 1;
11677 })
11678
11679 (define_insn "*memory_blockage"
11680 [(set (match_operand:BLK 0 "" "")
11681 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11682 ""
11683 ""
11684 [(set_attr "length" "0")])
11685
11686 ;; As USE insns aren't meaningful after reload, this is used instead
11687 ;; to prevent deleting instructions setting registers for PIC code
11688 (define_insn "prologue_use"
11689 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11690 ""
11691 ""
11692 [(set_attr "length" "0")])
11693
11694 ;; Insn emitted into the body of a function to return from a function.
11695 ;; This is only done if the function's epilogue is known to be simple.
11696 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11697
11698 (define_expand "return"
11699 [(simple_return)]
11700 "ix86_can_use_return_insn_p ()"
11701 {
11702 if (crtl->args.pops_args)
11703 {
11704 rtx popc = GEN_INT (crtl->args.pops_args);
11705 emit_jump_insn (gen_simple_return_pop_internal (popc));
11706 DONE;
11707 }
11708 })
11709
11710 ;; We need to disable this for TARGET_SEH, as otherwise
11711 ;; shrink-wrapped prologue gets enabled too. This might exceed
11712 ;; the maximum size of prologue in unwind information.
11713
11714 (define_expand "simple_return"
11715 [(simple_return)]
11716 "!TARGET_SEH"
11717 {
11718 if (crtl->args.pops_args)
11719 {
11720 rtx popc = GEN_INT (crtl->args.pops_args);
11721 emit_jump_insn (gen_simple_return_pop_internal (popc));
11722 DONE;
11723 }
11724 })
11725
11726 (define_insn "simple_return_internal"
11727 [(simple_return)]
11728 "reload_completed"
11729 "ret"
11730 [(set_attr "length" "1")
11731 (set_attr "atom_unit" "jeu")
11732 (set_attr "length_immediate" "0")
11733 (set_attr "modrm" "0")])
11734
11735 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11736 ;; instruction Athlon and K8 have.
11737
11738 (define_insn "simple_return_internal_long"
11739 [(simple_return)
11740 (unspec [(const_int 0)] UNSPEC_REP)]
11741 "reload_completed"
11742 "rep\;ret"
11743 [(set_attr "length" "2")
11744 (set_attr "atom_unit" "jeu")
11745 (set_attr "length_immediate" "0")
11746 (set_attr "prefix_rep" "1")
11747 (set_attr "modrm" "0")])
11748
11749 (define_insn "simple_return_pop_internal"
11750 [(simple_return)
11751 (use (match_operand:SI 0 "const_int_operand" ""))]
11752 "reload_completed"
11753 "ret\t%0"
11754 [(set_attr "length" "3")
11755 (set_attr "atom_unit" "jeu")
11756 (set_attr "length_immediate" "2")
11757 (set_attr "modrm" "0")])
11758
11759 (define_insn "simple_return_indirect_internal"
11760 [(simple_return)
11761 (use (match_operand:SI 0 "register_operand" "r"))]
11762 "reload_completed"
11763 "jmp\t%A0"
11764 [(set_attr "type" "ibr")
11765 (set_attr "length_immediate" "0")])
11766
11767 (define_insn "nop"
11768 [(const_int 0)]
11769 ""
11770 "nop"
11771 [(set_attr "length" "1")
11772 (set_attr "length_immediate" "0")
11773 (set_attr "modrm" "0")])
11774
11775 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11776 (define_insn "nops"
11777 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11778 UNSPECV_NOPS)]
11779 "reload_completed"
11780 {
11781 int num = INTVAL (operands[0]);
11782
11783 gcc_assert (num >= 1 && num <= 8);
11784
11785 while (num--)
11786 fputs ("\tnop\n", asm_out_file);
11787
11788 return "";
11789 }
11790 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11791 (set_attr "length_immediate" "0")
11792 (set_attr "modrm" "0")])
11793
11794 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11795 ;; branch prediction penalty for the third jump in a 16-byte
11796 ;; block on K8.
11797
11798 (define_insn "pad"
11799 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11800 ""
11801 {
11802 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11803 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11804 #else
11805 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11806 The align insn is used to avoid 3 jump instructions in the row to improve
11807 branch prediction and the benefits hardly outweigh the cost of extra 8
11808 nops on the average inserted by full alignment pseudo operation. */
11809 #endif
11810 return "";
11811 }
11812 [(set_attr "length" "16")])
11813
11814 (define_expand "prologue"
11815 [(const_int 0)]
11816 ""
11817 "ix86_expand_prologue (); DONE;")
11818
11819 (define_insn "set_got"
11820 [(set (match_operand:SI 0 "register_operand" "=r")
11821 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11822 (clobber (reg:CC FLAGS_REG))]
11823 "!TARGET_64BIT"
11824 "* return output_set_got (operands[0], NULL_RTX);"
11825 [(set_attr "type" "multi")
11826 (set_attr "length" "12")])
11827
11828 (define_insn "set_got_labelled"
11829 [(set (match_operand:SI 0 "register_operand" "=r")
11830 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11831 UNSPEC_SET_GOT))
11832 (clobber (reg:CC FLAGS_REG))]
11833 "!TARGET_64BIT"
11834 "* return output_set_got (operands[0], operands[1]);"
11835 [(set_attr "type" "multi")
11836 (set_attr "length" "12")])
11837
11838 (define_insn "set_got_rex64"
11839 [(set (match_operand:DI 0 "register_operand" "=r")
11840 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11841 "TARGET_64BIT"
11842 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11843 [(set_attr "type" "lea")
11844 (set_attr "length_address" "4")
11845 (set_attr "mode" "DI")])
11846
11847 (define_insn "set_rip_rex64"
11848 [(set (match_operand:DI 0 "register_operand" "=r")
11849 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11850 "TARGET_64BIT"
11851 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11852 [(set_attr "type" "lea")
11853 (set_attr "length_address" "4")
11854 (set_attr "mode" "DI")])
11855
11856 (define_insn "set_got_offset_rex64"
11857 [(set (match_operand:DI 0 "register_operand" "=r")
11858 (unspec:DI
11859 [(label_ref (match_operand 1 "" ""))]
11860 UNSPEC_SET_GOT_OFFSET))]
11861 "TARGET_LP64"
11862 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11863 [(set_attr "type" "imov")
11864 (set_attr "length_immediate" "0")
11865 (set_attr "length_address" "8")
11866 (set_attr "mode" "DI")])
11867
11868 (define_expand "epilogue"
11869 [(const_int 0)]
11870 ""
11871 "ix86_expand_epilogue (1); DONE;")
11872
11873 (define_expand "sibcall_epilogue"
11874 [(const_int 0)]
11875 ""
11876 "ix86_expand_epilogue (0); DONE;")
11877
11878 (define_expand "eh_return"
11879 [(use (match_operand 0 "register_operand" ""))]
11880 ""
11881 {
11882 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11883
11884 /* Tricky bit: we write the address of the handler to which we will
11885 be returning into someone else's stack frame, one word below the
11886 stack address we wish to restore. */
11887 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11888 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11889 tmp = gen_rtx_MEM (Pmode, tmp);
11890 emit_move_insn (tmp, ra);
11891
11892 emit_jump_insn (gen_eh_return_internal ());
11893 emit_barrier ();
11894 DONE;
11895 })
11896
11897 (define_insn_and_split "eh_return_internal"
11898 [(eh_return)]
11899 ""
11900 "#"
11901 "epilogue_completed"
11902 [(const_int 0)]
11903 "ix86_expand_epilogue (2); DONE;")
11904
11905 (define_insn "leave"
11906 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11907 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11908 (clobber (mem:BLK (scratch)))]
11909 "!TARGET_64BIT"
11910 "leave"
11911 [(set_attr "type" "leave")])
11912
11913 (define_insn "leave_rex64"
11914 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11915 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11916 (clobber (mem:BLK (scratch)))]
11917 "TARGET_64BIT"
11918 "leave"
11919 [(set_attr "type" "leave")])
11920 \f
11921 ;; Handle -fsplit-stack.
11922
11923 (define_expand "split_stack_prologue"
11924 [(const_int 0)]
11925 ""
11926 {
11927 ix86_expand_split_stack_prologue ();
11928 DONE;
11929 })
11930
11931 ;; In order to support the call/return predictor, we use a return
11932 ;; instruction which the middle-end doesn't see.
11933 (define_insn "split_stack_return"
11934 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11935 UNSPECV_SPLIT_STACK_RETURN)]
11936 ""
11937 {
11938 if (operands[0] == const0_rtx)
11939 return "ret";
11940 else
11941 return "ret\t%0";
11942 }
11943 [(set_attr "atom_unit" "jeu")
11944 (set_attr "modrm" "0")
11945 (set (attr "length")
11946 (if_then_else (match_operand:SI 0 "const0_operand" "")
11947 (const_int 1)
11948 (const_int 3)))
11949 (set (attr "length_immediate")
11950 (if_then_else (match_operand:SI 0 "const0_operand" "")
11951 (const_int 0)
11952 (const_int 2)))])
11953
11954 ;; If there are operand 0 bytes available on the stack, jump to
11955 ;; operand 1.
11956
11957 (define_expand "split_stack_space_check"
11958 [(set (pc) (if_then_else
11959 (ltu (minus (reg SP_REG)
11960 (match_operand 0 "register_operand" ""))
11961 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11962 (label_ref (match_operand 1 "" ""))
11963 (pc)))]
11964 ""
11965 {
11966 rtx reg, size, limit;
11967
11968 reg = gen_reg_rtx (Pmode);
11969 size = force_reg (Pmode, operands[0]);
11970 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11971 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11972 UNSPEC_STACK_CHECK);
11973 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11974 ix86_expand_branch (GEU, reg, limit, operands[1]);
11975
11976 DONE;
11977 })
11978 \f
11979 ;; Bit manipulation instructions.
11980
11981 (define_expand "ffs<mode>2"
11982 [(set (match_dup 2) (const_int -1))
11983 (parallel [(set (reg:CCZ FLAGS_REG)
11984 (compare:CCZ
11985 (match_operand:SWI48 1 "nonimmediate_operand" "")
11986 (const_int 0)))
11987 (set (match_operand:SWI48 0 "register_operand" "")
11988 (ctz:SWI48 (match_dup 1)))])
11989 (set (match_dup 0) (if_then_else:SWI48
11990 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11991 (match_dup 2)
11992 (match_dup 0)))
11993 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11994 (clobber (reg:CC FLAGS_REG))])]
11995 ""
11996 {
11997 if (<MODE>mode == SImode && !TARGET_CMOVE)
11998 {
11999 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12000 DONE;
12001 }
12002 operands[2] = gen_reg_rtx (<MODE>mode);
12003 })
12004
12005 (define_insn_and_split "ffssi2_no_cmove"
12006 [(set (match_operand:SI 0 "register_operand" "=r")
12007 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12008 (clobber (match_scratch:SI 2 "=&q"))
12009 (clobber (reg:CC FLAGS_REG))]
12010 "!TARGET_CMOVE"
12011 "#"
12012 "&& reload_completed"
12013 [(parallel [(set (reg:CCZ FLAGS_REG)
12014 (compare:CCZ (match_dup 1) (const_int 0)))
12015 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12016 (set (strict_low_part (match_dup 3))
12017 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12018 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12019 (clobber (reg:CC FLAGS_REG))])
12020 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12021 (clobber (reg:CC FLAGS_REG))])
12022 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12023 (clobber (reg:CC FLAGS_REG))])]
12024 {
12025 operands[3] = gen_lowpart (QImode, operands[2]);
12026 ix86_expand_clear (operands[2]);
12027 })
12028
12029 (define_insn "*ffs<mode>_1"
12030 [(set (reg:CCZ FLAGS_REG)
12031 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12032 (const_int 0)))
12033 (set (match_operand:SWI48 0 "register_operand" "=r")
12034 (ctz:SWI48 (match_dup 1)))]
12035 ""
12036 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12037 [(set_attr "type" "alu1")
12038 (set_attr "prefix_0f" "1")
12039 (set_attr "mode" "<MODE>")])
12040
12041 (define_insn "ctz<mode>2"
12042 [(set (match_operand:SWI248 0 "register_operand" "=r")
12043 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12044 (clobber (reg:CC FLAGS_REG))]
12045 ""
12046 {
12047 if (TARGET_BMI)
12048 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12049 else
12050 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12051 }
12052 [(set_attr "type" "alu1")
12053 (set_attr "prefix_0f" "1")
12054 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12055 (set_attr "mode" "<MODE>")])
12056
12057 (define_expand "clz<mode>2"
12058 [(parallel
12059 [(set (match_operand:SWI248 0 "register_operand" "")
12060 (minus:SWI248
12061 (match_dup 2)
12062 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12063 (clobber (reg:CC FLAGS_REG))])
12064 (parallel
12065 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12066 (clobber (reg:CC FLAGS_REG))])]
12067 ""
12068 {
12069 if (TARGET_LZCNT)
12070 {
12071 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12072 DONE;
12073 }
12074 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12075 })
12076
12077 (define_insn "clz<mode>2_lzcnt"
12078 [(set (match_operand:SWI248 0 "register_operand" "=r")
12079 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12080 (clobber (reg:CC FLAGS_REG))]
12081 "TARGET_LZCNT"
12082 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12083 [(set_attr "prefix_rep" "1")
12084 (set_attr "type" "bitmanip")
12085 (set_attr "mode" "<MODE>")])
12086
12087 ;; BMI instructions.
12088 (define_insn "*bmi_andn_<mode>"
12089 [(set (match_operand:SWI48 0 "register_operand" "=r")
12090 (and:SWI48
12091 (not:SWI48
12092 (match_operand:SWI48 1 "register_operand" "r"))
12093 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12094 (clobber (reg:CC FLAGS_REG))]
12095 "TARGET_BMI"
12096 "andn\t{%2, %1, %0|%0, %1, %2}"
12097 [(set_attr "type" "bitmanip")
12098 (set_attr "mode" "<MODE>")])
12099
12100 (define_insn "bmi_bextr_<mode>"
12101 [(set (match_operand:SWI48 0 "register_operand" "=r")
12102 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12103 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12104 UNSPEC_BEXTR))
12105 (clobber (reg:CC FLAGS_REG))]
12106 "TARGET_BMI"
12107 "bextr\t{%2, %1, %0|%0, %1, %2}"
12108 [(set_attr "type" "bitmanip")
12109 (set_attr "mode" "<MODE>")])
12110
12111 (define_insn "*bmi_blsi_<mode>"
12112 [(set (match_operand:SWI48 0 "register_operand" "=r")
12113 (and:SWI48
12114 (neg:SWI48
12115 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12116 (match_dup 1)))
12117 (clobber (reg:CC FLAGS_REG))]
12118 "TARGET_BMI"
12119 "blsi\t{%1, %0|%0, %1}"
12120 [(set_attr "type" "bitmanip")
12121 (set_attr "mode" "<MODE>")])
12122
12123 (define_insn "*bmi_blsmsk_<mode>"
12124 [(set (match_operand:SWI48 0 "register_operand" "=r")
12125 (xor:SWI48
12126 (plus:SWI48
12127 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12128 (const_int -1))
12129 (match_dup 1)))
12130 (clobber (reg:CC FLAGS_REG))]
12131 "TARGET_BMI"
12132 "blsmsk\t{%1, %0|%0, %1}"
12133 [(set_attr "type" "bitmanip")
12134 (set_attr "mode" "<MODE>")])
12135
12136 (define_insn "*bmi_blsr_<mode>"
12137 [(set (match_operand:SWI48 0 "register_operand" "=r")
12138 (and:SWI48
12139 (plus:SWI48
12140 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12141 (const_int -1))
12142 (match_dup 1)))
12143 (clobber (reg:CC FLAGS_REG))]
12144 "TARGET_BMI"
12145 "blsr\t{%1, %0|%0, %1}"
12146 [(set_attr "type" "bitmanip")
12147 (set_attr "mode" "<MODE>")])
12148
12149 ;; BMI2 instructions.
12150 (define_insn "bmi2_bzhi_<mode>3"
12151 [(set (match_operand:SWI48 0 "register_operand" "=r")
12152 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12153 (lshiftrt:SWI48 (const_int -1)
12154 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12155 (clobber (reg:CC FLAGS_REG))]
12156 "TARGET_BMI2"
12157 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12158 [(set_attr "type" "bitmanip")
12159 (set_attr "prefix" "vex")
12160 (set_attr "mode" "<MODE>")])
12161
12162 (define_insn "bmi2_pdep_<mode>3"
12163 [(set (match_operand:SWI48 0 "register_operand" "=r")
12164 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12165 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12166 UNSPEC_PDEP))]
12167 "TARGET_BMI2"
12168 "pdep\t{%2, %1, %0|%0, %1, %2}"
12169 [(set_attr "type" "bitmanip")
12170 (set_attr "prefix" "vex")
12171 (set_attr "mode" "<MODE>")])
12172
12173 (define_insn "bmi2_pext_<mode>3"
12174 [(set (match_operand:SWI48 0 "register_operand" "=r")
12175 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12176 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12177 UNSPEC_PEXT))]
12178 "TARGET_BMI2"
12179 "pext\t{%2, %1, %0|%0, %1, %2}"
12180 [(set_attr "type" "bitmanip")
12181 (set_attr "prefix" "vex")
12182 (set_attr "mode" "<MODE>")])
12183
12184 ;; TBM instructions.
12185 (define_insn "tbm_bextri_<mode>"
12186 [(set (match_operand:SWI48 0 "register_operand" "=r")
12187 (zero_extract:SWI48
12188 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12189 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12190 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12191 (clobber (reg:CC FLAGS_REG))]
12192 "TARGET_TBM"
12193 {
12194 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12195 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12196 }
12197 [(set_attr "type" "bitmanip")
12198 (set_attr "mode" "<MODE>")])
12199
12200 (define_insn "*tbm_blcfill_<mode>"
12201 [(set (match_operand:SWI48 0 "register_operand" "=r")
12202 (and:SWI48
12203 (plus:SWI48
12204 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12205 (const_int 1))
12206 (match_dup 1)))
12207 (clobber (reg:CC FLAGS_REG))]
12208 "TARGET_TBM"
12209 "blcfill\t{%1, %0|%0, %1}"
12210 [(set_attr "type" "bitmanip")
12211 (set_attr "mode" "<MODE>")])
12212
12213 (define_insn "*tbm_blci_<mode>"
12214 [(set (match_operand:SWI48 0 "register_operand" "=r")
12215 (ior:SWI48
12216 (not:SWI48
12217 (plus:SWI48
12218 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12219 (const_int 1)))
12220 (match_dup 1)))
12221 (clobber (reg:CC FLAGS_REG))]
12222 "TARGET_TBM"
12223 "blci\t{%1, %0|%0, %1}"
12224 [(set_attr "type" "bitmanip")
12225 (set_attr "mode" "<MODE>")])
12226
12227 (define_insn "*tbm_blcic_<mode>"
12228 [(set (match_operand:SWI48 0 "register_operand" "=r")
12229 (and:SWI48
12230 (plus:SWI48
12231 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12232 (const_int 1))
12233 (not:SWI48
12234 (match_dup 1))))
12235 (clobber (reg:CC FLAGS_REG))]
12236 "TARGET_TBM"
12237 "blcic\t{%1, %0|%0, %1}"
12238 [(set_attr "type" "bitmanip")
12239 (set_attr "mode" "<MODE>")])
12240
12241 (define_insn "*tbm_blcmsk_<mode>"
12242 [(set (match_operand:SWI48 0 "register_operand" "=r")
12243 (xor:SWI48
12244 (plus:SWI48
12245 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12246 (const_int 1))
12247 (match_dup 1)))
12248 (clobber (reg:CC FLAGS_REG))]
12249 "TARGET_TBM"
12250 "blcmsk\t{%1, %0|%0, %1}"
12251 [(set_attr "type" "bitmanip")
12252 (set_attr "mode" "<MODE>")])
12253
12254 (define_insn "*tbm_blcs_<mode>"
12255 [(set (match_operand:SWI48 0 "register_operand" "=r")
12256 (ior:SWI48
12257 (plus:SWI48
12258 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12259 (const_int 1))
12260 (match_dup 1)))
12261 (clobber (reg:CC FLAGS_REG))]
12262 "TARGET_TBM"
12263 "blcs\t{%1, %0|%0, %1}"
12264 [(set_attr "type" "bitmanip")
12265 (set_attr "mode" "<MODE>")])
12266
12267 (define_insn "*tbm_blsfill_<mode>"
12268 [(set (match_operand:SWI48 0 "register_operand" "=r")
12269 (ior:SWI48
12270 (plus:SWI48
12271 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12272 (const_int -1))
12273 (match_dup 1)))
12274 (clobber (reg:CC FLAGS_REG))]
12275 "TARGET_TBM"
12276 "blsfill\t{%1, %0|%0, %1}"
12277 [(set_attr "type" "bitmanip")
12278 (set_attr "mode" "<MODE>")])
12279
12280 (define_insn "*tbm_blsic_<mode>"
12281 [(set (match_operand:SWI48 0 "register_operand" "=r")
12282 (ior:SWI48
12283 (plus:SWI48
12284 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12285 (const_int -1))
12286 (not:SWI48
12287 (match_dup 1))))
12288 (clobber (reg:CC FLAGS_REG))]
12289 "TARGET_TBM"
12290 "blsic\t{%1, %0|%0, %1}"
12291 [(set_attr "type" "bitmanip")
12292 (set_attr "mode" "<MODE>")])
12293
12294 (define_insn "*tbm_t1mskc_<mode>"
12295 [(set (match_operand:SWI48 0 "register_operand" "=r")
12296 (ior:SWI48
12297 (plus:SWI48
12298 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12299 (const_int 1))
12300 (not:SWI48
12301 (match_dup 1))))
12302 (clobber (reg:CC FLAGS_REG))]
12303 "TARGET_TBM"
12304 "t1mskc\t{%1, %0|%0, %1}"
12305 [(set_attr "type" "bitmanip")
12306 (set_attr "mode" "<MODE>")])
12307
12308 (define_insn "*tbm_tzmsk_<mode>"
12309 [(set (match_operand:SWI48 0 "register_operand" "=r")
12310 (and:SWI48
12311 (plus:SWI48
12312 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12313 (const_int -1))
12314 (not:SWI48
12315 (match_dup 1))))
12316 (clobber (reg:CC FLAGS_REG))]
12317 "TARGET_TBM"
12318 "tzmsk\t{%1, %0|%0, %1}"
12319 [(set_attr "type" "bitmanip")
12320 (set_attr "mode" "<MODE>")])
12321
12322 (define_insn "bsr_rex64"
12323 [(set (match_operand:DI 0 "register_operand" "=r")
12324 (minus:DI (const_int 63)
12325 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12326 (clobber (reg:CC FLAGS_REG))]
12327 "TARGET_64BIT"
12328 "bsr{q}\t{%1, %0|%0, %1}"
12329 [(set_attr "type" "alu1")
12330 (set_attr "prefix_0f" "1")
12331 (set_attr "mode" "DI")])
12332
12333 (define_insn "bsr"
12334 [(set (match_operand:SI 0 "register_operand" "=r")
12335 (minus:SI (const_int 31)
12336 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12337 (clobber (reg:CC FLAGS_REG))]
12338 ""
12339 "bsr{l}\t{%1, %0|%0, %1}"
12340 [(set_attr "type" "alu1")
12341 (set_attr "prefix_0f" "1")
12342 (set_attr "mode" "SI")])
12343
12344 (define_insn "*bsrhi"
12345 [(set (match_operand:HI 0 "register_operand" "=r")
12346 (minus:HI (const_int 15)
12347 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12348 (clobber (reg:CC FLAGS_REG))]
12349 ""
12350 "bsr{w}\t{%1, %0|%0, %1}"
12351 [(set_attr "type" "alu1")
12352 (set_attr "prefix_0f" "1")
12353 (set_attr "mode" "HI")])
12354
12355 (define_insn "popcount<mode>2"
12356 [(set (match_operand:SWI248 0 "register_operand" "=r")
12357 (popcount:SWI248
12358 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12359 (clobber (reg:CC FLAGS_REG))]
12360 "TARGET_POPCNT"
12361 {
12362 #if TARGET_MACHO
12363 return "popcnt\t{%1, %0|%0, %1}";
12364 #else
12365 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12366 #endif
12367 }
12368 [(set_attr "prefix_rep" "1")
12369 (set_attr "type" "bitmanip")
12370 (set_attr "mode" "<MODE>")])
12371
12372 (define_insn "*popcount<mode>2_cmp"
12373 [(set (reg FLAGS_REG)
12374 (compare
12375 (popcount:SWI248
12376 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12377 (const_int 0)))
12378 (set (match_operand:SWI248 0 "register_operand" "=r")
12379 (popcount:SWI248 (match_dup 1)))]
12380 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12381 {
12382 #if TARGET_MACHO
12383 return "popcnt\t{%1, %0|%0, %1}";
12384 #else
12385 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12386 #endif
12387 }
12388 [(set_attr "prefix_rep" "1")
12389 (set_attr "type" "bitmanip")
12390 (set_attr "mode" "<MODE>")])
12391
12392 (define_insn "*popcountsi2_cmp_zext"
12393 [(set (reg FLAGS_REG)
12394 (compare
12395 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12396 (const_int 0)))
12397 (set (match_operand:DI 0 "register_operand" "=r")
12398 (zero_extend:DI(popcount:SI (match_dup 1))))]
12399 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12400 {
12401 #if TARGET_MACHO
12402 return "popcnt\t{%1, %0|%0, %1}";
12403 #else
12404 return "popcnt{l}\t{%1, %0|%0, %1}";
12405 #endif
12406 }
12407 [(set_attr "prefix_rep" "1")
12408 (set_attr "type" "bitmanip")
12409 (set_attr "mode" "SI")])
12410
12411 (define_expand "bswap<mode>2"
12412 [(set (match_operand:SWI48 0 "register_operand" "")
12413 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12414 ""
12415 {
12416 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12417 {
12418 rtx x = operands[0];
12419
12420 emit_move_insn (x, operands[1]);
12421 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12422 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12423 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12424 DONE;
12425 }
12426 })
12427
12428 (define_insn "*bswap<mode>2_movbe"
12429 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12430 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12431 "TARGET_MOVBE
12432 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12433 "@
12434 bswap\t%0
12435 movbe\t{%1, %0|%0, %1}
12436 movbe\t{%1, %0|%0, %1}"
12437 [(set_attr "type" "bitmanip,imov,imov")
12438 (set_attr "modrm" "0,1,1")
12439 (set_attr "prefix_0f" "*,1,1")
12440 (set_attr "prefix_extra" "*,1,1")
12441 (set_attr "mode" "<MODE>")])
12442
12443 (define_insn "*bswap<mode>2_1"
12444 [(set (match_operand:SWI48 0 "register_operand" "=r")
12445 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12446 "TARGET_BSWAP"
12447 "bswap\t%0"
12448 [(set_attr "type" "bitmanip")
12449 (set_attr "modrm" "0")
12450 (set_attr "mode" "<MODE>")])
12451
12452 (define_insn "*bswaphi_lowpart_1"
12453 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12454 (bswap:HI (match_dup 0)))
12455 (clobber (reg:CC FLAGS_REG))]
12456 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12457 "@
12458 xchg{b}\t{%h0, %b0|%b0, %h0}
12459 rol{w}\t{$8, %0|%0, 8}"
12460 [(set_attr "length" "2,4")
12461 (set_attr "mode" "QI,HI")])
12462
12463 (define_insn "bswaphi_lowpart"
12464 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12465 (bswap:HI (match_dup 0)))
12466 (clobber (reg:CC FLAGS_REG))]
12467 ""
12468 "rol{w}\t{$8, %0|%0, 8}"
12469 [(set_attr "length" "4")
12470 (set_attr "mode" "HI")])
12471
12472 (define_expand "paritydi2"
12473 [(set (match_operand:DI 0 "register_operand" "")
12474 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12475 "! TARGET_POPCNT"
12476 {
12477 rtx scratch = gen_reg_rtx (QImode);
12478 rtx cond;
12479
12480 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12481 NULL_RTX, operands[1]));
12482
12483 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12484 gen_rtx_REG (CCmode, FLAGS_REG),
12485 const0_rtx);
12486 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12487
12488 if (TARGET_64BIT)
12489 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12490 else
12491 {
12492 rtx tmp = gen_reg_rtx (SImode);
12493
12494 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12495 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12496 }
12497 DONE;
12498 })
12499
12500 (define_expand "paritysi2"
12501 [(set (match_operand:SI 0 "register_operand" "")
12502 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12503 "! TARGET_POPCNT"
12504 {
12505 rtx scratch = gen_reg_rtx (QImode);
12506 rtx cond;
12507
12508 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12509
12510 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12511 gen_rtx_REG (CCmode, FLAGS_REG),
12512 const0_rtx);
12513 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12514
12515 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12516 DONE;
12517 })
12518
12519 (define_insn_and_split "paritydi2_cmp"
12520 [(set (reg:CC FLAGS_REG)
12521 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12522 UNSPEC_PARITY))
12523 (clobber (match_scratch:DI 0 "=r"))
12524 (clobber (match_scratch:SI 1 "=&r"))
12525 (clobber (match_scratch:HI 2 "=Q"))]
12526 "! TARGET_POPCNT"
12527 "#"
12528 "&& reload_completed"
12529 [(parallel
12530 [(set (match_dup 1)
12531 (xor:SI (match_dup 1) (match_dup 4)))
12532 (clobber (reg:CC FLAGS_REG))])
12533 (parallel
12534 [(set (reg:CC FLAGS_REG)
12535 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12536 (clobber (match_dup 1))
12537 (clobber (match_dup 2))])]
12538 {
12539 operands[4] = gen_lowpart (SImode, operands[3]);
12540
12541 if (TARGET_64BIT)
12542 {
12543 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12544 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12545 }
12546 else
12547 operands[1] = gen_highpart (SImode, operands[3]);
12548 })
12549
12550 (define_insn_and_split "paritysi2_cmp"
12551 [(set (reg:CC FLAGS_REG)
12552 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12553 UNSPEC_PARITY))
12554 (clobber (match_scratch:SI 0 "=r"))
12555 (clobber (match_scratch:HI 1 "=&Q"))]
12556 "! TARGET_POPCNT"
12557 "#"
12558 "&& reload_completed"
12559 [(parallel
12560 [(set (match_dup 1)
12561 (xor:HI (match_dup 1) (match_dup 3)))
12562 (clobber (reg:CC FLAGS_REG))])
12563 (parallel
12564 [(set (reg:CC FLAGS_REG)
12565 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12566 (clobber (match_dup 1))])]
12567 {
12568 operands[3] = gen_lowpart (HImode, operands[2]);
12569
12570 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12571 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12572 })
12573
12574 (define_insn "*parityhi2_cmp"
12575 [(set (reg:CC FLAGS_REG)
12576 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12577 UNSPEC_PARITY))
12578 (clobber (match_scratch:HI 0 "=Q"))]
12579 "! TARGET_POPCNT"
12580 "xor{b}\t{%h0, %b0|%b0, %h0}"
12581 [(set_attr "length" "2")
12582 (set_attr "mode" "HI")])
12583
12584 \f
12585 ;; Thread-local storage patterns for ELF.
12586 ;;
12587 ;; Note that these code sequences must appear exactly as shown
12588 ;; in order to allow linker relaxation.
12589
12590 (define_insn "*tls_global_dynamic_32_gnu"
12591 [(set (match_operand:SI 0 "register_operand" "=a")
12592 (unspec:SI
12593 [(match_operand:SI 1 "register_operand" "b")
12594 (match_operand:SI 2 "tls_symbolic_operand" "")
12595 (match_operand:SI 3 "constant_call_address_operand" "z")]
12596 UNSPEC_TLS_GD))
12597 (clobber (match_scratch:SI 4 "=d"))
12598 (clobber (match_scratch:SI 5 "=c"))
12599 (clobber (reg:CC FLAGS_REG))]
12600 "!TARGET_64BIT && TARGET_GNU_TLS"
12601 {
12602 output_asm_insn
12603 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12604 if (TARGET_SUN_TLS)
12605 #ifdef HAVE_AS_IX86_TLSGDPLT
12606 return "call\t%a2@tlsgdplt";
12607 #else
12608 return "call\t%p3@plt";
12609 #endif
12610 return "call\t%P3";
12611 }
12612 [(set_attr "type" "multi")
12613 (set_attr "length" "12")])
12614
12615 (define_expand "tls_global_dynamic_32"
12616 [(parallel
12617 [(set (match_operand:SI 0 "register_operand" "")
12618 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12619 (match_operand:SI 1 "tls_symbolic_operand" "")
12620 (match_operand:SI 3 "constant_call_address_operand" "")]
12621 UNSPEC_TLS_GD))
12622 (clobber (match_scratch:SI 4 ""))
12623 (clobber (match_scratch:SI 5 ""))
12624 (clobber (reg:CC FLAGS_REG))])])
12625
12626 (define_insn "*tls_global_dynamic_64"
12627 [(set (match_operand:DI 0 "register_operand" "=a")
12628 (call:DI
12629 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12630 (match_operand:DI 3 "" "")))
12631 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12632 UNSPEC_TLS_GD)]
12633 "TARGET_64BIT"
12634 {
12635 if (!TARGET_X32)
12636 fputs (ASM_BYTE "0x66\n", asm_out_file);
12637 output_asm_insn
12638 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12639 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12640 fputs ("\trex64\n", asm_out_file);
12641 if (TARGET_SUN_TLS)
12642 return "call\t%p2@plt";
12643 return "call\t%P2";
12644 }
12645 [(set_attr "type" "multi")
12646 (set (attr "length")
12647 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12648
12649 (define_expand "tls_global_dynamic_64"
12650 [(parallel
12651 [(set (match_operand:DI 0 "register_operand" "")
12652 (call:DI
12653 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12654 (const_int 0)))
12655 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12656 UNSPEC_TLS_GD)])])
12657
12658 (define_insn "*tls_local_dynamic_base_32_gnu"
12659 [(set (match_operand:SI 0 "register_operand" "=a")
12660 (unspec:SI
12661 [(match_operand:SI 1 "register_operand" "b")
12662 (match_operand:SI 2 "constant_call_address_operand" "z")]
12663 UNSPEC_TLS_LD_BASE))
12664 (clobber (match_scratch:SI 3 "=d"))
12665 (clobber (match_scratch:SI 4 "=c"))
12666 (clobber (reg:CC FLAGS_REG))]
12667 "!TARGET_64BIT && TARGET_GNU_TLS"
12668 {
12669 output_asm_insn
12670 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12671 if (TARGET_SUN_TLS)
12672 #ifdef HAVE_AS_IX86_TLSLDMPLT
12673 return "call\t%&@tlsldmplt";
12674 #else
12675 return "call\t%p2@plt";
12676 #endif
12677 return "call\t%P2";
12678 }
12679 [(set_attr "type" "multi")
12680 (set_attr "length" "11")])
12681
12682 (define_expand "tls_local_dynamic_base_32"
12683 [(parallel
12684 [(set (match_operand:SI 0 "register_operand" "")
12685 (unspec:SI
12686 [(match_operand:SI 1 "register_operand" "")
12687 (match_operand:SI 2 "constant_call_address_operand" "")]
12688 UNSPEC_TLS_LD_BASE))
12689 (clobber (match_scratch:SI 3 ""))
12690 (clobber (match_scratch:SI 4 ""))
12691 (clobber (reg:CC FLAGS_REG))])])
12692
12693 (define_insn "*tls_local_dynamic_base_64"
12694 [(set (match_operand:DI 0 "register_operand" "=a")
12695 (call:DI
12696 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12697 (match_operand:DI 2 "" "")))
12698 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12699 "TARGET_64BIT"
12700 {
12701 output_asm_insn
12702 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12703 if (TARGET_SUN_TLS)
12704 return "call\t%p1@plt";
12705 return "call\t%P1";
12706 }
12707 [(set_attr "type" "multi")
12708 (set_attr "length" "12")])
12709
12710 (define_expand "tls_local_dynamic_base_64"
12711 [(parallel
12712 [(set (match_operand:DI 0 "register_operand" "")
12713 (call:DI
12714 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12715 (const_int 0)))
12716 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12717
12718 ;; Local dynamic of a single variable is a lose. Show combine how
12719 ;; to convert that back to global dynamic.
12720
12721 (define_insn_and_split "*tls_local_dynamic_32_once"
12722 [(set (match_operand:SI 0 "register_operand" "=a")
12723 (plus:SI
12724 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12725 (match_operand:SI 2 "constant_call_address_operand" "z")]
12726 UNSPEC_TLS_LD_BASE)
12727 (const:SI (unspec:SI
12728 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12729 UNSPEC_DTPOFF))))
12730 (clobber (match_scratch:SI 4 "=d"))
12731 (clobber (match_scratch:SI 5 "=c"))
12732 (clobber (reg:CC FLAGS_REG))]
12733 ""
12734 "#"
12735 ""
12736 [(parallel
12737 [(set (match_dup 0)
12738 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12739 UNSPEC_TLS_GD))
12740 (clobber (match_dup 4))
12741 (clobber (match_dup 5))
12742 (clobber (reg:CC FLAGS_REG))])])
12743
12744 ;; Segment register for the thread base ptr load
12745 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12746
12747 ;; Load and add the thread base pointer from %<tp_seg>:0.
12748 (define_insn "*load_tp_x32"
12749 [(set (match_operand:SI 0 "register_operand" "=r")
12750 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12751 "TARGET_X32"
12752 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12753 [(set_attr "type" "imov")
12754 (set_attr "modrm" "0")
12755 (set_attr "length" "7")
12756 (set_attr "memory" "load")
12757 (set_attr "imm_disp" "false")])
12758
12759 (define_insn "*load_tp_x32_zext"
12760 [(set (match_operand:DI 0 "register_operand" "=r")
12761 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12762 "TARGET_X32"
12763 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12764 [(set_attr "type" "imov")
12765 (set_attr "modrm" "0")
12766 (set_attr "length" "7")
12767 (set_attr "memory" "load")
12768 (set_attr "imm_disp" "false")])
12769
12770 (define_insn "*load_tp_<mode>"
12771 [(set (match_operand:P 0 "register_operand" "=r")
12772 (unspec:P [(const_int 0)] UNSPEC_TP))]
12773 "!TARGET_X32"
12774 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12775 [(set_attr "type" "imov")
12776 (set_attr "modrm" "0")
12777 (set_attr "length" "7")
12778 (set_attr "memory" "load")
12779 (set_attr "imm_disp" "false")])
12780
12781 (define_insn "*add_tp_x32"
12782 [(set (match_operand:SI 0 "register_operand" "=r")
12783 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12784 (match_operand:SI 1 "register_operand" "0")))
12785 (clobber (reg:CC FLAGS_REG))]
12786 "TARGET_X32"
12787 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12788 [(set_attr "type" "alu")
12789 (set_attr "modrm" "0")
12790 (set_attr "length" "7")
12791 (set_attr "memory" "load")
12792 (set_attr "imm_disp" "false")])
12793
12794 (define_insn "*add_tp_x32_zext"
12795 [(set (match_operand:DI 0 "register_operand" "=r")
12796 (zero_extend:DI
12797 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12798 (match_operand:SI 1 "register_operand" "0"))))
12799 (clobber (reg:CC FLAGS_REG))]
12800 "TARGET_X32"
12801 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12802 [(set_attr "type" "alu")
12803 (set_attr "modrm" "0")
12804 (set_attr "length" "7")
12805 (set_attr "memory" "load")
12806 (set_attr "imm_disp" "false")])
12807
12808 (define_insn "*add_tp_<mode>"
12809 [(set (match_operand:P 0 "register_operand" "=r")
12810 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12811 (match_operand:P 1 "register_operand" "0")))
12812 (clobber (reg:CC FLAGS_REG))]
12813 "!TARGET_X32"
12814 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12815 [(set_attr "type" "alu")
12816 (set_attr "modrm" "0")
12817 (set_attr "length" "7")
12818 (set_attr "memory" "load")
12819 (set_attr "imm_disp" "false")])
12820
12821 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12822 ;; %rax as destination of the initial executable code sequence.
12823 (define_insn "tls_initial_exec_64_sun"
12824 [(set (match_operand:DI 0 "register_operand" "=a")
12825 (unspec:DI
12826 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12827 UNSPEC_TLS_IE_SUN))
12828 (clobber (reg:CC FLAGS_REG))]
12829 "TARGET_64BIT && TARGET_SUN_TLS"
12830 {
12831 output_asm_insn
12832 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12833 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12834 }
12835 [(set_attr "type" "multi")])
12836
12837 ;; GNU2 TLS patterns can be split.
12838
12839 (define_expand "tls_dynamic_gnu2_32"
12840 [(set (match_dup 3)
12841 (plus:SI (match_operand:SI 2 "register_operand" "")
12842 (const:SI
12843 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12844 UNSPEC_TLSDESC))))
12845 (parallel
12846 [(set (match_operand:SI 0 "register_operand" "")
12847 (unspec:SI [(match_dup 1) (match_dup 3)
12848 (match_dup 2) (reg:SI SP_REG)]
12849 UNSPEC_TLSDESC))
12850 (clobber (reg:CC FLAGS_REG))])]
12851 "!TARGET_64BIT && TARGET_GNU2_TLS"
12852 {
12853 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12854 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12855 })
12856
12857 (define_insn "*tls_dynamic_gnu2_lea_32"
12858 [(set (match_operand:SI 0 "register_operand" "=r")
12859 (plus:SI (match_operand:SI 1 "register_operand" "b")
12860 (const:SI
12861 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12862 UNSPEC_TLSDESC))))]
12863 "!TARGET_64BIT && TARGET_GNU2_TLS"
12864 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12865 [(set_attr "type" "lea")
12866 (set_attr "mode" "SI")
12867 (set_attr "length" "6")
12868 (set_attr "length_address" "4")])
12869
12870 (define_insn "*tls_dynamic_gnu2_call_32"
12871 [(set (match_operand:SI 0 "register_operand" "=a")
12872 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12873 (match_operand:SI 2 "register_operand" "0")
12874 ;; we have to make sure %ebx still points to the GOT
12875 (match_operand:SI 3 "register_operand" "b")
12876 (reg:SI SP_REG)]
12877 UNSPEC_TLSDESC))
12878 (clobber (reg:CC FLAGS_REG))]
12879 "!TARGET_64BIT && TARGET_GNU2_TLS"
12880 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12881 [(set_attr "type" "call")
12882 (set_attr "length" "2")
12883 (set_attr "length_address" "0")])
12884
12885 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12886 [(set (match_operand:SI 0 "register_operand" "=&a")
12887 (plus:SI
12888 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12889 (match_operand:SI 4 "" "")
12890 (match_operand:SI 2 "register_operand" "b")
12891 (reg:SI SP_REG)]
12892 UNSPEC_TLSDESC)
12893 (const:SI (unspec:SI
12894 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12895 UNSPEC_DTPOFF))))
12896 (clobber (reg:CC FLAGS_REG))]
12897 "!TARGET_64BIT && TARGET_GNU2_TLS"
12898 "#"
12899 ""
12900 [(set (match_dup 0) (match_dup 5))]
12901 {
12902 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12903 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12904 })
12905
12906 (define_expand "tls_dynamic_gnu2_64"
12907 [(set (match_dup 2)
12908 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12909 UNSPEC_TLSDESC))
12910 (parallel
12911 [(set (match_operand:DI 0 "register_operand" "")
12912 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12913 UNSPEC_TLSDESC))
12914 (clobber (reg:CC FLAGS_REG))])]
12915 "TARGET_64BIT && TARGET_GNU2_TLS"
12916 {
12917 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12918 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12919 })
12920
12921 (define_insn "*tls_dynamic_gnu2_lea_64"
12922 [(set (match_operand:DI 0 "register_operand" "=r")
12923 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12924 UNSPEC_TLSDESC))]
12925 "TARGET_64BIT && TARGET_GNU2_TLS"
12926 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12927 [(set_attr "type" "lea")
12928 (set_attr "mode" "DI")
12929 (set_attr "length" "7")
12930 (set_attr "length_address" "4")])
12931
12932 (define_insn "*tls_dynamic_gnu2_call_64"
12933 [(set (match_operand:DI 0 "register_operand" "=a")
12934 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12935 (match_operand:DI 2 "register_operand" "0")
12936 (reg:DI SP_REG)]
12937 UNSPEC_TLSDESC))
12938 (clobber (reg:CC FLAGS_REG))]
12939 "TARGET_64BIT && TARGET_GNU2_TLS"
12940 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12941 [(set_attr "type" "call")
12942 (set_attr "length" "2")
12943 (set_attr "length_address" "0")])
12944
12945 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12946 [(set (match_operand:DI 0 "register_operand" "=&a")
12947 (plus:DI
12948 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12949 (match_operand:DI 3 "" "")
12950 (reg:DI SP_REG)]
12951 UNSPEC_TLSDESC)
12952 (const:DI (unspec:DI
12953 [(match_operand 1 "tls_symbolic_operand" "")]
12954 UNSPEC_DTPOFF))))
12955 (clobber (reg:CC FLAGS_REG))]
12956 "TARGET_64BIT && TARGET_GNU2_TLS"
12957 "#"
12958 ""
12959 [(set (match_dup 0) (match_dup 4))]
12960 {
12961 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12962 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12963 })
12964 \f
12965 ;; These patterns match the binary 387 instructions for addM3, subM3,
12966 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12967 ;; SFmode. The first is the normal insn, the second the same insn but
12968 ;; with one operand a conversion, and the third the same insn but with
12969 ;; the other operand a conversion. The conversion may be SFmode or
12970 ;; SImode if the target mode DFmode, but only SImode if the target mode
12971 ;; is SFmode.
12972
12973 ;; Gcc is slightly more smart about handling normal two address instructions
12974 ;; so use special patterns for add and mull.
12975
12976 (define_insn "*fop_<mode>_comm_mixed"
12977 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12978 (match_operator:MODEF 3 "binary_fp_operator"
12979 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12980 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12981 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12982 && COMMUTATIVE_ARITH_P (operands[3])
12983 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12984 "* return output_387_binary_op (insn, operands);"
12985 [(set (attr "type")
12986 (if_then_else (eq_attr "alternative" "1,2")
12987 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12988 (const_string "ssemul")
12989 (const_string "sseadd"))
12990 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12991 (const_string "fmul")
12992 (const_string "fop"))))
12993 (set_attr "isa" "*,noavx,avx")
12994 (set_attr "prefix" "orig,orig,vex")
12995 (set_attr "mode" "<MODE>")])
12996
12997 (define_insn "*fop_<mode>_comm_sse"
12998 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12999 (match_operator:MODEF 3 "binary_fp_operator"
13000 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13001 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13002 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13003 && COMMUTATIVE_ARITH_P (operands[3])
13004 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13005 "* return output_387_binary_op (insn, operands);"
13006 [(set (attr "type")
13007 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13008 (const_string "ssemul")
13009 (const_string "sseadd")))
13010 (set_attr "isa" "noavx,avx")
13011 (set_attr "prefix" "orig,vex")
13012 (set_attr "mode" "<MODE>")])
13013
13014 (define_insn "*fop_<mode>_comm_i387"
13015 [(set (match_operand:MODEF 0 "register_operand" "=f")
13016 (match_operator:MODEF 3 "binary_fp_operator"
13017 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13018 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13019 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13020 && COMMUTATIVE_ARITH_P (operands[3])
13021 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13022 "* return output_387_binary_op (insn, operands);"
13023 [(set (attr "type")
13024 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13025 (const_string "fmul")
13026 (const_string "fop")))
13027 (set_attr "mode" "<MODE>")])
13028
13029 (define_insn "*fop_<mode>_1_mixed"
13030 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13031 (match_operator:MODEF 3 "binary_fp_operator"
13032 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13033 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13034 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13035 && !COMMUTATIVE_ARITH_P (operands[3])
13036 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13037 "* return output_387_binary_op (insn, operands);"
13038 [(set (attr "type")
13039 (cond [(and (eq_attr "alternative" "2,3")
13040 (match_operand:MODEF 3 "mult_operator" ""))
13041 (const_string "ssemul")
13042 (and (eq_attr "alternative" "2,3")
13043 (match_operand:MODEF 3 "div_operator" ""))
13044 (const_string "ssediv")
13045 (eq_attr "alternative" "2,3")
13046 (const_string "sseadd")
13047 (match_operand:MODEF 3 "mult_operator" "")
13048 (const_string "fmul")
13049 (match_operand:MODEF 3 "div_operator" "")
13050 (const_string "fdiv")
13051 ]
13052 (const_string "fop")))
13053 (set_attr "isa" "*,*,noavx,avx")
13054 (set_attr "prefix" "orig,orig,orig,vex")
13055 (set_attr "mode" "<MODE>")])
13056
13057 (define_insn "*rcpsf2_sse"
13058 [(set (match_operand:SF 0 "register_operand" "=x")
13059 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13060 UNSPEC_RCP))]
13061 "TARGET_SSE_MATH"
13062 "%vrcpss\t{%1, %d0|%d0, %1}"
13063 [(set_attr "type" "sse")
13064 (set_attr "atom_sse_attr" "rcp")
13065 (set_attr "prefix" "maybe_vex")
13066 (set_attr "mode" "SF")])
13067
13068 (define_insn "*fop_<mode>_1_sse"
13069 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13070 (match_operator:MODEF 3 "binary_fp_operator"
13071 [(match_operand:MODEF 1 "register_operand" "0,x")
13072 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13073 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13074 && !COMMUTATIVE_ARITH_P (operands[3])"
13075 "* return output_387_binary_op (insn, operands);"
13076 [(set (attr "type")
13077 (cond [(match_operand:MODEF 3 "mult_operator" "")
13078 (const_string "ssemul")
13079 (match_operand:MODEF 3 "div_operator" "")
13080 (const_string "ssediv")
13081 ]
13082 (const_string "sseadd")))
13083 (set_attr "isa" "noavx,avx")
13084 (set_attr "prefix" "orig,vex")
13085 (set_attr "mode" "<MODE>")])
13086
13087 ;; This pattern is not fully shadowed by the pattern above.
13088 (define_insn "*fop_<mode>_1_i387"
13089 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13090 (match_operator:MODEF 3 "binary_fp_operator"
13091 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13092 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13093 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13094 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13095 && !COMMUTATIVE_ARITH_P (operands[3])
13096 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13097 "* return output_387_binary_op (insn, operands);"
13098 [(set (attr "type")
13099 (cond [(match_operand:MODEF 3 "mult_operator" "")
13100 (const_string "fmul")
13101 (match_operand:MODEF 3 "div_operator" "")
13102 (const_string "fdiv")
13103 ]
13104 (const_string "fop")))
13105 (set_attr "mode" "<MODE>")])
13106
13107 ;; ??? Add SSE splitters for these!
13108 (define_insn "*fop_<MODEF:mode>_2_i387"
13109 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13110 (match_operator:MODEF 3 "binary_fp_operator"
13111 [(float:MODEF
13112 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13113 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13114 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13115 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13116 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13117 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13118 [(set (attr "type")
13119 (cond [(match_operand:MODEF 3 "mult_operator" "")
13120 (const_string "fmul")
13121 (match_operand:MODEF 3 "div_operator" "")
13122 (const_string "fdiv")
13123 ]
13124 (const_string "fop")))
13125 (set_attr "fp_int_src" "true")
13126 (set_attr "mode" "<SWI24:MODE>")])
13127
13128 (define_insn "*fop_<MODEF:mode>_3_i387"
13129 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13130 (match_operator:MODEF 3 "binary_fp_operator"
13131 [(match_operand:MODEF 1 "register_operand" "0,0")
13132 (float:MODEF
13133 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13134 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13135 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13136 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13137 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13138 [(set (attr "type")
13139 (cond [(match_operand:MODEF 3 "mult_operator" "")
13140 (const_string "fmul")
13141 (match_operand:MODEF 3 "div_operator" "")
13142 (const_string "fdiv")
13143 ]
13144 (const_string "fop")))
13145 (set_attr "fp_int_src" "true")
13146 (set_attr "mode" "<MODE>")])
13147
13148 (define_insn "*fop_df_4_i387"
13149 [(set (match_operand:DF 0 "register_operand" "=f,f")
13150 (match_operator:DF 3 "binary_fp_operator"
13151 [(float_extend:DF
13152 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13153 (match_operand:DF 2 "register_operand" "0,f")]))]
13154 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13155 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13156 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13157 "* return output_387_binary_op (insn, operands);"
13158 [(set (attr "type")
13159 (cond [(match_operand:DF 3 "mult_operator" "")
13160 (const_string "fmul")
13161 (match_operand:DF 3 "div_operator" "")
13162 (const_string "fdiv")
13163 ]
13164 (const_string "fop")))
13165 (set_attr "mode" "SF")])
13166
13167 (define_insn "*fop_df_5_i387"
13168 [(set (match_operand:DF 0 "register_operand" "=f,f")
13169 (match_operator:DF 3 "binary_fp_operator"
13170 [(match_operand:DF 1 "register_operand" "0,f")
13171 (float_extend:DF
13172 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13173 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13174 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13175 "* return output_387_binary_op (insn, operands);"
13176 [(set (attr "type")
13177 (cond [(match_operand:DF 3 "mult_operator" "")
13178 (const_string "fmul")
13179 (match_operand:DF 3 "div_operator" "")
13180 (const_string "fdiv")
13181 ]
13182 (const_string "fop")))
13183 (set_attr "mode" "SF")])
13184
13185 (define_insn "*fop_df_6_i387"
13186 [(set (match_operand:DF 0 "register_operand" "=f,f")
13187 (match_operator:DF 3 "binary_fp_operator"
13188 [(float_extend:DF
13189 (match_operand:SF 1 "register_operand" "0,f"))
13190 (float_extend:DF
13191 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13192 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13193 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13194 "* return output_387_binary_op (insn, operands);"
13195 [(set (attr "type")
13196 (cond [(match_operand:DF 3 "mult_operator" "")
13197 (const_string "fmul")
13198 (match_operand:DF 3 "div_operator" "")
13199 (const_string "fdiv")
13200 ]
13201 (const_string "fop")))
13202 (set_attr "mode" "SF")])
13203
13204 (define_insn "*fop_xf_comm_i387"
13205 [(set (match_operand:XF 0 "register_operand" "=f")
13206 (match_operator:XF 3 "binary_fp_operator"
13207 [(match_operand:XF 1 "register_operand" "%0")
13208 (match_operand:XF 2 "register_operand" "f")]))]
13209 "TARGET_80387
13210 && COMMUTATIVE_ARITH_P (operands[3])"
13211 "* return output_387_binary_op (insn, operands);"
13212 [(set (attr "type")
13213 (if_then_else (match_operand:XF 3 "mult_operator" "")
13214 (const_string "fmul")
13215 (const_string "fop")))
13216 (set_attr "mode" "XF")])
13217
13218 (define_insn "*fop_xf_1_i387"
13219 [(set (match_operand:XF 0 "register_operand" "=f,f")
13220 (match_operator:XF 3 "binary_fp_operator"
13221 [(match_operand:XF 1 "register_operand" "0,f")
13222 (match_operand:XF 2 "register_operand" "f,0")]))]
13223 "TARGET_80387
13224 && !COMMUTATIVE_ARITH_P (operands[3])"
13225 "* return output_387_binary_op (insn, operands);"
13226 [(set (attr "type")
13227 (cond [(match_operand:XF 3 "mult_operator" "")
13228 (const_string "fmul")
13229 (match_operand:XF 3 "div_operator" "")
13230 (const_string "fdiv")
13231 ]
13232 (const_string "fop")))
13233 (set_attr "mode" "XF")])
13234
13235 (define_insn "*fop_xf_2_i387"
13236 [(set (match_operand:XF 0 "register_operand" "=f,f")
13237 (match_operator:XF 3 "binary_fp_operator"
13238 [(float:XF
13239 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13240 (match_operand:XF 2 "register_operand" "0,0")]))]
13241 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13242 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13243 [(set (attr "type")
13244 (cond [(match_operand:XF 3 "mult_operator" "")
13245 (const_string "fmul")
13246 (match_operand:XF 3 "div_operator" "")
13247 (const_string "fdiv")
13248 ]
13249 (const_string "fop")))
13250 (set_attr "fp_int_src" "true")
13251 (set_attr "mode" "<MODE>")])
13252
13253 (define_insn "*fop_xf_3_i387"
13254 [(set (match_operand:XF 0 "register_operand" "=f,f")
13255 (match_operator:XF 3 "binary_fp_operator"
13256 [(match_operand:XF 1 "register_operand" "0,0")
13257 (float:XF
13258 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13259 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13260 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13261 [(set (attr "type")
13262 (cond [(match_operand:XF 3 "mult_operator" "")
13263 (const_string "fmul")
13264 (match_operand:XF 3 "div_operator" "")
13265 (const_string "fdiv")
13266 ]
13267 (const_string "fop")))
13268 (set_attr "fp_int_src" "true")
13269 (set_attr "mode" "<MODE>")])
13270
13271 (define_insn "*fop_xf_4_i387"
13272 [(set (match_operand:XF 0 "register_operand" "=f,f")
13273 (match_operator:XF 3 "binary_fp_operator"
13274 [(float_extend:XF
13275 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13276 (match_operand:XF 2 "register_operand" "0,f")]))]
13277 "TARGET_80387"
13278 "* return output_387_binary_op (insn, operands);"
13279 [(set (attr "type")
13280 (cond [(match_operand:XF 3 "mult_operator" "")
13281 (const_string "fmul")
13282 (match_operand:XF 3 "div_operator" "")
13283 (const_string "fdiv")
13284 ]
13285 (const_string "fop")))
13286 (set_attr "mode" "<MODE>")])
13287
13288 (define_insn "*fop_xf_5_i387"
13289 [(set (match_operand:XF 0 "register_operand" "=f,f")
13290 (match_operator:XF 3 "binary_fp_operator"
13291 [(match_operand:XF 1 "register_operand" "0,f")
13292 (float_extend:XF
13293 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13294 "TARGET_80387"
13295 "* return output_387_binary_op (insn, operands);"
13296 [(set (attr "type")
13297 (cond [(match_operand:XF 3 "mult_operator" "")
13298 (const_string "fmul")
13299 (match_operand:XF 3 "div_operator" "")
13300 (const_string "fdiv")
13301 ]
13302 (const_string "fop")))
13303 (set_attr "mode" "<MODE>")])
13304
13305 (define_insn "*fop_xf_6_i387"
13306 [(set (match_operand:XF 0 "register_operand" "=f,f")
13307 (match_operator:XF 3 "binary_fp_operator"
13308 [(float_extend:XF
13309 (match_operand:MODEF 1 "register_operand" "0,f"))
13310 (float_extend:XF
13311 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13312 "TARGET_80387"
13313 "* return output_387_binary_op (insn, operands);"
13314 [(set (attr "type")
13315 (cond [(match_operand:XF 3 "mult_operator" "")
13316 (const_string "fmul")
13317 (match_operand:XF 3 "div_operator" "")
13318 (const_string "fdiv")
13319 ]
13320 (const_string "fop")))
13321 (set_attr "mode" "<MODE>")])
13322
13323 (define_split
13324 [(set (match_operand 0 "register_operand" "")
13325 (match_operator 3 "binary_fp_operator"
13326 [(float (match_operand:SWI24 1 "register_operand" ""))
13327 (match_operand 2 "register_operand" "")]))]
13328 "reload_completed
13329 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13330 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13331 [(const_int 0)]
13332 {
13333 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13334 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13335 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13336 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13337 GET_MODE (operands[3]),
13338 operands[4],
13339 operands[2])));
13340 ix86_free_from_memory (GET_MODE (operands[1]));
13341 DONE;
13342 })
13343
13344 (define_split
13345 [(set (match_operand 0 "register_operand" "")
13346 (match_operator 3 "binary_fp_operator"
13347 [(match_operand 1 "register_operand" "")
13348 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13349 "reload_completed
13350 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13351 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13352 [(const_int 0)]
13353 {
13354 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13355 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13356 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13357 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13358 GET_MODE (operands[3]),
13359 operands[1],
13360 operands[4])));
13361 ix86_free_from_memory (GET_MODE (operands[2]));
13362 DONE;
13363 })
13364 \f
13365 ;; FPU special functions.
13366
13367 ;; This pattern implements a no-op XFmode truncation for
13368 ;; all fancy i386 XFmode math functions.
13369
13370 (define_insn "truncxf<mode>2_i387_noop_unspec"
13371 [(set (match_operand:MODEF 0 "register_operand" "=f")
13372 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13373 UNSPEC_TRUNC_NOOP))]
13374 "TARGET_USE_FANCY_MATH_387"
13375 "* return output_387_reg_move (insn, operands);"
13376 [(set_attr "type" "fmov")
13377 (set_attr "mode" "<MODE>")])
13378
13379 (define_insn "sqrtxf2"
13380 [(set (match_operand:XF 0 "register_operand" "=f")
13381 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13382 "TARGET_USE_FANCY_MATH_387"
13383 "fsqrt"
13384 [(set_attr "type" "fpspc")
13385 (set_attr "mode" "XF")
13386 (set_attr "athlon_decode" "direct")
13387 (set_attr "amdfam10_decode" "direct")
13388 (set_attr "bdver1_decode" "direct")])
13389
13390 (define_insn "sqrt_extend<mode>xf2_i387"
13391 [(set (match_operand:XF 0 "register_operand" "=f")
13392 (sqrt:XF
13393 (float_extend:XF
13394 (match_operand:MODEF 1 "register_operand" "0"))))]
13395 "TARGET_USE_FANCY_MATH_387"
13396 "fsqrt"
13397 [(set_attr "type" "fpspc")
13398 (set_attr "mode" "XF")
13399 (set_attr "athlon_decode" "direct")
13400 (set_attr "amdfam10_decode" "direct")
13401 (set_attr "bdver1_decode" "direct")])
13402
13403 (define_insn "*rsqrtsf2_sse"
13404 [(set (match_operand:SF 0 "register_operand" "=x")
13405 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13406 UNSPEC_RSQRT))]
13407 "TARGET_SSE_MATH"
13408 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13409 [(set_attr "type" "sse")
13410 (set_attr "atom_sse_attr" "rcp")
13411 (set_attr "prefix" "maybe_vex")
13412 (set_attr "mode" "SF")])
13413
13414 (define_expand "rsqrtsf2"
13415 [(set (match_operand:SF 0 "register_operand" "")
13416 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13417 UNSPEC_RSQRT))]
13418 "TARGET_SSE_MATH"
13419 {
13420 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13421 DONE;
13422 })
13423
13424 (define_insn "*sqrt<mode>2_sse"
13425 [(set (match_operand:MODEF 0 "register_operand" "=x")
13426 (sqrt:MODEF
13427 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13428 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13429 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13430 [(set_attr "type" "sse")
13431 (set_attr "atom_sse_attr" "sqrt")
13432 (set_attr "prefix" "maybe_vex")
13433 (set_attr "mode" "<MODE>")
13434 (set_attr "athlon_decode" "*")
13435 (set_attr "amdfam10_decode" "*")
13436 (set_attr "bdver1_decode" "*")])
13437
13438 (define_expand "sqrt<mode>2"
13439 [(set (match_operand:MODEF 0 "register_operand" "")
13440 (sqrt:MODEF
13441 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13442 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13443 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13444 {
13445 if (<MODE>mode == SFmode
13446 && TARGET_SSE_MATH
13447 && TARGET_RECIP_SQRT
13448 && !optimize_function_for_size_p (cfun)
13449 && flag_finite_math_only && !flag_trapping_math
13450 && flag_unsafe_math_optimizations)
13451 {
13452 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13453 DONE;
13454 }
13455
13456 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13457 {
13458 rtx op0 = gen_reg_rtx (XFmode);
13459 rtx op1 = force_reg (<MODE>mode, operands[1]);
13460
13461 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13462 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13463 DONE;
13464 }
13465 })
13466
13467 (define_insn "fpremxf4_i387"
13468 [(set (match_operand:XF 0 "register_operand" "=f")
13469 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13470 (match_operand:XF 3 "register_operand" "1")]
13471 UNSPEC_FPREM_F))
13472 (set (match_operand:XF 1 "register_operand" "=u")
13473 (unspec:XF [(match_dup 2) (match_dup 3)]
13474 UNSPEC_FPREM_U))
13475 (set (reg:CCFP FPSR_REG)
13476 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13477 UNSPEC_C2_FLAG))]
13478 "TARGET_USE_FANCY_MATH_387"
13479 "fprem"
13480 [(set_attr "type" "fpspc")
13481 (set_attr "mode" "XF")])
13482
13483 (define_expand "fmodxf3"
13484 [(use (match_operand:XF 0 "register_operand" ""))
13485 (use (match_operand:XF 1 "general_operand" ""))
13486 (use (match_operand:XF 2 "general_operand" ""))]
13487 "TARGET_USE_FANCY_MATH_387"
13488 {
13489 rtx label = gen_label_rtx ();
13490
13491 rtx op1 = gen_reg_rtx (XFmode);
13492 rtx op2 = gen_reg_rtx (XFmode);
13493
13494 emit_move_insn (op2, operands[2]);
13495 emit_move_insn (op1, operands[1]);
13496
13497 emit_label (label);
13498 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13499 ix86_emit_fp_unordered_jump (label);
13500 LABEL_NUSES (label) = 1;
13501
13502 emit_move_insn (operands[0], op1);
13503 DONE;
13504 })
13505
13506 (define_expand "fmod<mode>3"
13507 [(use (match_operand:MODEF 0 "register_operand" ""))
13508 (use (match_operand:MODEF 1 "general_operand" ""))
13509 (use (match_operand:MODEF 2 "general_operand" ""))]
13510 "TARGET_USE_FANCY_MATH_387"
13511 {
13512 rtx (*gen_truncxf) (rtx, rtx);
13513
13514 rtx label = gen_label_rtx ();
13515
13516 rtx op1 = gen_reg_rtx (XFmode);
13517 rtx op2 = gen_reg_rtx (XFmode);
13518
13519 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13520 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13521
13522 emit_label (label);
13523 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13524 ix86_emit_fp_unordered_jump (label);
13525 LABEL_NUSES (label) = 1;
13526
13527 /* Truncate the result properly for strict SSE math. */
13528 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13529 && !TARGET_MIX_SSE_I387)
13530 gen_truncxf = gen_truncxf<mode>2;
13531 else
13532 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13533
13534 emit_insn (gen_truncxf (operands[0], op1));
13535 DONE;
13536 })
13537
13538 (define_insn "fprem1xf4_i387"
13539 [(set (match_operand:XF 0 "register_operand" "=f")
13540 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13541 (match_operand:XF 3 "register_operand" "1")]
13542 UNSPEC_FPREM1_F))
13543 (set (match_operand:XF 1 "register_operand" "=u")
13544 (unspec:XF [(match_dup 2) (match_dup 3)]
13545 UNSPEC_FPREM1_U))
13546 (set (reg:CCFP FPSR_REG)
13547 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13548 UNSPEC_C2_FLAG))]
13549 "TARGET_USE_FANCY_MATH_387"
13550 "fprem1"
13551 [(set_attr "type" "fpspc")
13552 (set_attr "mode" "XF")])
13553
13554 (define_expand "remainderxf3"
13555 [(use (match_operand:XF 0 "register_operand" ""))
13556 (use (match_operand:XF 1 "general_operand" ""))
13557 (use (match_operand:XF 2 "general_operand" ""))]
13558 "TARGET_USE_FANCY_MATH_387"
13559 {
13560 rtx label = gen_label_rtx ();
13561
13562 rtx op1 = gen_reg_rtx (XFmode);
13563 rtx op2 = gen_reg_rtx (XFmode);
13564
13565 emit_move_insn (op2, operands[2]);
13566 emit_move_insn (op1, operands[1]);
13567
13568 emit_label (label);
13569 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13570 ix86_emit_fp_unordered_jump (label);
13571 LABEL_NUSES (label) = 1;
13572
13573 emit_move_insn (operands[0], op1);
13574 DONE;
13575 })
13576
13577 (define_expand "remainder<mode>3"
13578 [(use (match_operand:MODEF 0 "register_operand" ""))
13579 (use (match_operand:MODEF 1 "general_operand" ""))
13580 (use (match_operand:MODEF 2 "general_operand" ""))]
13581 "TARGET_USE_FANCY_MATH_387"
13582 {
13583 rtx (*gen_truncxf) (rtx, rtx);
13584
13585 rtx label = gen_label_rtx ();
13586
13587 rtx op1 = gen_reg_rtx (XFmode);
13588 rtx op2 = gen_reg_rtx (XFmode);
13589
13590 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13591 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13592
13593 emit_label (label);
13594
13595 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13596 ix86_emit_fp_unordered_jump (label);
13597 LABEL_NUSES (label) = 1;
13598
13599 /* Truncate the result properly for strict SSE math. */
13600 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13601 && !TARGET_MIX_SSE_I387)
13602 gen_truncxf = gen_truncxf<mode>2;
13603 else
13604 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13605
13606 emit_insn (gen_truncxf (operands[0], op1));
13607 DONE;
13608 })
13609
13610 (define_insn "*sinxf2_i387"
13611 [(set (match_operand:XF 0 "register_operand" "=f")
13612 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13613 "TARGET_USE_FANCY_MATH_387
13614 && flag_unsafe_math_optimizations"
13615 "fsin"
13616 [(set_attr "type" "fpspc")
13617 (set_attr "mode" "XF")])
13618
13619 (define_insn "*sin_extend<mode>xf2_i387"
13620 [(set (match_operand:XF 0 "register_operand" "=f")
13621 (unspec:XF [(float_extend:XF
13622 (match_operand:MODEF 1 "register_operand" "0"))]
13623 UNSPEC_SIN))]
13624 "TARGET_USE_FANCY_MATH_387
13625 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13626 || TARGET_MIX_SSE_I387)
13627 && flag_unsafe_math_optimizations"
13628 "fsin"
13629 [(set_attr "type" "fpspc")
13630 (set_attr "mode" "XF")])
13631
13632 (define_insn "*cosxf2_i387"
13633 [(set (match_operand:XF 0 "register_operand" "=f")
13634 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13635 "TARGET_USE_FANCY_MATH_387
13636 && flag_unsafe_math_optimizations"
13637 "fcos"
13638 [(set_attr "type" "fpspc")
13639 (set_attr "mode" "XF")])
13640
13641 (define_insn "*cos_extend<mode>xf2_i387"
13642 [(set (match_operand:XF 0 "register_operand" "=f")
13643 (unspec:XF [(float_extend:XF
13644 (match_operand:MODEF 1 "register_operand" "0"))]
13645 UNSPEC_COS))]
13646 "TARGET_USE_FANCY_MATH_387
13647 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13648 || TARGET_MIX_SSE_I387)
13649 && flag_unsafe_math_optimizations"
13650 "fcos"
13651 [(set_attr "type" "fpspc")
13652 (set_attr "mode" "XF")])
13653
13654 ;; When sincos pattern is defined, sin and cos builtin functions will be
13655 ;; expanded to sincos pattern with one of its outputs left unused.
13656 ;; CSE pass will figure out if two sincos patterns can be combined,
13657 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13658 ;; depending on the unused output.
13659
13660 (define_insn "sincosxf3"
13661 [(set (match_operand:XF 0 "register_operand" "=f")
13662 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13663 UNSPEC_SINCOS_COS))
13664 (set (match_operand:XF 1 "register_operand" "=u")
13665 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13666 "TARGET_USE_FANCY_MATH_387
13667 && flag_unsafe_math_optimizations"
13668 "fsincos"
13669 [(set_attr "type" "fpspc")
13670 (set_attr "mode" "XF")])
13671
13672 (define_split
13673 [(set (match_operand:XF 0 "register_operand" "")
13674 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13675 UNSPEC_SINCOS_COS))
13676 (set (match_operand:XF 1 "register_operand" "")
13677 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13678 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13679 && can_create_pseudo_p ()"
13680 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13681
13682 (define_split
13683 [(set (match_operand:XF 0 "register_operand" "")
13684 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13685 UNSPEC_SINCOS_COS))
13686 (set (match_operand:XF 1 "register_operand" "")
13687 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13688 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13689 && can_create_pseudo_p ()"
13690 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13691
13692 (define_insn "sincos_extend<mode>xf3_i387"
13693 [(set (match_operand:XF 0 "register_operand" "=f")
13694 (unspec:XF [(float_extend:XF
13695 (match_operand:MODEF 2 "register_operand" "0"))]
13696 UNSPEC_SINCOS_COS))
13697 (set (match_operand:XF 1 "register_operand" "=u")
13698 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13699 "TARGET_USE_FANCY_MATH_387
13700 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13701 || TARGET_MIX_SSE_I387)
13702 && flag_unsafe_math_optimizations"
13703 "fsincos"
13704 [(set_attr "type" "fpspc")
13705 (set_attr "mode" "XF")])
13706
13707 (define_split
13708 [(set (match_operand:XF 0 "register_operand" "")
13709 (unspec:XF [(float_extend:XF
13710 (match_operand:MODEF 2 "register_operand" ""))]
13711 UNSPEC_SINCOS_COS))
13712 (set (match_operand:XF 1 "register_operand" "")
13713 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13714 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13715 && can_create_pseudo_p ()"
13716 [(set (match_dup 1)
13717 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13718
13719 (define_split
13720 [(set (match_operand:XF 0 "register_operand" "")
13721 (unspec:XF [(float_extend:XF
13722 (match_operand:MODEF 2 "register_operand" ""))]
13723 UNSPEC_SINCOS_COS))
13724 (set (match_operand:XF 1 "register_operand" "")
13725 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13726 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13727 && can_create_pseudo_p ()"
13728 [(set (match_dup 0)
13729 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13730
13731 (define_expand "sincos<mode>3"
13732 [(use (match_operand:MODEF 0 "register_operand" ""))
13733 (use (match_operand:MODEF 1 "register_operand" ""))
13734 (use (match_operand:MODEF 2 "register_operand" ""))]
13735 "TARGET_USE_FANCY_MATH_387
13736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13737 || TARGET_MIX_SSE_I387)
13738 && flag_unsafe_math_optimizations"
13739 {
13740 rtx op0 = gen_reg_rtx (XFmode);
13741 rtx op1 = gen_reg_rtx (XFmode);
13742
13743 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13744 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13745 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13746 DONE;
13747 })
13748
13749 (define_insn "fptanxf4_i387"
13750 [(set (match_operand:XF 0 "register_operand" "=f")
13751 (match_operand:XF 3 "const_double_operand" "F"))
13752 (set (match_operand:XF 1 "register_operand" "=u")
13753 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13754 UNSPEC_TAN))]
13755 "TARGET_USE_FANCY_MATH_387
13756 && flag_unsafe_math_optimizations
13757 && standard_80387_constant_p (operands[3]) == 2"
13758 "fptan"
13759 [(set_attr "type" "fpspc")
13760 (set_attr "mode" "XF")])
13761
13762 (define_insn "fptan_extend<mode>xf4_i387"
13763 [(set (match_operand:MODEF 0 "register_operand" "=f")
13764 (match_operand:MODEF 3 "const_double_operand" "F"))
13765 (set (match_operand:XF 1 "register_operand" "=u")
13766 (unspec:XF [(float_extend:XF
13767 (match_operand:MODEF 2 "register_operand" "0"))]
13768 UNSPEC_TAN))]
13769 "TARGET_USE_FANCY_MATH_387
13770 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13771 || TARGET_MIX_SSE_I387)
13772 && flag_unsafe_math_optimizations
13773 && standard_80387_constant_p (operands[3]) == 2"
13774 "fptan"
13775 [(set_attr "type" "fpspc")
13776 (set_attr "mode" "XF")])
13777
13778 (define_expand "tanxf2"
13779 [(use (match_operand:XF 0 "register_operand" ""))
13780 (use (match_operand:XF 1 "register_operand" ""))]
13781 "TARGET_USE_FANCY_MATH_387
13782 && flag_unsafe_math_optimizations"
13783 {
13784 rtx one = gen_reg_rtx (XFmode);
13785 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13786
13787 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13788 DONE;
13789 })
13790
13791 (define_expand "tan<mode>2"
13792 [(use (match_operand:MODEF 0 "register_operand" ""))
13793 (use (match_operand:MODEF 1 "register_operand" ""))]
13794 "TARGET_USE_FANCY_MATH_387
13795 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13796 || TARGET_MIX_SSE_I387)
13797 && flag_unsafe_math_optimizations"
13798 {
13799 rtx op0 = gen_reg_rtx (XFmode);
13800
13801 rtx one = gen_reg_rtx (<MODE>mode);
13802 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13803
13804 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13805 operands[1], op2));
13806 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13807 DONE;
13808 })
13809
13810 (define_insn "*fpatanxf3_i387"
13811 [(set (match_operand:XF 0 "register_operand" "=f")
13812 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13813 (match_operand:XF 2 "register_operand" "u")]
13814 UNSPEC_FPATAN))
13815 (clobber (match_scratch:XF 3 "=2"))]
13816 "TARGET_USE_FANCY_MATH_387
13817 && flag_unsafe_math_optimizations"
13818 "fpatan"
13819 [(set_attr "type" "fpspc")
13820 (set_attr "mode" "XF")])
13821
13822 (define_insn "fpatan_extend<mode>xf3_i387"
13823 [(set (match_operand:XF 0 "register_operand" "=f")
13824 (unspec:XF [(float_extend:XF
13825 (match_operand:MODEF 1 "register_operand" "0"))
13826 (float_extend:XF
13827 (match_operand:MODEF 2 "register_operand" "u"))]
13828 UNSPEC_FPATAN))
13829 (clobber (match_scratch:XF 3 "=2"))]
13830 "TARGET_USE_FANCY_MATH_387
13831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13832 || TARGET_MIX_SSE_I387)
13833 && flag_unsafe_math_optimizations"
13834 "fpatan"
13835 [(set_attr "type" "fpspc")
13836 (set_attr "mode" "XF")])
13837
13838 (define_expand "atan2xf3"
13839 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13840 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13841 (match_operand:XF 1 "register_operand" "")]
13842 UNSPEC_FPATAN))
13843 (clobber (match_scratch:XF 3 ""))])]
13844 "TARGET_USE_FANCY_MATH_387
13845 && flag_unsafe_math_optimizations")
13846
13847 (define_expand "atan2<mode>3"
13848 [(use (match_operand:MODEF 0 "register_operand" ""))
13849 (use (match_operand:MODEF 1 "register_operand" ""))
13850 (use (match_operand:MODEF 2 "register_operand" ""))]
13851 "TARGET_USE_FANCY_MATH_387
13852 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13853 || TARGET_MIX_SSE_I387)
13854 && flag_unsafe_math_optimizations"
13855 {
13856 rtx op0 = gen_reg_rtx (XFmode);
13857
13858 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13859 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13860 DONE;
13861 })
13862
13863 (define_expand "atanxf2"
13864 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13865 (unspec:XF [(match_dup 2)
13866 (match_operand:XF 1 "register_operand" "")]
13867 UNSPEC_FPATAN))
13868 (clobber (match_scratch:XF 3 ""))])]
13869 "TARGET_USE_FANCY_MATH_387
13870 && flag_unsafe_math_optimizations"
13871 {
13872 operands[2] = gen_reg_rtx (XFmode);
13873 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13874 })
13875
13876 (define_expand "atan<mode>2"
13877 [(use (match_operand:MODEF 0 "register_operand" ""))
13878 (use (match_operand:MODEF 1 "register_operand" ""))]
13879 "TARGET_USE_FANCY_MATH_387
13880 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13881 || TARGET_MIX_SSE_I387)
13882 && flag_unsafe_math_optimizations"
13883 {
13884 rtx op0 = gen_reg_rtx (XFmode);
13885
13886 rtx op2 = gen_reg_rtx (<MODE>mode);
13887 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13888
13889 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13890 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13891 DONE;
13892 })
13893
13894 (define_expand "asinxf2"
13895 [(set (match_dup 2)
13896 (mult:XF (match_operand:XF 1 "register_operand" "")
13897 (match_dup 1)))
13898 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13899 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13900 (parallel [(set (match_operand:XF 0 "register_operand" "")
13901 (unspec:XF [(match_dup 5) (match_dup 1)]
13902 UNSPEC_FPATAN))
13903 (clobber (match_scratch:XF 6 ""))])]
13904 "TARGET_USE_FANCY_MATH_387
13905 && flag_unsafe_math_optimizations"
13906 {
13907 int i;
13908
13909 if (optimize_insn_for_size_p ())
13910 FAIL;
13911
13912 for (i = 2; i < 6; i++)
13913 operands[i] = gen_reg_rtx (XFmode);
13914
13915 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13916 })
13917
13918 (define_expand "asin<mode>2"
13919 [(use (match_operand:MODEF 0 "register_operand" ""))
13920 (use (match_operand:MODEF 1 "general_operand" ""))]
13921 "TARGET_USE_FANCY_MATH_387
13922 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13923 || TARGET_MIX_SSE_I387)
13924 && flag_unsafe_math_optimizations"
13925 {
13926 rtx op0 = gen_reg_rtx (XFmode);
13927 rtx op1 = gen_reg_rtx (XFmode);
13928
13929 if (optimize_insn_for_size_p ())
13930 FAIL;
13931
13932 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13933 emit_insn (gen_asinxf2 (op0, op1));
13934 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13935 DONE;
13936 })
13937
13938 (define_expand "acosxf2"
13939 [(set (match_dup 2)
13940 (mult:XF (match_operand:XF 1 "register_operand" "")
13941 (match_dup 1)))
13942 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13943 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13944 (parallel [(set (match_operand:XF 0 "register_operand" "")
13945 (unspec:XF [(match_dup 1) (match_dup 5)]
13946 UNSPEC_FPATAN))
13947 (clobber (match_scratch:XF 6 ""))])]
13948 "TARGET_USE_FANCY_MATH_387
13949 && flag_unsafe_math_optimizations"
13950 {
13951 int i;
13952
13953 if (optimize_insn_for_size_p ())
13954 FAIL;
13955
13956 for (i = 2; i < 6; i++)
13957 operands[i] = gen_reg_rtx (XFmode);
13958
13959 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13960 })
13961
13962 (define_expand "acos<mode>2"
13963 [(use (match_operand:MODEF 0 "register_operand" ""))
13964 (use (match_operand:MODEF 1 "general_operand" ""))]
13965 "TARGET_USE_FANCY_MATH_387
13966 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13967 || TARGET_MIX_SSE_I387)
13968 && flag_unsafe_math_optimizations"
13969 {
13970 rtx op0 = gen_reg_rtx (XFmode);
13971 rtx op1 = gen_reg_rtx (XFmode);
13972
13973 if (optimize_insn_for_size_p ())
13974 FAIL;
13975
13976 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13977 emit_insn (gen_acosxf2 (op0, op1));
13978 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13979 DONE;
13980 })
13981
13982 (define_insn "fyl2xxf3_i387"
13983 [(set (match_operand:XF 0 "register_operand" "=f")
13984 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13985 (match_operand:XF 2 "register_operand" "u")]
13986 UNSPEC_FYL2X))
13987 (clobber (match_scratch:XF 3 "=2"))]
13988 "TARGET_USE_FANCY_MATH_387
13989 && flag_unsafe_math_optimizations"
13990 "fyl2x"
13991 [(set_attr "type" "fpspc")
13992 (set_attr "mode" "XF")])
13993
13994 (define_insn "fyl2x_extend<mode>xf3_i387"
13995 [(set (match_operand:XF 0 "register_operand" "=f")
13996 (unspec:XF [(float_extend:XF
13997 (match_operand:MODEF 1 "register_operand" "0"))
13998 (match_operand:XF 2 "register_operand" "u")]
13999 UNSPEC_FYL2X))
14000 (clobber (match_scratch:XF 3 "=2"))]
14001 "TARGET_USE_FANCY_MATH_387
14002 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14003 || TARGET_MIX_SSE_I387)
14004 && flag_unsafe_math_optimizations"
14005 "fyl2x"
14006 [(set_attr "type" "fpspc")
14007 (set_attr "mode" "XF")])
14008
14009 (define_expand "logxf2"
14010 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14011 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14012 (match_dup 2)] UNSPEC_FYL2X))
14013 (clobber (match_scratch:XF 3 ""))])]
14014 "TARGET_USE_FANCY_MATH_387
14015 && flag_unsafe_math_optimizations"
14016 {
14017 operands[2] = gen_reg_rtx (XFmode);
14018 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14019 })
14020
14021 (define_expand "log<mode>2"
14022 [(use (match_operand:MODEF 0 "register_operand" ""))
14023 (use (match_operand:MODEF 1 "register_operand" ""))]
14024 "TARGET_USE_FANCY_MATH_387
14025 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14026 || TARGET_MIX_SSE_I387)
14027 && flag_unsafe_math_optimizations"
14028 {
14029 rtx op0 = gen_reg_rtx (XFmode);
14030
14031 rtx op2 = gen_reg_rtx (XFmode);
14032 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14033
14034 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14035 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14036 DONE;
14037 })
14038
14039 (define_expand "log10xf2"
14040 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14041 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14042 (match_dup 2)] UNSPEC_FYL2X))
14043 (clobber (match_scratch:XF 3 ""))])]
14044 "TARGET_USE_FANCY_MATH_387
14045 && flag_unsafe_math_optimizations"
14046 {
14047 operands[2] = gen_reg_rtx (XFmode);
14048 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14049 })
14050
14051 (define_expand "log10<mode>2"
14052 [(use (match_operand:MODEF 0 "register_operand" ""))
14053 (use (match_operand:MODEF 1 "register_operand" ""))]
14054 "TARGET_USE_FANCY_MATH_387
14055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056 || TARGET_MIX_SSE_I387)
14057 && flag_unsafe_math_optimizations"
14058 {
14059 rtx op0 = gen_reg_rtx (XFmode);
14060
14061 rtx op2 = gen_reg_rtx (XFmode);
14062 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14063
14064 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14065 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14066 DONE;
14067 })
14068
14069 (define_expand "log2xf2"
14070 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14071 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14072 (match_dup 2)] UNSPEC_FYL2X))
14073 (clobber (match_scratch:XF 3 ""))])]
14074 "TARGET_USE_FANCY_MATH_387
14075 && flag_unsafe_math_optimizations"
14076 {
14077 operands[2] = gen_reg_rtx (XFmode);
14078 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14079 })
14080
14081 (define_expand "log2<mode>2"
14082 [(use (match_operand:MODEF 0 "register_operand" ""))
14083 (use (match_operand:MODEF 1 "register_operand" ""))]
14084 "TARGET_USE_FANCY_MATH_387
14085 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14086 || TARGET_MIX_SSE_I387)
14087 && flag_unsafe_math_optimizations"
14088 {
14089 rtx op0 = gen_reg_rtx (XFmode);
14090
14091 rtx op2 = gen_reg_rtx (XFmode);
14092 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14093
14094 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14095 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14096 DONE;
14097 })
14098
14099 (define_insn "fyl2xp1xf3_i387"
14100 [(set (match_operand:XF 0 "register_operand" "=f")
14101 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14102 (match_operand:XF 2 "register_operand" "u")]
14103 UNSPEC_FYL2XP1))
14104 (clobber (match_scratch:XF 3 "=2"))]
14105 "TARGET_USE_FANCY_MATH_387
14106 && flag_unsafe_math_optimizations"
14107 "fyl2xp1"
14108 [(set_attr "type" "fpspc")
14109 (set_attr "mode" "XF")])
14110
14111 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14112 [(set (match_operand:XF 0 "register_operand" "=f")
14113 (unspec:XF [(float_extend:XF
14114 (match_operand:MODEF 1 "register_operand" "0"))
14115 (match_operand:XF 2 "register_operand" "u")]
14116 UNSPEC_FYL2XP1))
14117 (clobber (match_scratch:XF 3 "=2"))]
14118 "TARGET_USE_FANCY_MATH_387
14119 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14120 || TARGET_MIX_SSE_I387)
14121 && flag_unsafe_math_optimizations"
14122 "fyl2xp1"
14123 [(set_attr "type" "fpspc")
14124 (set_attr "mode" "XF")])
14125
14126 (define_expand "log1pxf2"
14127 [(use (match_operand:XF 0 "register_operand" ""))
14128 (use (match_operand:XF 1 "register_operand" ""))]
14129 "TARGET_USE_FANCY_MATH_387
14130 && flag_unsafe_math_optimizations"
14131 {
14132 if (optimize_insn_for_size_p ())
14133 FAIL;
14134
14135 ix86_emit_i387_log1p (operands[0], operands[1]);
14136 DONE;
14137 })
14138
14139 (define_expand "log1p<mode>2"
14140 [(use (match_operand:MODEF 0 "register_operand" ""))
14141 (use (match_operand:MODEF 1 "register_operand" ""))]
14142 "TARGET_USE_FANCY_MATH_387
14143 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14144 || TARGET_MIX_SSE_I387)
14145 && flag_unsafe_math_optimizations"
14146 {
14147 rtx op0;
14148
14149 if (optimize_insn_for_size_p ())
14150 FAIL;
14151
14152 op0 = gen_reg_rtx (XFmode);
14153
14154 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14155
14156 ix86_emit_i387_log1p (op0, operands[1]);
14157 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14158 DONE;
14159 })
14160
14161 (define_insn "fxtractxf3_i387"
14162 [(set (match_operand:XF 0 "register_operand" "=f")
14163 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14164 UNSPEC_XTRACT_FRACT))
14165 (set (match_operand:XF 1 "register_operand" "=u")
14166 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14167 "TARGET_USE_FANCY_MATH_387
14168 && flag_unsafe_math_optimizations"
14169 "fxtract"
14170 [(set_attr "type" "fpspc")
14171 (set_attr "mode" "XF")])
14172
14173 (define_insn "fxtract_extend<mode>xf3_i387"
14174 [(set (match_operand:XF 0 "register_operand" "=f")
14175 (unspec:XF [(float_extend:XF
14176 (match_operand:MODEF 2 "register_operand" "0"))]
14177 UNSPEC_XTRACT_FRACT))
14178 (set (match_operand:XF 1 "register_operand" "=u")
14179 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14180 "TARGET_USE_FANCY_MATH_387
14181 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14182 || TARGET_MIX_SSE_I387)
14183 && flag_unsafe_math_optimizations"
14184 "fxtract"
14185 [(set_attr "type" "fpspc")
14186 (set_attr "mode" "XF")])
14187
14188 (define_expand "logbxf2"
14189 [(parallel [(set (match_dup 2)
14190 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14191 UNSPEC_XTRACT_FRACT))
14192 (set (match_operand:XF 0 "register_operand" "")
14193 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14194 "TARGET_USE_FANCY_MATH_387
14195 && flag_unsafe_math_optimizations"
14196 "operands[2] = gen_reg_rtx (XFmode);")
14197
14198 (define_expand "logb<mode>2"
14199 [(use (match_operand:MODEF 0 "register_operand" ""))
14200 (use (match_operand:MODEF 1 "register_operand" ""))]
14201 "TARGET_USE_FANCY_MATH_387
14202 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14203 || TARGET_MIX_SSE_I387)
14204 && flag_unsafe_math_optimizations"
14205 {
14206 rtx op0 = gen_reg_rtx (XFmode);
14207 rtx op1 = gen_reg_rtx (XFmode);
14208
14209 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14210 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14211 DONE;
14212 })
14213
14214 (define_expand "ilogbxf2"
14215 [(use (match_operand:SI 0 "register_operand" ""))
14216 (use (match_operand:XF 1 "register_operand" ""))]
14217 "TARGET_USE_FANCY_MATH_387
14218 && flag_unsafe_math_optimizations"
14219 {
14220 rtx op0, op1;
14221
14222 if (optimize_insn_for_size_p ())
14223 FAIL;
14224
14225 op0 = gen_reg_rtx (XFmode);
14226 op1 = gen_reg_rtx (XFmode);
14227
14228 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14229 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14230 DONE;
14231 })
14232
14233 (define_expand "ilogb<mode>2"
14234 [(use (match_operand:SI 0 "register_operand" ""))
14235 (use (match_operand:MODEF 1 "register_operand" ""))]
14236 "TARGET_USE_FANCY_MATH_387
14237 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14238 || TARGET_MIX_SSE_I387)
14239 && flag_unsafe_math_optimizations"
14240 {
14241 rtx op0, op1;
14242
14243 if (optimize_insn_for_size_p ())
14244 FAIL;
14245
14246 op0 = gen_reg_rtx (XFmode);
14247 op1 = gen_reg_rtx (XFmode);
14248
14249 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14250 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14251 DONE;
14252 })
14253
14254 (define_insn "*f2xm1xf2_i387"
14255 [(set (match_operand:XF 0 "register_operand" "=f")
14256 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14257 UNSPEC_F2XM1))]
14258 "TARGET_USE_FANCY_MATH_387
14259 && flag_unsafe_math_optimizations"
14260 "f2xm1"
14261 [(set_attr "type" "fpspc")
14262 (set_attr "mode" "XF")])
14263
14264 (define_insn "*fscalexf4_i387"
14265 [(set (match_operand:XF 0 "register_operand" "=f")
14266 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14267 (match_operand:XF 3 "register_operand" "1")]
14268 UNSPEC_FSCALE_FRACT))
14269 (set (match_operand:XF 1 "register_operand" "=u")
14270 (unspec:XF [(match_dup 2) (match_dup 3)]
14271 UNSPEC_FSCALE_EXP))]
14272 "TARGET_USE_FANCY_MATH_387
14273 && flag_unsafe_math_optimizations"
14274 "fscale"
14275 [(set_attr "type" "fpspc")
14276 (set_attr "mode" "XF")])
14277
14278 (define_expand "expNcorexf3"
14279 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14280 (match_operand:XF 2 "register_operand" "")))
14281 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14282 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14283 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14284 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14285 (parallel [(set (match_operand:XF 0 "register_operand" "")
14286 (unspec:XF [(match_dup 8) (match_dup 4)]
14287 UNSPEC_FSCALE_FRACT))
14288 (set (match_dup 9)
14289 (unspec:XF [(match_dup 8) (match_dup 4)]
14290 UNSPEC_FSCALE_EXP))])]
14291 "TARGET_USE_FANCY_MATH_387
14292 && flag_unsafe_math_optimizations"
14293 {
14294 int i;
14295
14296 if (optimize_insn_for_size_p ())
14297 FAIL;
14298
14299 for (i = 3; i < 10; i++)
14300 operands[i] = gen_reg_rtx (XFmode);
14301
14302 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14303 })
14304
14305 (define_expand "expxf2"
14306 [(use (match_operand:XF 0 "register_operand" ""))
14307 (use (match_operand:XF 1 "register_operand" ""))]
14308 "TARGET_USE_FANCY_MATH_387
14309 && flag_unsafe_math_optimizations"
14310 {
14311 rtx op2;
14312
14313 if (optimize_insn_for_size_p ())
14314 FAIL;
14315
14316 op2 = gen_reg_rtx (XFmode);
14317 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14318
14319 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14320 DONE;
14321 })
14322
14323 (define_expand "exp<mode>2"
14324 [(use (match_operand:MODEF 0 "register_operand" ""))
14325 (use (match_operand:MODEF 1 "general_operand" ""))]
14326 "TARGET_USE_FANCY_MATH_387
14327 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14328 || TARGET_MIX_SSE_I387)
14329 && flag_unsafe_math_optimizations"
14330 {
14331 rtx op0, op1;
14332
14333 if (optimize_insn_for_size_p ())
14334 FAIL;
14335
14336 op0 = gen_reg_rtx (XFmode);
14337 op1 = gen_reg_rtx (XFmode);
14338
14339 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14340 emit_insn (gen_expxf2 (op0, op1));
14341 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14342 DONE;
14343 })
14344
14345 (define_expand "exp10xf2"
14346 [(use (match_operand:XF 0 "register_operand" ""))
14347 (use (match_operand:XF 1 "register_operand" ""))]
14348 "TARGET_USE_FANCY_MATH_387
14349 && flag_unsafe_math_optimizations"
14350 {
14351 rtx op2;
14352
14353 if (optimize_insn_for_size_p ())
14354 FAIL;
14355
14356 op2 = gen_reg_rtx (XFmode);
14357 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14358
14359 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14360 DONE;
14361 })
14362
14363 (define_expand "exp10<mode>2"
14364 [(use (match_operand:MODEF 0 "register_operand" ""))
14365 (use (match_operand:MODEF 1 "general_operand" ""))]
14366 "TARGET_USE_FANCY_MATH_387
14367 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14368 || TARGET_MIX_SSE_I387)
14369 && flag_unsafe_math_optimizations"
14370 {
14371 rtx op0, op1;
14372
14373 if (optimize_insn_for_size_p ())
14374 FAIL;
14375
14376 op0 = gen_reg_rtx (XFmode);
14377 op1 = gen_reg_rtx (XFmode);
14378
14379 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14380 emit_insn (gen_exp10xf2 (op0, op1));
14381 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14382 DONE;
14383 })
14384
14385 (define_expand "exp2xf2"
14386 [(use (match_operand:XF 0 "register_operand" ""))
14387 (use (match_operand:XF 1 "register_operand" ""))]
14388 "TARGET_USE_FANCY_MATH_387
14389 && flag_unsafe_math_optimizations"
14390 {
14391 rtx op2;
14392
14393 if (optimize_insn_for_size_p ())
14394 FAIL;
14395
14396 op2 = gen_reg_rtx (XFmode);
14397 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14398
14399 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14400 DONE;
14401 })
14402
14403 (define_expand "exp2<mode>2"
14404 [(use (match_operand:MODEF 0 "register_operand" ""))
14405 (use (match_operand:MODEF 1 "general_operand" ""))]
14406 "TARGET_USE_FANCY_MATH_387
14407 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14408 || TARGET_MIX_SSE_I387)
14409 && flag_unsafe_math_optimizations"
14410 {
14411 rtx op0, op1;
14412
14413 if (optimize_insn_for_size_p ())
14414 FAIL;
14415
14416 op0 = gen_reg_rtx (XFmode);
14417 op1 = gen_reg_rtx (XFmode);
14418
14419 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14420 emit_insn (gen_exp2xf2 (op0, op1));
14421 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14422 DONE;
14423 })
14424
14425 (define_expand "expm1xf2"
14426 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14427 (match_dup 2)))
14428 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14429 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14430 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14431 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14432 (parallel [(set (match_dup 7)
14433 (unspec:XF [(match_dup 6) (match_dup 4)]
14434 UNSPEC_FSCALE_FRACT))
14435 (set (match_dup 8)
14436 (unspec:XF [(match_dup 6) (match_dup 4)]
14437 UNSPEC_FSCALE_EXP))])
14438 (parallel [(set (match_dup 10)
14439 (unspec:XF [(match_dup 9) (match_dup 8)]
14440 UNSPEC_FSCALE_FRACT))
14441 (set (match_dup 11)
14442 (unspec:XF [(match_dup 9) (match_dup 8)]
14443 UNSPEC_FSCALE_EXP))])
14444 (set (match_dup 12) (minus:XF (match_dup 10)
14445 (float_extend:XF (match_dup 13))))
14446 (set (match_operand:XF 0 "register_operand" "")
14447 (plus:XF (match_dup 12) (match_dup 7)))]
14448 "TARGET_USE_FANCY_MATH_387
14449 && flag_unsafe_math_optimizations"
14450 {
14451 int i;
14452
14453 if (optimize_insn_for_size_p ())
14454 FAIL;
14455
14456 for (i = 2; i < 13; i++)
14457 operands[i] = gen_reg_rtx (XFmode);
14458
14459 operands[13]
14460 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14461
14462 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14463 })
14464
14465 (define_expand "expm1<mode>2"
14466 [(use (match_operand:MODEF 0 "register_operand" ""))
14467 (use (match_operand:MODEF 1 "general_operand" ""))]
14468 "TARGET_USE_FANCY_MATH_387
14469 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14470 || TARGET_MIX_SSE_I387)
14471 && flag_unsafe_math_optimizations"
14472 {
14473 rtx op0, op1;
14474
14475 if (optimize_insn_for_size_p ())
14476 FAIL;
14477
14478 op0 = gen_reg_rtx (XFmode);
14479 op1 = gen_reg_rtx (XFmode);
14480
14481 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14482 emit_insn (gen_expm1xf2 (op0, op1));
14483 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14484 DONE;
14485 })
14486
14487 (define_expand "ldexpxf3"
14488 [(set (match_dup 3)
14489 (float:XF (match_operand:SI 2 "register_operand" "")))
14490 (parallel [(set (match_operand:XF 0 " register_operand" "")
14491 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14492 (match_dup 3)]
14493 UNSPEC_FSCALE_FRACT))
14494 (set (match_dup 4)
14495 (unspec:XF [(match_dup 1) (match_dup 3)]
14496 UNSPEC_FSCALE_EXP))])]
14497 "TARGET_USE_FANCY_MATH_387
14498 && flag_unsafe_math_optimizations"
14499 {
14500 if (optimize_insn_for_size_p ())
14501 FAIL;
14502
14503 operands[3] = gen_reg_rtx (XFmode);
14504 operands[4] = gen_reg_rtx (XFmode);
14505 })
14506
14507 (define_expand "ldexp<mode>3"
14508 [(use (match_operand:MODEF 0 "register_operand" ""))
14509 (use (match_operand:MODEF 1 "general_operand" ""))
14510 (use (match_operand:SI 2 "register_operand" ""))]
14511 "TARGET_USE_FANCY_MATH_387
14512 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14513 || TARGET_MIX_SSE_I387)
14514 && flag_unsafe_math_optimizations"
14515 {
14516 rtx op0, op1;
14517
14518 if (optimize_insn_for_size_p ())
14519 FAIL;
14520
14521 op0 = gen_reg_rtx (XFmode);
14522 op1 = gen_reg_rtx (XFmode);
14523
14524 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14525 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14526 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14527 DONE;
14528 })
14529
14530 (define_expand "scalbxf3"
14531 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14532 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14533 (match_operand:XF 2 "register_operand" "")]
14534 UNSPEC_FSCALE_FRACT))
14535 (set (match_dup 3)
14536 (unspec:XF [(match_dup 1) (match_dup 2)]
14537 UNSPEC_FSCALE_EXP))])]
14538 "TARGET_USE_FANCY_MATH_387
14539 && flag_unsafe_math_optimizations"
14540 {
14541 if (optimize_insn_for_size_p ())
14542 FAIL;
14543
14544 operands[3] = gen_reg_rtx (XFmode);
14545 })
14546
14547 (define_expand "scalb<mode>3"
14548 [(use (match_operand:MODEF 0 "register_operand" ""))
14549 (use (match_operand:MODEF 1 "general_operand" ""))
14550 (use (match_operand:MODEF 2 "general_operand" ""))]
14551 "TARGET_USE_FANCY_MATH_387
14552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14553 || TARGET_MIX_SSE_I387)
14554 && flag_unsafe_math_optimizations"
14555 {
14556 rtx op0, op1, op2;
14557
14558 if (optimize_insn_for_size_p ())
14559 FAIL;
14560
14561 op0 = gen_reg_rtx (XFmode);
14562 op1 = gen_reg_rtx (XFmode);
14563 op2 = gen_reg_rtx (XFmode);
14564
14565 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14566 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14567 emit_insn (gen_scalbxf3 (op0, op1, op2));
14568 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14569 DONE;
14570 })
14571
14572 (define_expand "significandxf2"
14573 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14574 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14575 UNSPEC_XTRACT_FRACT))
14576 (set (match_dup 2)
14577 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14578 "TARGET_USE_FANCY_MATH_387
14579 && flag_unsafe_math_optimizations"
14580 "operands[2] = gen_reg_rtx (XFmode);")
14581
14582 (define_expand "significand<mode>2"
14583 [(use (match_operand:MODEF 0 "register_operand" ""))
14584 (use (match_operand:MODEF 1 "register_operand" ""))]
14585 "TARGET_USE_FANCY_MATH_387
14586 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14587 || TARGET_MIX_SSE_I387)
14588 && flag_unsafe_math_optimizations"
14589 {
14590 rtx op0 = gen_reg_rtx (XFmode);
14591 rtx op1 = gen_reg_rtx (XFmode);
14592
14593 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14594 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14595 DONE;
14596 })
14597 \f
14598
14599 (define_insn "sse4_1_round<mode>2"
14600 [(set (match_operand:MODEF 0 "register_operand" "=x")
14601 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14602 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14603 UNSPEC_ROUND))]
14604 "TARGET_ROUND"
14605 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14606 [(set_attr "type" "ssecvt")
14607 (set_attr "prefix_extra" "1")
14608 (set_attr "prefix" "maybe_vex")
14609 (set_attr "mode" "<MODE>")])
14610
14611 (define_insn "rintxf2"
14612 [(set (match_operand:XF 0 "register_operand" "=f")
14613 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14614 UNSPEC_FRNDINT))]
14615 "TARGET_USE_FANCY_MATH_387
14616 && flag_unsafe_math_optimizations"
14617 "frndint"
14618 [(set_attr "type" "fpspc")
14619 (set_attr "mode" "XF")])
14620
14621 (define_expand "rint<mode>2"
14622 [(use (match_operand:MODEF 0 "register_operand" ""))
14623 (use (match_operand:MODEF 1 "register_operand" ""))]
14624 "(TARGET_USE_FANCY_MATH_387
14625 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14626 || TARGET_MIX_SSE_I387)
14627 && flag_unsafe_math_optimizations)
14628 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14629 && !flag_trapping_math)"
14630 {
14631 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14632 && !flag_trapping_math)
14633 {
14634 if (TARGET_ROUND)
14635 emit_insn (gen_sse4_1_round<mode>2
14636 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14637 else if (optimize_insn_for_size_p ())
14638 FAIL;
14639 else
14640 ix86_expand_rint (operand0, operand1);
14641 }
14642 else
14643 {
14644 rtx op0 = gen_reg_rtx (XFmode);
14645 rtx op1 = gen_reg_rtx (XFmode);
14646
14647 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14648 emit_insn (gen_rintxf2 (op0, op1));
14649
14650 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14651 }
14652 DONE;
14653 })
14654
14655 (define_expand "round<mode>2"
14656 [(match_operand:X87MODEF 0 "register_operand" "")
14657 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14658 "(TARGET_USE_FANCY_MATH_387
14659 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14660 || TARGET_MIX_SSE_I387)
14661 && flag_unsafe_math_optimizations)
14662 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14663 && !flag_trapping_math && !flag_rounding_math)"
14664 {
14665 if (optimize_insn_for_size_p ())
14666 FAIL;
14667
14668 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14669 && !flag_trapping_math && !flag_rounding_math)
14670 {
14671 if (TARGET_ROUND)
14672 {
14673 operands[1] = force_reg (<MODE>mode, operands[1]);
14674 ix86_expand_round_sse4 (operands[0], operands[1]);
14675 }
14676 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14677 ix86_expand_round (operands[0], operands[1]);
14678 else
14679 ix86_expand_rounddf_32 (operands[0], operands[1]);
14680 }
14681 else
14682 {
14683 operands[1] = force_reg (<MODE>mode, operands[1]);
14684 ix86_emit_i387_round (operands[0], operands[1]);
14685 }
14686 DONE;
14687 })
14688
14689 (define_insn_and_split "*fistdi2_1"
14690 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14691 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14692 UNSPEC_FIST))]
14693 "TARGET_USE_FANCY_MATH_387
14694 && can_create_pseudo_p ()"
14695 "#"
14696 "&& 1"
14697 [(const_int 0)]
14698 {
14699 if (memory_operand (operands[0], VOIDmode))
14700 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14701 else
14702 {
14703 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14704 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14705 operands[2]));
14706 }
14707 DONE;
14708 }
14709 [(set_attr "type" "fpspc")
14710 (set_attr "mode" "DI")])
14711
14712 (define_insn "fistdi2"
14713 [(set (match_operand:DI 0 "memory_operand" "=m")
14714 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14715 UNSPEC_FIST))
14716 (clobber (match_scratch:XF 2 "=&1f"))]
14717 "TARGET_USE_FANCY_MATH_387"
14718 "* return output_fix_trunc (insn, operands, false);"
14719 [(set_attr "type" "fpspc")
14720 (set_attr "mode" "DI")])
14721
14722 (define_insn "fistdi2_with_temp"
14723 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14724 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14725 UNSPEC_FIST))
14726 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14727 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14728 "TARGET_USE_FANCY_MATH_387"
14729 "#"
14730 [(set_attr "type" "fpspc")
14731 (set_attr "mode" "DI")])
14732
14733 (define_split
14734 [(set (match_operand:DI 0 "register_operand" "")
14735 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14736 UNSPEC_FIST))
14737 (clobber (match_operand:DI 2 "memory_operand" ""))
14738 (clobber (match_scratch 3 ""))]
14739 "reload_completed"
14740 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14741 (clobber (match_dup 3))])
14742 (set (match_dup 0) (match_dup 2))])
14743
14744 (define_split
14745 [(set (match_operand:DI 0 "memory_operand" "")
14746 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14747 UNSPEC_FIST))
14748 (clobber (match_operand:DI 2 "memory_operand" ""))
14749 (clobber (match_scratch 3 ""))]
14750 "reload_completed"
14751 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14752 (clobber (match_dup 3))])])
14753
14754 (define_insn_and_split "*fist<mode>2_1"
14755 [(set (match_operand:SWI24 0 "register_operand" "")
14756 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14757 UNSPEC_FIST))]
14758 "TARGET_USE_FANCY_MATH_387
14759 && can_create_pseudo_p ()"
14760 "#"
14761 "&& 1"
14762 [(const_int 0)]
14763 {
14764 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14765 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14766 operands[2]));
14767 DONE;
14768 }
14769 [(set_attr "type" "fpspc")
14770 (set_attr "mode" "<MODE>")])
14771
14772 (define_insn "fist<mode>2"
14773 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14774 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14775 UNSPEC_FIST))]
14776 "TARGET_USE_FANCY_MATH_387"
14777 "* return output_fix_trunc (insn, operands, false);"
14778 [(set_attr "type" "fpspc")
14779 (set_attr "mode" "<MODE>")])
14780
14781 (define_insn "fist<mode>2_with_temp"
14782 [(set (match_operand:SWI24 0 "register_operand" "=r")
14783 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14784 UNSPEC_FIST))
14785 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14786 "TARGET_USE_FANCY_MATH_387"
14787 "#"
14788 [(set_attr "type" "fpspc")
14789 (set_attr "mode" "<MODE>")])
14790
14791 (define_split
14792 [(set (match_operand:SWI24 0 "register_operand" "")
14793 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14794 UNSPEC_FIST))
14795 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14796 "reload_completed"
14797 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14798 (set (match_dup 0) (match_dup 2))])
14799
14800 (define_split
14801 [(set (match_operand:SWI24 0 "memory_operand" "")
14802 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14803 UNSPEC_FIST))
14804 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14805 "reload_completed"
14806 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14807
14808 (define_expand "lrintxf<mode>2"
14809 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14810 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14811 UNSPEC_FIST))]
14812 "TARGET_USE_FANCY_MATH_387")
14813
14814 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14815 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14816 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14817 UNSPEC_FIX_NOTRUNC))]
14818 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14819 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14820
14821 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14822 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14823 (match_operand:X87MODEF 1 "register_operand" "")]
14824 "(TARGET_USE_FANCY_MATH_387
14825 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14826 || TARGET_MIX_SSE_I387)
14827 && flag_unsafe_math_optimizations)
14828 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14829 && <SWI248x:MODE>mode != HImode
14830 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14831 && !flag_trapping_math && !flag_rounding_math)"
14832 {
14833 if (optimize_insn_for_size_p ())
14834 FAIL;
14835
14836 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14837 && <SWI248x:MODE>mode != HImode
14838 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14839 && !flag_trapping_math && !flag_rounding_math)
14840 ix86_expand_lround (operand0, operand1);
14841 else
14842 ix86_emit_i387_round (operands[0], operands[1]);
14843 DONE;
14844 })
14845
14846 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14847 (define_insn_and_split "frndintxf2_floor"
14848 [(set (match_operand:XF 0 "register_operand" "")
14849 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14850 UNSPEC_FRNDINT_FLOOR))
14851 (clobber (reg:CC FLAGS_REG))]
14852 "TARGET_USE_FANCY_MATH_387
14853 && flag_unsafe_math_optimizations
14854 && can_create_pseudo_p ()"
14855 "#"
14856 "&& 1"
14857 [(const_int 0)]
14858 {
14859 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14860
14861 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14862 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14863
14864 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14865 operands[2], operands[3]));
14866 DONE;
14867 }
14868 [(set_attr "type" "frndint")
14869 (set_attr "i387_cw" "floor")
14870 (set_attr "mode" "XF")])
14871
14872 (define_insn "frndintxf2_floor_i387"
14873 [(set (match_operand:XF 0 "register_operand" "=f")
14874 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14875 UNSPEC_FRNDINT_FLOOR))
14876 (use (match_operand:HI 2 "memory_operand" "m"))
14877 (use (match_operand:HI 3 "memory_operand" "m"))]
14878 "TARGET_USE_FANCY_MATH_387
14879 && flag_unsafe_math_optimizations"
14880 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14881 [(set_attr "type" "frndint")
14882 (set_attr "i387_cw" "floor")
14883 (set_attr "mode" "XF")])
14884
14885 (define_expand "floorxf2"
14886 [(use (match_operand:XF 0 "register_operand" ""))
14887 (use (match_operand:XF 1 "register_operand" ""))]
14888 "TARGET_USE_FANCY_MATH_387
14889 && flag_unsafe_math_optimizations"
14890 {
14891 if (optimize_insn_for_size_p ())
14892 FAIL;
14893 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14894 DONE;
14895 })
14896
14897 (define_expand "floor<mode>2"
14898 [(use (match_operand:MODEF 0 "register_operand" ""))
14899 (use (match_operand:MODEF 1 "register_operand" ""))]
14900 "(TARGET_USE_FANCY_MATH_387
14901 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14902 || TARGET_MIX_SSE_I387)
14903 && flag_unsafe_math_optimizations)
14904 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14905 && !flag_trapping_math)"
14906 {
14907 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14908 && !flag_trapping_math)
14909 {
14910 if (TARGET_ROUND)
14911 emit_insn (gen_sse4_1_round<mode>2
14912 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14913 else if (optimize_insn_for_size_p ())
14914 FAIL;
14915 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14916 ix86_expand_floorceil (operand0, operand1, true);
14917 else
14918 ix86_expand_floorceildf_32 (operand0, operand1, true);
14919 }
14920 else
14921 {
14922 rtx op0, op1;
14923
14924 if (optimize_insn_for_size_p ())
14925 FAIL;
14926
14927 op0 = gen_reg_rtx (XFmode);
14928 op1 = gen_reg_rtx (XFmode);
14929 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14930 emit_insn (gen_frndintxf2_floor (op0, op1));
14931
14932 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14933 }
14934 DONE;
14935 })
14936
14937 (define_insn_and_split "*fist<mode>2_floor_1"
14938 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14939 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14940 UNSPEC_FIST_FLOOR))
14941 (clobber (reg:CC FLAGS_REG))]
14942 "TARGET_USE_FANCY_MATH_387
14943 && flag_unsafe_math_optimizations
14944 && can_create_pseudo_p ()"
14945 "#"
14946 "&& 1"
14947 [(const_int 0)]
14948 {
14949 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14950
14951 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14952 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14953 if (memory_operand (operands[0], VOIDmode))
14954 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14955 operands[2], operands[3]));
14956 else
14957 {
14958 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14959 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14960 operands[2], operands[3],
14961 operands[4]));
14962 }
14963 DONE;
14964 }
14965 [(set_attr "type" "fistp")
14966 (set_attr "i387_cw" "floor")
14967 (set_attr "mode" "<MODE>")])
14968
14969 (define_insn "fistdi2_floor"
14970 [(set (match_operand:DI 0 "memory_operand" "=m")
14971 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14972 UNSPEC_FIST_FLOOR))
14973 (use (match_operand:HI 2 "memory_operand" "m"))
14974 (use (match_operand:HI 3 "memory_operand" "m"))
14975 (clobber (match_scratch:XF 4 "=&1f"))]
14976 "TARGET_USE_FANCY_MATH_387
14977 && flag_unsafe_math_optimizations"
14978 "* return output_fix_trunc (insn, operands, false);"
14979 [(set_attr "type" "fistp")
14980 (set_attr "i387_cw" "floor")
14981 (set_attr "mode" "DI")])
14982
14983 (define_insn "fistdi2_floor_with_temp"
14984 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14985 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14986 UNSPEC_FIST_FLOOR))
14987 (use (match_operand:HI 2 "memory_operand" "m,m"))
14988 (use (match_operand:HI 3 "memory_operand" "m,m"))
14989 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14990 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14991 "TARGET_USE_FANCY_MATH_387
14992 && flag_unsafe_math_optimizations"
14993 "#"
14994 [(set_attr "type" "fistp")
14995 (set_attr "i387_cw" "floor")
14996 (set_attr "mode" "DI")])
14997
14998 (define_split
14999 [(set (match_operand:DI 0 "register_operand" "")
15000 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15001 UNSPEC_FIST_FLOOR))
15002 (use (match_operand:HI 2 "memory_operand" ""))
15003 (use (match_operand:HI 3 "memory_operand" ""))
15004 (clobber (match_operand:DI 4 "memory_operand" ""))
15005 (clobber (match_scratch 5 ""))]
15006 "reload_completed"
15007 [(parallel [(set (match_dup 4)
15008 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15009 (use (match_dup 2))
15010 (use (match_dup 3))
15011 (clobber (match_dup 5))])
15012 (set (match_dup 0) (match_dup 4))])
15013
15014 (define_split
15015 [(set (match_operand:DI 0 "memory_operand" "")
15016 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15017 UNSPEC_FIST_FLOOR))
15018 (use (match_operand:HI 2 "memory_operand" ""))
15019 (use (match_operand:HI 3 "memory_operand" ""))
15020 (clobber (match_operand:DI 4 "memory_operand" ""))
15021 (clobber (match_scratch 5 ""))]
15022 "reload_completed"
15023 [(parallel [(set (match_dup 0)
15024 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15025 (use (match_dup 2))
15026 (use (match_dup 3))
15027 (clobber (match_dup 5))])])
15028
15029 (define_insn "fist<mode>2_floor"
15030 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15031 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15032 UNSPEC_FIST_FLOOR))
15033 (use (match_operand:HI 2 "memory_operand" "m"))
15034 (use (match_operand:HI 3 "memory_operand" "m"))]
15035 "TARGET_USE_FANCY_MATH_387
15036 && flag_unsafe_math_optimizations"
15037 "* return output_fix_trunc (insn, operands, false);"
15038 [(set_attr "type" "fistp")
15039 (set_attr "i387_cw" "floor")
15040 (set_attr "mode" "<MODE>")])
15041
15042 (define_insn "fist<mode>2_floor_with_temp"
15043 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15044 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15045 UNSPEC_FIST_FLOOR))
15046 (use (match_operand:HI 2 "memory_operand" "m,m"))
15047 (use (match_operand:HI 3 "memory_operand" "m,m"))
15048 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15049 "TARGET_USE_FANCY_MATH_387
15050 && flag_unsafe_math_optimizations"
15051 "#"
15052 [(set_attr "type" "fistp")
15053 (set_attr "i387_cw" "floor")
15054 (set_attr "mode" "<MODE>")])
15055
15056 (define_split
15057 [(set (match_operand:SWI24 0 "register_operand" "")
15058 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15059 UNSPEC_FIST_FLOOR))
15060 (use (match_operand:HI 2 "memory_operand" ""))
15061 (use (match_operand:HI 3 "memory_operand" ""))
15062 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15063 "reload_completed"
15064 [(parallel [(set (match_dup 4)
15065 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15066 (use (match_dup 2))
15067 (use (match_dup 3))])
15068 (set (match_dup 0) (match_dup 4))])
15069
15070 (define_split
15071 [(set (match_operand:SWI24 0 "memory_operand" "")
15072 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15073 UNSPEC_FIST_FLOOR))
15074 (use (match_operand:HI 2 "memory_operand" ""))
15075 (use (match_operand:HI 3 "memory_operand" ""))
15076 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15077 "reload_completed"
15078 [(parallel [(set (match_dup 0)
15079 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15080 (use (match_dup 2))
15081 (use (match_dup 3))])])
15082
15083 (define_expand "lfloorxf<mode>2"
15084 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15085 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15086 UNSPEC_FIST_FLOOR))
15087 (clobber (reg:CC FLAGS_REG))])]
15088 "TARGET_USE_FANCY_MATH_387
15089 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15090 && flag_unsafe_math_optimizations")
15091
15092 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15093 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15094 (match_operand:MODEF 1 "register_operand" "")]
15095 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15096 && !flag_trapping_math"
15097 {
15098 if (TARGET_64BIT && optimize_insn_for_size_p ())
15099 FAIL;
15100 ix86_expand_lfloorceil (operand0, operand1, true);
15101 DONE;
15102 })
15103
15104 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15105 (define_insn_and_split "frndintxf2_ceil"
15106 [(set (match_operand:XF 0 "register_operand" "")
15107 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15108 UNSPEC_FRNDINT_CEIL))
15109 (clobber (reg:CC FLAGS_REG))]
15110 "TARGET_USE_FANCY_MATH_387
15111 && flag_unsafe_math_optimizations
15112 && can_create_pseudo_p ()"
15113 "#"
15114 "&& 1"
15115 [(const_int 0)]
15116 {
15117 ix86_optimize_mode_switching[I387_CEIL] = 1;
15118
15119 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15120 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15121
15122 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15123 operands[2], operands[3]));
15124 DONE;
15125 }
15126 [(set_attr "type" "frndint")
15127 (set_attr "i387_cw" "ceil")
15128 (set_attr "mode" "XF")])
15129
15130 (define_insn "frndintxf2_ceil_i387"
15131 [(set (match_operand:XF 0 "register_operand" "=f")
15132 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15133 UNSPEC_FRNDINT_CEIL))
15134 (use (match_operand:HI 2 "memory_operand" "m"))
15135 (use (match_operand:HI 3 "memory_operand" "m"))]
15136 "TARGET_USE_FANCY_MATH_387
15137 && flag_unsafe_math_optimizations"
15138 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15139 [(set_attr "type" "frndint")
15140 (set_attr "i387_cw" "ceil")
15141 (set_attr "mode" "XF")])
15142
15143 (define_expand "ceilxf2"
15144 [(use (match_operand:XF 0 "register_operand" ""))
15145 (use (match_operand:XF 1 "register_operand" ""))]
15146 "TARGET_USE_FANCY_MATH_387
15147 && flag_unsafe_math_optimizations"
15148 {
15149 if (optimize_insn_for_size_p ())
15150 FAIL;
15151 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15152 DONE;
15153 })
15154
15155 (define_expand "ceil<mode>2"
15156 [(use (match_operand:MODEF 0 "register_operand" ""))
15157 (use (match_operand:MODEF 1 "register_operand" ""))]
15158 "(TARGET_USE_FANCY_MATH_387
15159 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15160 || TARGET_MIX_SSE_I387)
15161 && flag_unsafe_math_optimizations)
15162 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15163 && !flag_trapping_math)"
15164 {
15165 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15166 && !flag_trapping_math)
15167 {
15168 if (TARGET_ROUND)
15169 emit_insn (gen_sse4_1_round<mode>2
15170 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15171 else if (optimize_insn_for_size_p ())
15172 FAIL;
15173 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15174 ix86_expand_floorceil (operand0, operand1, false);
15175 else
15176 ix86_expand_floorceildf_32 (operand0, operand1, false);
15177 }
15178 else
15179 {
15180 rtx op0, op1;
15181
15182 if (optimize_insn_for_size_p ())
15183 FAIL;
15184
15185 op0 = gen_reg_rtx (XFmode);
15186 op1 = gen_reg_rtx (XFmode);
15187 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15188 emit_insn (gen_frndintxf2_ceil (op0, op1));
15189
15190 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15191 }
15192 DONE;
15193 })
15194
15195 (define_insn_and_split "*fist<mode>2_ceil_1"
15196 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15197 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15198 UNSPEC_FIST_CEIL))
15199 (clobber (reg:CC FLAGS_REG))]
15200 "TARGET_USE_FANCY_MATH_387
15201 && flag_unsafe_math_optimizations
15202 && can_create_pseudo_p ()"
15203 "#"
15204 "&& 1"
15205 [(const_int 0)]
15206 {
15207 ix86_optimize_mode_switching[I387_CEIL] = 1;
15208
15209 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15210 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15211 if (memory_operand (operands[0], VOIDmode))
15212 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15213 operands[2], operands[3]));
15214 else
15215 {
15216 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15217 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15218 operands[2], operands[3],
15219 operands[4]));
15220 }
15221 DONE;
15222 }
15223 [(set_attr "type" "fistp")
15224 (set_attr "i387_cw" "ceil")
15225 (set_attr "mode" "<MODE>")])
15226
15227 (define_insn "fistdi2_ceil"
15228 [(set (match_operand:DI 0 "memory_operand" "=m")
15229 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15230 UNSPEC_FIST_CEIL))
15231 (use (match_operand:HI 2 "memory_operand" "m"))
15232 (use (match_operand:HI 3 "memory_operand" "m"))
15233 (clobber (match_scratch:XF 4 "=&1f"))]
15234 "TARGET_USE_FANCY_MATH_387
15235 && flag_unsafe_math_optimizations"
15236 "* return output_fix_trunc (insn, operands, false);"
15237 [(set_attr "type" "fistp")
15238 (set_attr "i387_cw" "ceil")
15239 (set_attr "mode" "DI")])
15240
15241 (define_insn "fistdi2_ceil_with_temp"
15242 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15243 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15244 UNSPEC_FIST_CEIL))
15245 (use (match_operand:HI 2 "memory_operand" "m,m"))
15246 (use (match_operand:HI 3 "memory_operand" "m,m"))
15247 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15248 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15249 "TARGET_USE_FANCY_MATH_387
15250 && flag_unsafe_math_optimizations"
15251 "#"
15252 [(set_attr "type" "fistp")
15253 (set_attr "i387_cw" "ceil")
15254 (set_attr "mode" "DI")])
15255
15256 (define_split
15257 [(set (match_operand:DI 0 "register_operand" "")
15258 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15259 UNSPEC_FIST_CEIL))
15260 (use (match_operand:HI 2 "memory_operand" ""))
15261 (use (match_operand:HI 3 "memory_operand" ""))
15262 (clobber (match_operand:DI 4 "memory_operand" ""))
15263 (clobber (match_scratch 5 ""))]
15264 "reload_completed"
15265 [(parallel [(set (match_dup 4)
15266 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15267 (use (match_dup 2))
15268 (use (match_dup 3))
15269 (clobber (match_dup 5))])
15270 (set (match_dup 0) (match_dup 4))])
15271
15272 (define_split
15273 [(set (match_operand:DI 0 "memory_operand" "")
15274 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15275 UNSPEC_FIST_CEIL))
15276 (use (match_operand:HI 2 "memory_operand" ""))
15277 (use (match_operand:HI 3 "memory_operand" ""))
15278 (clobber (match_operand:DI 4 "memory_operand" ""))
15279 (clobber (match_scratch 5 ""))]
15280 "reload_completed"
15281 [(parallel [(set (match_dup 0)
15282 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15283 (use (match_dup 2))
15284 (use (match_dup 3))
15285 (clobber (match_dup 5))])])
15286
15287 (define_insn "fist<mode>2_ceil"
15288 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15289 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15290 UNSPEC_FIST_CEIL))
15291 (use (match_operand:HI 2 "memory_operand" "m"))
15292 (use (match_operand:HI 3 "memory_operand" "m"))]
15293 "TARGET_USE_FANCY_MATH_387
15294 && flag_unsafe_math_optimizations"
15295 "* return output_fix_trunc (insn, operands, false);"
15296 [(set_attr "type" "fistp")
15297 (set_attr "i387_cw" "ceil")
15298 (set_attr "mode" "<MODE>")])
15299
15300 (define_insn "fist<mode>2_ceil_with_temp"
15301 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15302 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15303 UNSPEC_FIST_CEIL))
15304 (use (match_operand:HI 2 "memory_operand" "m,m"))
15305 (use (match_operand:HI 3 "memory_operand" "m,m"))
15306 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15307 "TARGET_USE_FANCY_MATH_387
15308 && flag_unsafe_math_optimizations"
15309 "#"
15310 [(set_attr "type" "fistp")
15311 (set_attr "i387_cw" "ceil")
15312 (set_attr "mode" "<MODE>")])
15313
15314 (define_split
15315 [(set (match_operand:SWI24 0 "register_operand" "")
15316 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15317 UNSPEC_FIST_CEIL))
15318 (use (match_operand:HI 2 "memory_operand" ""))
15319 (use (match_operand:HI 3 "memory_operand" ""))
15320 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15321 "reload_completed"
15322 [(parallel [(set (match_dup 4)
15323 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15324 (use (match_dup 2))
15325 (use (match_dup 3))])
15326 (set (match_dup 0) (match_dup 4))])
15327
15328 (define_split
15329 [(set (match_operand:SWI24 0 "memory_operand" "")
15330 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15331 UNSPEC_FIST_CEIL))
15332 (use (match_operand:HI 2 "memory_operand" ""))
15333 (use (match_operand:HI 3 "memory_operand" ""))
15334 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15335 "reload_completed"
15336 [(parallel [(set (match_dup 0)
15337 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15338 (use (match_dup 2))
15339 (use (match_dup 3))])])
15340
15341 (define_expand "lceilxf<mode>2"
15342 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15343 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15344 UNSPEC_FIST_CEIL))
15345 (clobber (reg:CC FLAGS_REG))])]
15346 "TARGET_USE_FANCY_MATH_387
15347 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15348 && flag_unsafe_math_optimizations")
15349
15350 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15351 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15352 (match_operand:MODEF 1 "register_operand" "")]
15353 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15354 && !flag_trapping_math"
15355 {
15356 ix86_expand_lfloorceil (operand0, operand1, false);
15357 DONE;
15358 })
15359
15360 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15361 (define_insn_and_split "frndintxf2_trunc"
15362 [(set (match_operand:XF 0 "register_operand" "")
15363 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15364 UNSPEC_FRNDINT_TRUNC))
15365 (clobber (reg:CC FLAGS_REG))]
15366 "TARGET_USE_FANCY_MATH_387
15367 && flag_unsafe_math_optimizations
15368 && can_create_pseudo_p ()"
15369 "#"
15370 "&& 1"
15371 [(const_int 0)]
15372 {
15373 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15374
15375 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15376 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15377
15378 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15379 operands[2], operands[3]));
15380 DONE;
15381 }
15382 [(set_attr "type" "frndint")
15383 (set_attr "i387_cw" "trunc")
15384 (set_attr "mode" "XF")])
15385
15386 (define_insn "frndintxf2_trunc_i387"
15387 [(set (match_operand:XF 0 "register_operand" "=f")
15388 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15389 UNSPEC_FRNDINT_TRUNC))
15390 (use (match_operand:HI 2 "memory_operand" "m"))
15391 (use (match_operand:HI 3 "memory_operand" "m"))]
15392 "TARGET_USE_FANCY_MATH_387
15393 && flag_unsafe_math_optimizations"
15394 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15395 [(set_attr "type" "frndint")
15396 (set_attr "i387_cw" "trunc")
15397 (set_attr "mode" "XF")])
15398
15399 (define_expand "btruncxf2"
15400 [(use (match_operand:XF 0 "register_operand" ""))
15401 (use (match_operand:XF 1 "register_operand" ""))]
15402 "TARGET_USE_FANCY_MATH_387
15403 && flag_unsafe_math_optimizations"
15404 {
15405 if (optimize_insn_for_size_p ())
15406 FAIL;
15407 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15408 DONE;
15409 })
15410
15411 (define_expand "btrunc<mode>2"
15412 [(use (match_operand:MODEF 0 "register_operand" ""))
15413 (use (match_operand:MODEF 1 "register_operand" ""))]
15414 "(TARGET_USE_FANCY_MATH_387
15415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15416 || TARGET_MIX_SSE_I387)
15417 && flag_unsafe_math_optimizations)
15418 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15419 && !flag_trapping_math)"
15420 {
15421 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15422 && !flag_trapping_math)
15423 {
15424 if (TARGET_ROUND)
15425 emit_insn (gen_sse4_1_round<mode>2
15426 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15427 else if (optimize_insn_for_size_p ())
15428 FAIL;
15429 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15430 ix86_expand_trunc (operand0, operand1);
15431 else
15432 ix86_expand_truncdf_32 (operand0, operand1);
15433 }
15434 else
15435 {
15436 rtx op0, op1;
15437
15438 if (optimize_insn_for_size_p ())
15439 FAIL;
15440
15441 op0 = gen_reg_rtx (XFmode);
15442 op1 = gen_reg_rtx (XFmode);
15443 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15444 emit_insn (gen_frndintxf2_trunc (op0, op1));
15445
15446 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15447 }
15448 DONE;
15449 })
15450
15451 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15452 (define_insn_and_split "frndintxf2_mask_pm"
15453 [(set (match_operand:XF 0 "register_operand" "")
15454 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15455 UNSPEC_FRNDINT_MASK_PM))
15456 (clobber (reg:CC FLAGS_REG))]
15457 "TARGET_USE_FANCY_MATH_387
15458 && flag_unsafe_math_optimizations
15459 && can_create_pseudo_p ()"
15460 "#"
15461 "&& 1"
15462 [(const_int 0)]
15463 {
15464 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15465
15466 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15467 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15468
15469 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15470 operands[2], operands[3]));
15471 DONE;
15472 }
15473 [(set_attr "type" "frndint")
15474 (set_attr "i387_cw" "mask_pm")
15475 (set_attr "mode" "XF")])
15476
15477 (define_insn "frndintxf2_mask_pm_i387"
15478 [(set (match_operand:XF 0 "register_operand" "=f")
15479 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15480 UNSPEC_FRNDINT_MASK_PM))
15481 (use (match_operand:HI 2 "memory_operand" "m"))
15482 (use (match_operand:HI 3 "memory_operand" "m"))]
15483 "TARGET_USE_FANCY_MATH_387
15484 && flag_unsafe_math_optimizations"
15485 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15486 [(set_attr "type" "frndint")
15487 (set_attr "i387_cw" "mask_pm")
15488 (set_attr "mode" "XF")])
15489
15490 (define_expand "nearbyintxf2"
15491 [(use (match_operand:XF 0 "register_operand" ""))
15492 (use (match_operand:XF 1 "register_operand" ""))]
15493 "TARGET_USE_FANCY_MATH_387
15494 && flag_unsafe_math_optimizations"
15495 {
15496 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15497 DONE;
15498 })
15499
15500 (define_expand "nearbyint<mode>2"
15501 [(use (match_operand:MODEF 0 "register_operand" ""))
15502 (use (match_operand:MODEF 1 "register_operand" ""))]
15503 "TARGET_USE_FANCY_MATH_387
15504 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15505 || TARGET_MIX_SSE_I387)
15506 && flag_unsafe_math_optimizations"
15507 {
15508 rtx op0 = gen_reg_rtx (XFmode);
15509 rtx op1 = gen_reg_rtx (XFmode);
15510
15511 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15512 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15513
15514 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15515 DONE;
15516 })
15517
15518 (define_insn "fxam<mode>2_i387"
15519 [(set (match_operand:HI 0 "register_operand" "=a")
15520 (unspec:HI
15521 [(match_operand:X87MODEF 1 "register_operand" "f")]
15522 UNSPEC_FXAM))]
15523 "TARGET_USE_FANCY_MATH_387"
15524 "fxam\n\tfnstsw\t%0"
15525 [(set_attr "type" "multi")
15526 (set_attr "length" "4")
15527 (set_attr "unit" "i387")
15528 (set_attr "mode" "<MODE>")])
15529
15530 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15531 [(set (match_operand:HI 0 "register_operand" "")
15532 (unspec:HI
15533 [(match_operand:MODEF 1 "memory_operand" "")]
15534 UNSPEC_FXAM_MEM))]
15535 "TARGET_USE_FANCY_MATH_387
15536 && can_create_pseudo_p ()"
15537 "#"
15538 "&& 1"
15539 [(set (match_dup 2)(match_dup 1))
15540 (set (match_dup 0)
15541 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15542 {
15543 operands[2] = gen_reg_rtx (<MODE>mode);
15544
15545 MEM_VOLATILE_P (operands[1]) = 1;
15546 }
15547 [(set_attr "type" "multi")
15548 (set_attr "unit" "i387")
15549 (set_attr "mode" "<MODE>")])
15550
15551 (define_expand "isinfxf2"
15552 [(use (match_operand:SI 0 "register_operand" ""))
15553 (use (match_operand:XF 1 "register_operand" ""))]
15554 "TARGET_USE_FANCY_MATH_387
15555 && TARGET_C99_FUNCTIONS"
15556 {
15557 rtx mask = GEN_INT (0x45);
15558 rtx val = GEN_INT (0x05);
15559
15560 rtx cond;
15561
15562 rtx scratch = gen_reg_rtx (HImode);
15563 rtx res = gen_reg_rtx (QImode);
15564
15565 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15566
15567 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15568 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15569 cond = gen_rtx_fmt_ee (EQ, QImode,
15570 gen_rtx_REG (CCmode, FLAGS_REG),
15571 const0_rtx);
15572 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15573 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15574 DONE;
15575 })
15576
15577 (define_expand "isinf<mode>2"
15578 [(use (match_operand:SI 0 "register_operand" ""))
15579 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15580 "TARGET_USE_FANCY_MATH_387
15581 && TARGET_C99_FUNCTIONS
15582 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15583 {
15584 rtx mask = GEN_INT (0x45);
15585 rtx val = GEN_INT (0x05);
15586
15587 rtx cond;
15588
15589 rtx scratch = gen_reg_rtx (HImode);
15590 rtx res = gen_reg_rtx (QImode);
15591
15592 /* Remove excess precision by forcing value through memory. */
15593 if (memory_operand (operands[1], VOIDmode))
15594 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15595 else
15596 {
15597 enum ix86_stack_slot slot = (virtuals_instantiated
15598 ? SLOT_TEMP
15599 : SLOT_VIRTUAL);
15600 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15601
15602 emit_move_insn (temp, operands[1]);
15603 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15604 }
15605
15606 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15607 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15608 cond = gen_rtx_fmt_ee (EQ, QImode,
15609 gen_rtx_REG (CCmode, FLAGS_REG),
15610 const0_rtx);
15611 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15612 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15613 DONE;
15614 })
15615
15616 (define_expand "signbitxf2"
15617 [(use (match_operand:SI 0 "register_operand" ""))
15618 (use (match_operand:XF 1 "register_operand" ""))]
15619 "TARGET_USE_FANCY_MATH_387"
15620 {
15621 rtx scratch = gen_reg_rtx (HImode);
15622
15623 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15624 emit_insn (gen_andsi3 (operands[0],
15625 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15626 DONE;
15627 })
15628
15629 (define_insn "movmsk_df"
15630 [(set (match_operand:SI 0 "register_operand" "=r")
15631 (unspec:SI
15632 [(match_operand:DF 1 "register_operand" "x")]
15633 UNSPEC_MOVMSK))]
15634 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15635 "%vmovmskpd\t{%1, %0|%0, %1}"
15636 [(set_attr "type" "ssemov")
15637 (set_attr "prefix" "maybe_vex")
15638 (set_attr "mode" "DF")])
15639
15640 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15641 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15642 (define_expand "signbitdf2"
15643 [(use (match_operand:SI 0 "register_operand" ""))
15644 (use (match_operand:DF 1 "register_operand" ""))]
15645 "TARGET_USE_FANCY_MATH_387
15646 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15647 {
15648 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15649 {
15650 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15651 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15652 }
15653 else
15654 {
15655 rtx scratch = gen_reg_rtx (HImode);
15656
15657 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15658 emit_insn (gen_andsi3 (operands[0],
15659 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15660 }
15661 DONE;
15662 })
15663
15664 (define_expand "signbitsf2"
15665 [(use (match_operand:SI 0 "register_operand" ""))
15666 (use (match_operand:SF 1 "register_operand" ""))]
15667 "TARGET_USE_FANCY_MATH_387
15668 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15669 {
15670 rtx scratch = gen_reg_rtx (HImode);
15671
15672 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15673 emit_insn (gen_andsi3 (operands[0],
15674 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15675 DONE;
15676 })
15677 \f
15678 ;; Block operation instructions
15679
15680 (define_insn "cld"
15681 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15682 ""
15683 "cld"
15684 [(set_attr "length" "1")
15685 (set_attr "length_immediate" "0")
15686 (set_attr "modrm" "0")])
15687
15688 (define_expand "movmem<mode>"
15689 [(use (match_operand:BLK 0 "memory_operand" ""))
15690 (use (match_operand:BLK 1 "memory_operand" ""))
15691 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15692 (use (match_operand:SWI48 3 "const_int_operand" ""))
15693 (use (match_operand:SI 4 "const_int_operand" ""))
15694 (use (match_operand:SI 5 "const_int_operand" ""))]
15695 ""
15696 {
15697 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15698 operands[4], operands[5]))
15699 DONE;
15700 else
15701 FAIL;
15702 })
15703
15704 ;; Most CPUs don't like single string operations
15705 ;; Handle this case here to simplify previous expander.
15706
15707 (define_expand "strmov"
15708 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15709 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15710 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15711 (clobber (reg:CC FLAGS_REG))])
15712 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15713 (clobber (reg:CC FLAGS_REG))])]
15714 ""
15715 {
15716 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15717
15718 /* If .md ever supports :P for Pmode, these can be directly
15719 in the pattern above. */
15720 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15721 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15722
15723 /* Can't use this if the user has appropriated esi or edi. */
15724 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15725 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15726 {
15727 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15728 operands[2], operands[3],
15729 operands[5], operands[6]));
15730 DONE;
15731 }
15732
15733 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15734 })
15735
15736 (define_expand "strmov_singleop"
15737 [(parallel [(set (match_operand 1 "memory_operand" "")
15738 (match_operand 3 "memory_operand" ""))
15739 (set (match_operand 0 "register_operand" "")
15740 (match_operand 4 "" ""))
15741 (set (match_operand 2 "register_operand" "")
15742 (match_operand 5 "" ""))])]
15743 ""
15744 "ix86_current_function_needs_cld = 1;")
15745
15746 (define_insn "*strmovdi_rex_1"
15747 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15748 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15749 (set (match_operand:DI 0 "register_operand" "=D")
15750 (plus:DI (match_dup 2)
15751 (const_int 8)))
15752 (set (match_operand:DI 1 "register_operand" "=S")
15753 (plus:DI (match_dup 3)
15754 (const_int 8)))]
15755 "TARGET_64BIT
15756 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15757 "movsq"
15758 [(set_attr "type" "str")
15759 (set_attr "memory" "both")
15760 (set_attr "mode" "DI")])
15761
15762 (define_insn "*strmovsi_1"
15763 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15764 (mem:SI (match_operand:P 3 "register_operand" "1")))
15765 (set (match_operand:P 0 "register_operand" "=D")
15766 (plus:P (match_dup 2)
15767 (const_int 4)))
15768 (set (match_operand:P 1 "register_operand" "=S")
15769 (plus:P (match_dup 3)
15770 (const_int 4)))]
15771 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15772 "movs{l|d}"
15773 [(set_attr "type" "str")
15774 (set_attr "memory" "both")
15775 (set_attr "mode" "SI")])
15776
15777 (define_insn "*strmovhi_1"
15778 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15779 (mem:HI (match_operand:P 3 "register_operand" "1")))
15780 (set (match_operand:P 0 "register_operand" "=D")
15781 (plus:P (match_dup 2)
15782 (const_int 2)))
15783 (set (match_operand:P 1 "register_operand" "=S")
15784 (plus:P (match_dup 3)
15785 (const_int 2)))]
15786 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15787 "movsw"
15788 [(set_attr "type" "str")
15789 (set_attr "memory" "both")
15790 (set_attr "mode" "HI")])
15791
15792 (define_insn "*strmovqi_1"
15793 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15794 (mem:QI (match_operand:P 3 "register_operand" "1")))
15795 (set (match_operand:P 0 "register_operand" "=D")
15796 (plus:P (match_dup 2)
15797 (const_int 1)))
15798 (set (match_operand:P 1 "register_operand" "=S")
15799 (plus:P (match_dup 3)
15800 (const_int 1)))]
15801 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15802 "movsb"
15803 [(set_attr "type" "str")
15804 (set_attr "memory" "both")
15805 (set (attr "prefix_rex")
15806 (if_then_else
15807 (match_test "<P:MODE>mode == DImode")
15808 (const_string "0")
15809 (const_string "*")))
15810 (set_attr "mode" "QI")])
15811
15812 (define_expand "rep_mov"
15813 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15814 (set (match_operand 0 "register_operand" "")
15815 (match_operand 5 "" ""))
15816 (set (match_operand 2 "register_operand" "")
15817 (match_operand 6 "" ""))
15818 (set (match_operand 1 "memory_operand" "")
15819 (match_operand 3 "memory_operand" ""))
15820 (use (match_dup 4))])]
15821 ""
15822 "ix86_current_function_needs_cld = 1;")
15823
15824 (define_insn "*rep_movdi_rex64"
15825 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15826 (set (match_operand:DI 0 "register_operand" "=D")
15827 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15828 (const_int 3))
15829 (match_operand:DI 3 "register_operand" "0")))
15830 (set (match_operand:DI 1 "register_operand" "=S")
15831 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15832 (match_operand:DI 4 "register_operand" "1")))
15833 (set (mem:BLK (match_dup 3))
15834 (mem:BLK (match_dup 4)))
15835 (use (match_dup 5))]
15836 "TARGET_64BIT
15837 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15838 "rep{%;} movsq"
15839 [(set_attr "type" "str")
15840 (set_attr "prefix_rep" "1")
15841 (set_attr "memory" "both")
15842 (set_attr "mode" "DI")])
15843
15844 (define_insn "*rep_movsi"
15845 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15846 (set (match_operand:P 0 "register_operand" "=D")
15847 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15848 (const_int 2))
15849 (match_operand:P 3 "register_operand" "0")))
15850 (set (match_operand:P 1 "register_operand" "=S")
15851 (plus:P (ashift:P (match_dup 5) (const_int 2))
15852 (match_operand:P 4 "register_operand" "1")))
15853 (set (mem:BLK (match_dup 3))
15854 (mem:BLK (match_dup 4)))
15855 (use (match_dup 5))]
15856 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15857 "rep{%;} movs{l|d}"
15858 [(set_attr "type" "str")
15859 (set_attr "prefix_rep" "1")
15860 (set_attr "memory" "both")
15861 (set_attr "mode" "SI")])
15862
15863 (define_insn "*rep_movqi"
15864 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15865 (set (match_operand:P 0 "register_operand" "=D")
15866 (plus:P (match_operand:P 3 "register_operand" "0")
15867 (match_operand:P 5 "register_operand" "2")))
15868 (set (match_operand:P 1 "register_operand" "=S")
15869 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15870 (set (mem:BLK (match_dup 3))
15871 (mem:BLK (match_dup 4)))
15872 (use (match_dup 5))]
15873 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15874 "rep{%;} movsb"
15875 [(set_attr "type" "str")
15876 (set_attr "prefix_rep" "1")
15877 (set_attr "memory" "both")
15878 (set_attr "mode" "QI")])
15879
15880 (define_expand "setmem<mode>"
15881 [(use (match_operand:BLK 0 "memory_operand" ""))
15882 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15883 (use (match_operand:QI 2 "nonmemory_operand" ""))
15884 (use (match_operand 3 "const_int_operand" ""))
15885 (use (match_operand:SI 4 "const_int_operand" ""))
15886 (use (match_operand:SI 5 "const_int_operand" ""))]
15887 ""
15888 {
15889 if (ix86_expand_setmem (operands[0], operands[1],
15890 operands[2], operands[3],
15891 operands[4], operands[5]))
15892 DONE;
15893 else
15894 FAIL;
15895 })
15896
15897 ;; Most CPUs don't like single string operations
15898 ;; Handle this case here to simplify previous expander.
15899
15900 (define_expand "strset"
15901 [(set (match_operand 1 "memory_operand" "")
15902 (match_operand 2 "register_operand" ""))
15903 (parallel [(set (match_operand 0 "register_operand" "")
15904 (match_dup 3))
15905 (clobber (reg:CC FLAGS_REG))])]
15906 ""
15907 {
15908 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15909 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15910
15911 /* If .md ever supports :P for Pmode, this can be directly
15912 in the pattern above. */
15913 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15914 GEN_INT (GET_MODE_SIZE (GET_MODE
15915 (operands[2]))));
15916 /* Can't use this if the user has appropriated eax or edi. */
15917 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15918 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15919 {
15920 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15921 operands[3]));
15922 DONE;
15923 }
15924 })
15925
15926 (define_expand "strset_singleop"
15927 [(parallel [(set (match_operand 1 "memory_operand" "")
15928 (match_operand 2 "register_operand" ""))
15929 (set (match_operand 0 "register_operand" "")
15930 (match_operand 3 "" ""))])]
15931 ""
15932 "ix86_current_function_needs_cld = 1;")
15933
15934 (define_insn "*strsetdi_rex_1"
15935 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15936 (match_operand:DI 2 "register_operand" "a"))
15937 (set (match_operand:DI 0 "register_operand" "=D")
15938 (plus:DI (match_dup 1)
15939 (const_int 8)))]
15940 "TARGET_64BIT
15941 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15942 "stosq"
15943 [(set_attr "type" "str")
15944 (set_attr "memory" "store")
15945 (set_attr "mode" "DI")])
15946
15947 (define_insn "*strsetsi_1"
15948 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15949 (match_operand:SI 2 "register_operand" "a"))
15950 (set (match_operand:P 0 "register_operand" "=D")
15951 (plus:P (match_dup 1)
15952 (const_int 4)))]
15953 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15954 "stos{l|d}"
15955 [(set_attr "type" "str")
15956 (set_attr "memory" "store")
15957 (set_attr "mode" "SI")])
15958
15959 (define_insn "*strsethi_1"
15960 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15961 (match_operand:HI 2 "register_operand" "a"))
15962 (set (match_operand:P 0 "register_operand" "=D")
15963 (plus:P (match_dup 1)
15964 (const_int 2)))]
15965 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15966 "stosw"
15967 [(set_attr "type" "str")
15968 (set_attr "memory" "store")
15969 (set_attr "mode" "HI")])
15970
15971 (define_insn "*strsetqi_1"
15972 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15973 (match_operand:QI 2 "register_operand" "a"))
15974 (set (match_operand:P 0 "register_operand" "=D")
15975 (plus:P (match_dup 1)
15976 (const_int 1)))]
15977 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15978 "stosb"
15979 [(set_attr "type" "str")
15980 (set_attr "memory" "store")
15981 (set (attr "prefix_rex")
15982 (if_then_else
15983 (match_test "<P:MODE>mode == DImode")
15984 (const_string "0")
15985 (const_string "*")))
15986 (set_attr "mode" "QI")])
15987
15988 (define_expand "rep_stos"
15989 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15990 (set (match_operand 0 "register_operand" "")
15991 (match_operand 4 "" ""))
15992 (set (match_operand 2 "memory_operand" "") (const_int 0))
15993 (use (match_operand 3 "register_operand" ""))
15994 (use (match_dup 1))])]
15995 ""
15996 "ix86_current_function_needs_cld = 1;")
15997
15998 (define_insn "*rep_stosdi_rex64"
15999 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16000 (set (match_operand:DI 0 "register_operand" "=D")
16001 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16002 (const_int 3))
16003 (match_operand:DI 3 "register_operand" "0")))
16004 (set (mem:BLK (match_dup 3))
16005 (const_int 0))
16006 (use (match_operand:DI 2 "register_operand" "a"))
16007 (use (match_dup 4))]
16008 "TARGET_64BIT
16009 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16010 "rep{%;} stosq"
16011 [(set_attr "type" "str")
16012 (set_attr "prefix_rep" "1")
16013 (set_attr "memory" "store")
16014 (set_attr "mode" "DI")])
16015
16016 (define_insn "*rep_stossi"
16017 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16018 (set (match_operand:P 0 "register_operand" "=D")
16019 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16020 (const_int 2))
16021 (match_operand:P 3 "register_operand" "0")))
16022 (set (mem:BLK (match_dup 3))
16023 (const_int 0))
16024 (use (match_operand:SI 2 "register_operand" "a"))
16025 (use (match_dup 4))]
16026 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16027 "rep{%;} stos{l|d}"
16028 [(set_attr "type" "str")
16029 (set_attr "prefix_rep" "1")
16030 (set_attr "memory" "store")
16031 (set_attr "mode" "SI")])
16032
16033 (define_insn "*rep_stosqi"
16034 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16035 (set (match_operand:P 0 "register_operand" "=D")
16036 (plus:P (match_operand:P 3 "register_operand" "0")
16037 (match_operand:P 4 "register_operand" "1")))
16038 (set (mem:BLK (match_dup 3))
16039 (const_int 0))
16040 (use (match_operand:QI 2 "register_operand" "a"))
16041 (use (match_dup 4))]
16042 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16043 "rep{%;} stosb"
16044 [(set_attr "type" "str")
16045 (set_attr "prefix_rep" "1")
16046 (set_attr "memory" "store")
16047 (set (attr "prefix_rex")
16048 (if_then_else
16049 (match_test "<P:MODE>mode == DImode")
16050 (const_string "0")
16051 (const_string "*")))
16052 (set_attr "mode" "QI")])
16053
16054 (define_expand "cmpstrnsi"
16055 [(set (match_operand:SI 0 "register_operand" "")
16056 (compare:SI (match_operand:BLK 1 "general_operand" "")
16057 (match_operand:BLK 2 "general_operand" "")))
16058 (use (match_operand 3 "general_operand" ""))
16059 (use (match_operand 4 "immediate_operand" ""))]
16060 ""
16061 {
16062 rtx addr1, addr2, out, outlow, count, countreg, align;
16063
16064 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16065 FAIL;
16066
16067 /* Can't use this if the user has appropriated ecx, esi or edi. */
16068 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16069 FAIL;
16070
16071 out = operands[0];
16072 if (!REG_P (out))
16073 out = gen_reg_rtx (SImode);
16074
16075 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16076 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16077 if (addr1 != XEXP (operands[1], 0))
16078 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16079 if (addr2 != XEXP (operands[2], 0))
16080 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16081
16082 count = operands[3];
16083 countreg = ix86_zero_extend_to_Pmode (count);
16084
16085 /* %%% Iff we are testing strict equality, we can use known alignment
16086 to good advantage. This may be possible with combine, particularly
16087 once cc0 is dead. */
16088 align = operands[4];
16089
16090 if (CONST_INT_P (count))
16091 {
16092 if (INTVAL (count) == 0)
16093 {
16094 emit_move_insn (operands[0], const0_rtx);
16095 DONE;
16096 }
16097 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16098 operands[1], operands[2]));
16099 }
16100 else
16101 {
16102 rtx (*gen_cmp) (rtx, rtx);
16103
16104 gen_cmp = (TARGET_64BIT
16105 ? gen_cmpdi_1 : gen_cmpsi_1);
16106
16107 emit_insn (gen_cmp (countreg, countreg));
16108 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16109 operands[1], operands[2]));
16110 }
16111
16112 outlow = gen_lowpart (QImode, out);
16113 emit_insn (gen_cmpintqi (outlow));
16114 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16115
16116 if (operands[0] != out)
16117 emit_move_insn (operands[0], out);
16118
16119 DONE;
16120 })
16121
16122 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16123
16124 (define_expand "cmpintqi"
16125 [(set (match_dup 1)
16126 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16127 (set (match_dup 2)
16128 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16129 (parallel [(set (match_operand:QI 0 "register_operand" "")
16130 (minus:QI (match_dup 1)
16131 (match_dup 2)))
16132 (clobber (reg:CC FLAGS_REG))])]
16133 ""
16134 {
16135 operands[1] = gen_reg_rtx (QImode);
16136 operands[2] = gen_reg_rtx (QImode);
16137 })
16138
16139 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16140 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16141
16142 (define_expand "cmpstrnqi_nz_1"
16143 [(parallel [(set (reg:CC FLAGS_REG)
16144 (compare:CC (match_operand 4 "memory_operand" "")
16145 (match_operand 5 "memory_operand" "")))
16146 (use (match_operand 2 "register_operand" ""))
16147 (use (match_operand:SI 3 "immediate_operand" ""))
16148 (clobber (match_operand 0 "register_operand" ""))
16149 (clobber (match_operand 1 "register_operand" ""))
16150 (clobber (match_dup 2))])]
16151 ""
16152 "ix86_current_function_needs_cld = 1;")
16153
16154 (define_insn "*cmpstrnqi_nz_1"
16155 [(set (reg:CC FLAGS_REG)
16156 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16157 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16158 (use (match_operand:P 6 "register_operand" "2"))
16159 (use (match_operand:SI 3 "immediate_operand" "i"))
16160 (clobber (match_operand:P 0 "register_operand" "=S"))
16161 (clobber (match_operand:P 1 "register_operand" "=D"))
16162 (clobber (match_operand:P 2 "register_operand" "=c"))]
16163 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16164 "repz{%;} cmpsb"
16165 [(set_attr "type" "str")
16166 (set_attr "mode" "QI")
16167 (set (attr "prefix_rex")
16168 (if_then_else
16169 (match_test "<P:MODE>mode == DImode")
16170 (const_string "0")
16171 (const_string "*")))
16172 (set_attr "prefix_rep" "1")])
16173
16174 ;; The same, but the count is not known to not be zero.
16175
16176 (define_expand "cmpstrnqi_1"
16177 [(parallel [(set (reg:CC FLAGS_REG)
16178 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16179 (const_int 0))
16180 (compare:CC (match_operand 4 "memory_operand" "")
16181 (match_operand 5 "memory_operand" ""))
16182 (const_int 0)))
16183 (use (match_operand:SI 3 "immediate_operand" ""))
16184 (use (reg:CC FLAGS_REG))
16185 (clobber (match_operand 0 "register_operand" ""))
16186 (clobber (match_operand 1 "register_operand" ""))
16187 (clobber (match_dup 2))])]
16188 ""
16189 "ix86_current_function_needs_cld = 1;")
16190
16191 (define_insn "*cmpstrnqi_1"
16192 [(set (reg:CC FLAGS_REG)
16193 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16194 (const_int 0))
16195 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16196 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16197 (const_int 0)))
16198 (use (match_operand:SI 3 "immediate_operand" "i"))
16199 (use (reg:CC FLAGS_REG))
16200 (clobber (match_operand:P 0 "register_operand" "=S"))
16201 (clobber (match_operand:P 1 "register_operand" "=D"))
16202 (clobber (match_operand:P 2 "register_operand" "=c"))]
16203 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16204 "repz{%;} cmpsb"
16205 [(set_attr "type" "str")
16206 (set_attr "mode" "QI")
16207 (set (attr "prefix_rex")
16208 (if_then_else
16209 (match_test "<P:MODE>mode == DImode")
16210 (const_string "0")
16211 (const_string "*")))
16212 (set_attr "prefix_rep" "1")])
16213
16214 (define_expand "strlen<mode>"
16215 [(set (match_operand:P 0 "register_operand" "")
16216 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16217 (match_operand:QI 2 "immediate_operand" "")
16218 (match_operand 3 "immediate_operand" "")]
16219 UNSPEC_SCAS))]
16220 ""
16221 {
16222 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16223 DONE;
16224 else
16225 FAIL;
16226 })
16227
16228 (define_expand "strlenqi_1"
16229 [(parallel [(set (match_operand 0 "register_operand" "")
16230 (match_operand 2 "" ""))
16231 (clobber (match_operand 1 "register_operand" ""))
16232 (clobber (reg:CC FLAGS_REG))])]
16233 ""
16234 "ix86_current_function_needs_cld = 1;")
16235
16236 (define_insn "*strlenqi_1"
16237 [(set (match_operand:P 0 "register_operand" "=&c")
16238 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16239 (match_operand:QI 2 "register_operand" "a")
16240 (match_operand:P 3 "immediate_operand" "i")
16241 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16242 (clobber (match_operand:P 1 "register_operand" "=D"))
16243 (clobber (reg:CC FLAGS_REG))]
16244 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16245 "repnz{%;} scasb"
16246 [(set_attr "type" "str")
16247 (set_attr "mode" "QI")
16248 (set (attr "prefix_rex")
16249 (if_then_else
16250 (match_test "<P:MODE>mode == DImode")
16251 (const_string "0")
16252 (const_string "*")))
16253 (set_attr "prefix_rep" "1")])
16254
16255 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16256 ;; handled in combine, but it is not currently up to the task.
16257 ;; When used for their truth value, the cmpstrn* expanders generate
16258 ;; code like this:
16259 ;;
16260 ;; repz cmpsb
16261 ;; seta %al
16262 ;; setb %dl
16263 ;; cmpb %al, %dl
16264 ;; jcc label
16265 ;;
16266 ;; The intermediate three instructions are unnecessary.
16267
16268 ;; This one handles cmpstrn*_nz_1...
16269 (define_peephole2
16270 [(parallel[
16271 (set (reg:CC FLAGS_REG)
16272 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16273 (mem:BLK (match_operand 5 "register_operand" ""))))
16274 (use (match_operand 6 "register_operand" ""))
16275 (use (match_operand:SI 3 "immediate_operand" ""))
16276 (clobber (match_operand 0 "register_operand" ""))
16277 (clobber (match_operand 1 "register_operand" ""))
16278 (clobber (match_operand 2 "register_operand" ""))])
16279 (set (match_operand:QI 7 "register_operand" "")
16280 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16281 (set (match_operand:QI 8 "register_operand" "")
16282 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16283 (set (reg FLAGS_REG)
16284 (compare (match_dup 7) (match_dup 8)))
16285 ]
16286 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16287 [(parallel[
16288 (set (reg:CC FLAGS_REG)
16289 (compare:CC (mem:BLK (match_dup 4))
16290 (mem:BLK (match_dup 5))))
16291 (use (match_dup 6))
16292 (use (match_dup 3))
16293 (clobber (match_dup 0))
16294 (clobber (match_dup 1))
16295 (clobber (match_dup 2))])])
16296
16297 ;; ...and this one handles cmpstrn*_1.
16298 (define_peephole2
16299 [(parallel[
16300 (set (reg:CC FLAGS_REG)
16301 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16302 (const_int 0))
16303 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16304 (mem:BLK (match_operand 5 "register_operand" "")))
16305 (const_int 0)))
16306 (use (match_operand:SI 3 "immediate_operand" ""))
16307 (use (reg:CC FLAGS_REG))
16308 (clobber (match_operand 0 "register_operand" ""))
16309 (clobber (match_operand 1 "register_operand" ""))
16310 (clobber (match_operand 2 "register_operand" ""))])
16311 (set (match_operand:QI 7 "register_operand" "")
16312 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16313 (set (match_operand:QI 8 "register_operand" "")
16314 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16315 (set (reg FLAGS_REG)
16316 (compare (match_dup 7) (match_dup 8)))
16317 ]
16318 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16319 [(parallel[
16320 (set (reg:CC FLAGS_REG)
16321 (if_then_else:CC (ne (match_dup 6)
16322 (const_int 0))
16323 (compare:CC (mem:BLK (match_dup 4))
16324 (mem:BLK (match_dup 5)))
16325 (const_int 0)))
16326 (use (match_dup 3))
16327 (use (reg:CC FLAGS_REG))
16328 (clobber (match_dup 0))
16329 (clobber (match_dup 1))
16330 (clobber (match_dup 2))])])
16331 \f
16332 ;; Conditional move instructions.
16333
16334 (define_expand "mov<mode>cc"
16335 [(set (match_operand:SWIM 0 "register_operand" "")
16336 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16337 (match_operand:SWIM 2 "<general_operand>" "")
16338 (match_operand:SWIM 3 "<general_operand>" "")))]
16339 ""
16340 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16341
16342 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16343 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16344 ;; So just document what we're doing explicitly.
16345
16346 (define_expand "x86_mov<mode>cc_0_m1"
16347 [(parallel
16348 [(set (match_operand:SWI48 0 "register_operand" "")
16349 (if_then_else:SWI48
16350 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16351 [(match_operand 1 "flags_reg_operand" "")
16352 (const_int 0)])
16353 (const_int -1)
16354 (const_int 0)))
16355 (clobber (reg:CC FLAGS_REG))])])
16356
16357 (define_insn "*x86_mov<mode>cc_0_m1"
16358 [(set (match_operand:SWI48 0 "register_operand" "=r")
16359 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16360 [(reg FLAGS_REG) (const_int 0)])
16361 (const_int -1)
16362 (const_int 0)))
16363 (clobber (reg:CC FLAGS_REG))]
16364 ""
16365 "sbb{<imodesuffix>}\t%0, %0"
16366 ; Since we don't have the proper number of operands for an alu insn,
16367 ; fill in all the blanks.
16368 [(set_attr "type" "alu")
16369 (set_attr "use_carry" "1")
16370 (set_attr "pent_pair" "pu")
16371 (set_attr "memory" "none")
16372 (set_attr "imm_disp" "false")
16373 (set_attr "mode" "<MODE>")
16374 (set_attr "length_immediate" "0")])
16375
16376 (define_insn "*x86_mov<mode>cc_0_m1_se"
16377 [(set (match_operand:SWI48 0 "register_operand" "=r")
16378 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16379 [(reg FLAGS_REG) (const_int 0)])
16380 (const_int 1)
16381 (const_int 0)))
16382 (clobber (reg:CC FLAGS_REG))]
16383 ""
16384 "sbb{<imodesuffix>}\t%0, %0"
16385 [(set_attr "type" "alu")
16386 (set_attr "use_carry" "1")
16387 (set_attr "pent_pair" "pu")
16388 (set_attr "memory" "none")
16389 (set_attr "imm_disp" "false")
16390 (set_attr "mode" "<MODE>")
16391 (set_attr "length_immediate" "0")])
16392
16393 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16394 [(set (match_operand:SWI48 0 "register_operand" "=r")
16395 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16396 [(reg FLAGS_REG) (const_int 0)])))]
16397 ""
16398 "sbb{<imodesuffix>}\t%0, %0"
16399 [(set_attr "type" "alu")
16400 (set_attr "use_carry" "1")
16401 (set_attr "pent_pair" "pu")
16402 (set_attr "memory" "none")
16403 (set_attr "imm_disp" "false")
16404 (set_attr "mode" "<MODE>")
16405 (set_attr "length_immediate" "0")])
16406
16407 (define_insn "*mov<mode>cc_noc"
16408 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16409 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16410 [(reg FLAGS_REG) (const_int 0)])
16411 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16412 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16413 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16414 "@
16415 cmov%O2%C1\t{%2, %0|%0, %2}
16416 cmov%O2%c1\t{%3, %0|%0, %3}"
16417 [(set_attr "type" "icmov")
16418 (set_attr "mode" "<MODE>")])
16419
16420 (define_insn_and_split "*movqicc_noc"
16421 [(set (match_operand:QI 0 "register_operand" "=r,r")
16422 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16423 [(match_operand 4 "flags_reg_operand" "")
16424 (const_int 0)])
16425 (match_operand:QI 2 "register_operand" "r,0")
16426 (match_operand:QI 3 "register_operand" "0,r")))]
16427 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16428 "#"
16429 "&& reload_completed"
16430 [(set (match_dup 0)
16431 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16432 (match_dup 2)
16433 (match_dup 3)))]
16434 "operands[0] = gen_lowpart (SImode, operands[0]);
16435 operands[2] = gen_lowpart (SImode, operands[2]);
16436 operands[3] = gen_lowpart (SImode, operands[3]);"
16437 [(set_attr "type" "icmov")
16438 (set_attr "mode" "SI")])
16439
16440 (define_expand "mov<mode>cc"
16441 [(set (match_operand:X87MODEF 0 "register_operand" "")
16442 (if_then_else:X87MODEF
16443 (match_operand 1 "ix86_fp_comparison_operator" "")
16444 (match_operand:X87MODEF 2 "register_operand" "")
16445 (match_operand:X87MODEF 3 "register_operand" "")))]
16446 "(TARGET_80387 && TARGET_CMOVE)
16447 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16448 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16449
16450 (define_insn "*movxfcc_1"
16451 [(set (match_operand:XF 0 "register_operand" "=f,f")
16452 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16453 [(reg FLAGS_REG) (const_int 0)])
16454 (match_operand:XF 2 "register_operand" "f,0")
16455 (match_operand:XF 3 "register_operand" "0,f")))]
16456 "TARGET_80387 && TARGET_CMOVE"
16457 "@
16458 fcmov%F1\t{%2, %0|%0, %2}
16459 fcmov%f1\t{%3, %0|%0, %3}"
16460 [(set_attr "type" "fcmov")
16461 (set_attr "mode" "XF")])
16462
16463 (define_insn "*movdfcc_1_rex64"
16464 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16465 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16466 [(reg FLAGS_REG) (const_int 0)])
16467 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16468 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16469 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16470 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16471 "@
16472 fcmov%F1\t{%2, %0|%0, %2}
16473 fcmov%f1\t{%3, %0|%0, %3}
16474 cmov%O2%C1\t{%2, %0|%0, %2}
16475 cmov%O2%c1\t{%3, %0|%0, %3}"
16476 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16477 (set_attr "mode" "DF,DF,DI,DI")])
16478
16479 (define_insn "*movdfcc_1"
16480 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16481 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16482 [(reg FLAGS_REG) (const_int 0)])
16483 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16484 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16485 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16486 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16487 "@
16488 fcmov%F1\t{%2, %0|%0, %2}
16489 fcmov%f1\t{%3, %0|%0, %3}
16490 #
16491 #"
16492 [(set_attr "type" "fcmov,fcmov,multi,multi")
16493 (set_attr "mode" "DF,DF,DI,DI")])
16494
16495 (define_split
16496 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16497 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16498 [(match_operand 4 "flags_reg_operand" "")
16499 (const_int 0)])
16500 (match_operand:DF 2 "nonimmediate_operand" "")
16501 (match_operand:DF 3 "nonimmediate_operand" "")))]
16502 "!TARGET_64BIT && reload_completed"
16503 [(set (match_dup 2)
16504 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16505 (match_dup 5)
16506 (match_dup 6)))
16507 (set (match_dup 3)
16508 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16509 (match_dup 7)
16510 (match_dup 8)))]
16511 {
16512 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16513 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16514 })
16515
16516 (define_insn "*movsfcc_1_387"
16517 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16518 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16519 [(reg FLAGS_REG) (const_int 0)])
16520 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16521 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16522 "TARGET_80387 && TARGET_CMOVE
16523 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16524 "@
16525 fcmov%F1\t{%2, %0|%0, %2}
16526 fcmov%f1\t{%3, %0|%0, %3}
16527 cmov%O2%C1\t{%2, %0|%0, %2}
16528 cmov%O2%c1\t{%3, %0|%0, %3}"
16529 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16530 (set_attr "mode" "SF,SF,SI,SI")])
16531
16532 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16533 ;; the scalar versions to have only XMM registers as operands.
16534
16535 ;; XOP conditional move
16536 (define_insn "*xop_pcmov_<mode>"
16537 [(set (match_operand:MODEF 0 "register_operand" "=x")
16538 (if_then_else:MODEF
16539 (match_operand:MODEF 1 "register_operand" "x")
16540 (match_operand:MODEF 2 "register_operand" "x")
16541 (match_operand:MODEF 3 "register_operand" "x")))]
16542 "TARGET_XOP"
16543 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16544 [(set_attr "type" "sse4arg")])
16545
16546 ;; These versions of the min/max patterns are intentionally ignorant of
16547 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16548 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16549 ;; are undefined in this condition, we're certain this is correct.
16550
16551 (define_insn "<code><mode>3"
16552 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16553 (smaxmin:MODEF
16554 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16555 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16556 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16557 "@
16558 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16559 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16560 [(set_attr "isa" "noavx,avx")
16561 (set_attr "prefix" "orig,vex")
16562 (set_attr "type" "sseadd")
16563 (set_attr "mode" "<MODE>")])
16564
16565 ;; These versions of the min/max patterns implement exactly the operations
16566 ;; min = (op1 < op2 ? op1 : op2)
16567 ;; max = (!(op1 < op2) ? op1 : op2)
16568 ;; Their operands are not commutative, and thus they may be used in the
16569 ;; presence of -0.0 and NaN.
16570
16571 (define_insn "*ieee_smin<mode>3"
16572 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16573 (unspec:MODEF
16574 [(match_operand:MODEF 1 "register_operand" "0,x")
16575 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16576 UNSPEC_IEEE_MIN))]
16577 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16578 "@
16579 min<ssemodesuffix>\t{%2, %0|%0, %2}
16580 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16581 [(set_attr "isa" "noavx,avx")
16582 (set_attr "prefix" "orig,vex")
16583 (set_attr "type" "sseadd")
16584 (set_attr "mode" "<MODE>")])
16585
16586 (define_insn "*ieee_smax<mode>3"
16587 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16588 (unspec:MODEF
16589 [(match_operand:MODEF 1 "register_operand" "0,x")
16590 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16591 UNSPEC_IEEE_MAX))]
16592 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16593 "@
16594 max<ssemodesuffix>\t{%2, %0|%0, %2}
16595 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16596 [(set_attr "isa" "noavx,avx")
16597 (set_attr "prefix" "orig,vex")
16598 (set_attr "type" "sseadd")
16599 (set_attr "mode" "<MODE>")])
16600
16601 ;; Make two stack loads independent:
16602 ;; fld aa fld aa
16603 ;; fld %st(0) -> fld bb
16604 ;; fmul bb fmul %st(1), %st
16605 ;;
16606 ;; Actually we only match the last two instructions for simplicity.
16607 (define_peephole2
16608 [(set (match_operand 0 "fp_register_operand" "")
16609 (match_operand 1 "fp_register_operand" ""))
16610 (set (match_dup 0)
16611 (match_operator 2 "binary_fp_operator"
16612 [(match_dup 0)
16613 (match_operand 3 "memory_operand" "")]))]
16614 "REGNO (operands[0]) != REGNO (operands[1])"
16615 [(set (match_dup 0) (match_dup 3))
16616 (set (match_dup 0) (match_dup 4))]
16617
16618 ;; The % modifier is not operational anymore in peephole2's, so we have to
16619 ;; swap the operands manually in the case of addition and multiplication.
16620 "if (COMMUTATIVE_ARITH_P (operands[2]))
16621 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16622 GET_MODE (operands[2]),
16623 operands[0], operands[1]);
16624 else
16625 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16626 GET_MODE (operands[2]),
16627 operands[1], operands[0]);")
16628
16629 ;; Conditional addition patterns
16630 (define_expand "add<mode>cc"
16631 [(match_operand:SWI 0 "register_operand" "")
16632 (match_operand 1 "ordered_comparison_operator" "")
16633 (match_operand:SWI 2 "register_operand" "")
16634 (match_operand:SWI 3 "const_int_operand" "")]
16635 ""
16636 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16637 \f
16638 ;; Misc patterns (?)
16639
16640 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16641 ;; Otherwise there will be nothing to keep
16642 ;;
16643 ;; [(set (reg ebp) (reg esp))]
16644 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16645 ;; (clobber (eflags)]
16646 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16647 ;;
16648 ;; in proper program order.
16649
16650 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16651 [(set (match_operand:P 0 "register_operand" "=r,r")
16652 (plus:P (match_operand:P 1 "register_operand" "0,r")
16653 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16654 (clobber (reg:CC FLAGS_REG))
16655 (clobber (mem:BLK (scratch)))]
16656 ""
16657 {
16658 switch (get_attr_type (insn))
16659 {
16660 case TYPE_IMOV:
16661 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16662
16663 case TYPE_ALU:
16664 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16665 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16666 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16667
16668 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16669
16670 default:
16671 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16672 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16673 }
16674 }
16675 [(set (attr "type")
16676 (cond [(and (eq_attr "alternative" "0")
16677 (not (match_test "TARGET_OPT_AGU")))
16678 (const_string "alu")
16679 (match_operand:<MODE> 2 "const0_operand" "")
16680 (const_string "imov")
16681 ]
16682 (const_string "lea")))
16683 (set (attr "length_immediate")
16684 (cond [(eq_attr "type" "imov")
16685 (const_string "0")
16686 (and (eq_attr "type" "alu")
16687 (match_operand 2 "const128_operand" ""))
16688 (const_string "1")
16689 ]
16690 (const_string "*")))
16691 (set_attr "mode" "<MODE>")])
16692
16693 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16694 [(set (match_operand:P 0 "register_operand" "=r")
16695 (minus:P (match_operand:P 1 "register_operand" "0")
16696 (match_operand:P 2 "register_operand" "r")))
16697 (clobber (reg:CC FLAGS_REG))
16698 (clobber (mem:BLK (scratch)))]
16699 ""
16700 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16701 [(set_attr "type" "alu")
16702 (set_attr "mode" "<MODE>")])
16703
16704 (define_insn "allocate_stack_worker_probe_<mode>"
16705 [(set (match_operand:P 0 "register_operand" "=a")
16706 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16707 UNSPECV_STACK_PROBE))
16708 (clobber (reg:CC FLAGS_REG))]
16709 "ix86_target_stack_probe ()"
16710 "call\t___chkstk_ms"
16711 [(set_attr "type" "multi")
16712 (set_attr "length" "5")])
16713
16714 (define_expand "allocate_stack"
16715 [(match_operand 0 "register_operand" "")
16716 (match_operand 1 "general_operand" "")]
16717 "ix86_target_stack_probe ()"
16718 {
16719 rtx x;
16720
16721 #ifndef CHECK_STACK_LIMIT
16722 #define CHECK_STACK_LIMIT 0
16723 #endif
16724
16725 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16726 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16727 {
16728 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16729 stack_pointer_rtx, 0, OPTAB_DIRECT);
16730 if (x != stack_pointer_rtx)
16731 emit_move_insn (stack_pointer_rtx, x);
16732 }
16733 else
16734 {
16735 x = copy_to_mode_reg (Pmode, operands[1]);
16736 if (TARGET_64BIT)
16737 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16738 else
16739 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16740 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16741 stack_pointer_rtx, 0, OPTAB_DIRECT);
16742 if (x != stack_pointer_rtx)
16743 emit_move_insn (stack_pointer_rtx, x);
16744 }
16745
16746 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16747 DONE;
16748 })
16749
16750 ;; Use IOR for stack probes, this is shorter.
16751 (define_expand "probe_stack"
16752 [(match_operand 0 "memory_operand" "")]
16753 ""
16754 {
16755 rtx (*gen_ior3) (rtx, rtx, rtx);
16756
16757 gen_ior3 = (GET_MODE (operands[0]) == DImode
16758 ? gen_iordi3 : gen_iorsi3);
16759
16760 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16761 DONE;
16762 })
16763
16764 (define_insn "adjust_stack_and_probe<mode>"
16765 [(set (match_operand:P 0 "register_operand" "=r")
16766 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16767 UNSPECV_PROBE_STACK_RANGE))
16768 (set (reg:P SP_REG)
16769 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16770 (clobber (reg:CC FLAGS_REG))
16771 (clobber (mem:BLK (scratch)))]
16772 ""
16773 "* return output_adjust_stack_and_probe (operands[0]);"
16774 [(set_attr "type" "multi")])
16775
16776 (define_insn "probe_stack_range<mode>"
16777 [(set (match_operand:P 0 "register_operand" "=r")
16778 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16779 (match_operand:P 2 "const_int_operand" "n")]
16780 UNSPECV_PROBE_STACK_RANGE))
16781 (clobber (reg:CC FLAGS_REG))]
16782 ""
16783 "* return output_probe_stack_range (operands[0], operands[2]);"
16784 [(set_attr "type" "multi")])
16785
16786 (define_expand "builtin_setjmp_receiver"
16787 [(label_ref (match_operand 0 "" ""))]
16788 "!TARGET_64BIT && flag_pic"
16789 {
16790 #if TARGET_MACHO
16791 if (TARGET_MACHO)
16792 {
16793 rtx xops[3];
16794 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16795 rtx label_rtx = gen_label_rtx ();
16796 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16797 xops[0] = xops[1] = picreg;
16798 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16799 ix86_expand_binary_operator (MINUS, SImode, xops);
16800 }
16801 else
16802 #endif
16803 emit_insn (gen_set_got (pic_offset_table_rtx));
16804 DONE;
16805 })
16806 \f
16807 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16808
16809 (define_split
16810 [(set (match_operand 0 "register_operand" "")
16811 (match_operator 3 "promotable_binary_operator"
16812 [(match_operand 1 "register_operand" "")
16813 (match_operand 2 "aligned_operand" "")]))
16814 (clobber (reg:CC FLAGS_REG))]
16815 "! TARGET_PARTIAL_REG_STALL && reload_completed
16816 && ((GET_MODE (operands[0]) == HImode
16817 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16818 /* ??? next two lines just !satisfies_constraint_K (...) */
16819 || !CONST_INT_P (operands[2])
16820 || satisfies_constraint_K (operands[2])))
16821 || (GET_MODE (operands[0]) == QImode
16822 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16823 [(parallel [(set (match_dup 0)
16824 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16825 (clobber (reg:CC FLAGS_REG))])]
16826 "operands[0] = gen_lowpart (SImode, operands[0]);
16827 operands[1] = gen_lowpart (SImode, operands[1]);
16828 if (GET_CODE (operands[3]) != ASHIFT)
16829 operands[2] = gen_lowpart (SImode, operands[2]);
16830 PUT_MODE (operands[3], SImode);")
16831
16832 ; Promote the QImode tests, as i386 has encoding of the AND
16833 ; instruction with 32-bit sign-extended immediate and thus the
16834 ; instruction size is unchanged, except in the %eax case for
16835 ; which it is increased by one byte, hence the ! optimize_size.
16836 (define_split
16837 [(set (match_operand 0 "flags_reg_operand" "")
16838 (match_operator 2 "compare_operator"
16839 [(and (match_operand 3 "aligned_operand" "")
16840 (match_operand 4 "const_int_operand" ""))
16841 (const_int 0)]))
16842 (set (match_operand 1 "register_operand" "")
16843 (and (match_dup 3) (match_dup 4)))]
16844 "! TARGET_PARTIAL_REG_STALL && reload_completed
16845 && optimize_insn_for_speed_p ()
16846 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16847 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16848 /* Ensure that the operand will remain sign-extended immediate. */
16849 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16850 [(parallel [(set (match_dup 0)
16851 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16852 (const_int 0)]))
16853 (set (match_dup 1)
16854 (and:SI (match_dup 3) (match_dup 4)))])]
16855 {
16856 operands[4]
16857 = gen_int_mode (INTVAL (operands[4])
16858 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16859 operands[1] = gen_lowpart (SImode, operands[1]);
16860 operands[3] = gen_lowpart (SImode, operands[3]);
16861 })
16862
16863 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16864 ; the TEST instruction with 32-bit sign-extended immediate and thus
16865 ; the instruction size would at least double, which is not what we
16866 ; want even with ! optimize_size.
16867 (define_split
16868 [(set (match_operand 0 "flags_reg_operand" "")
16869 (match_operator 1 "compare_operator"
16870 [(and (match_operand:HI 2 "aligned_operand" "")
16871 (match_operand:HI 3 "const_int_operand" ""))
16872 (const_int 0)]))]
16873 "! TARGET_PARTIAL_REG_STALL && reload_completed
16874 && ! TARGET_FAST_PREFIX
16875 && optimize_insn_for_speed_p ()
16876 /* Ensure that the operand will remain sign-extended immediate. */
16877 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16878 [(set (match_dup 0)
16879 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16880 (const_int 0)]))]
16881 {
16882 operands[3]
16883 = gen_int_mode (INTVAL (operands[3])
16884 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16885 operands[2] = gen_lowpart (SImode, operands[2]);
16886 })
16887
16888 (define_split
16889 [(set (match_operand 0 "register_operand" "")
16890 (neg (match_operand 1 "register_operand" "")))
16891 (clobber (reg:CC FLAGS_REG))]
16892 "! TARGET_PARTIAL_REG_STALL && reload_completed
16893 && (GET_MODE (operands[0]) == HImode
16894 || (GET_MODE (operands[0]) == QImode
16895 && (TARGET_PROMOTE_QImode
16896 || optimize_insn_for_size_p ())))"
16897 [(parallel [(set (match_dup 0)
16898 (neg:SI (match_dup 1)))
16899 (clobber (reg:CC FLAGS_REG))])]
16900 "operands[0] = gen_lowpart (SImode, operands[0]);
16901 operands[1] = gen_lowpart (SImode, operands[1]);")
16902
16903 (define_split
16904 [(set (match_operand 0 "register_operand" "")
16905 (not (match_operand 1 "register_operand" "")))]
16906 "! TARGET_PARTIAL_REG_STALL && reload_completed
16907 && (GET_MODE (operands[0]) == HImode
16908 || (GET_MODE (operands[0]) == QImode
16909 && (TARGET_PROMOTE_QImode
16910 || optimize_insn_for_size_p ())))"
16911 [(set (match_dup 0)
16912 (not:SI (match_dup 1)))]
16913 "operands[0] = gen_lowpart (SImode, operands[0]);
16914 operands[1] = gen_lowpart (SImode, operands[1]);")
16915
16916 (define_split
16917 [(set (match_operand 0 "register_operand" "")
16918 (if_then_else (match_operator 1 "ordered_comparison_operator"
16919 [(reg FLAGS_REG) (const_int 0)])
16920 (match_operand 2 "register_operand" "")
16921 (match_operand 3 "register_operand" "")))]
16922 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16923 && (GET_MODE (operands[0]) == HImode
16924 || (GET_MODE (operands[0]) == QImode
16925 && (TARGET_PROMOTE_QImode
16926 || optimize_insn_for_size_p ())))"
16927 [(set (match_dup 0)
16928 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16929 "operands[0] = gen_lowpart (SImode, operands[0]);
16930 operands[2] = gen_lowpart (SImode, operands[2]);
16931 operands[3] = gen_lowpart (SImode, operands[3]);")
16932 \f
16933 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16934 ;; transform a complex memory operation into two memory to register operations.
16935
16936 ;; Don't push memory operands
16937 (define_peephole2
16938 [(set (match_operand:SWI 0 "push_operand" "")
16939 (match_operand:SWI 1 "memory_operand" ""))
16940 (match_scratch:SWI 2 "<r>")]
16941 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16942 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16943 [(set (match_dup 2) (match_dup 1))
16944 (set (match_dup 0) (match_dup 2))])
16945
16946 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16947 ;; SImode pushes.
16948 (define_peephole2
16949 [(set (match_operand:SF 0 "push_operand" "")
16950 (match_operand:SF 1 "memory_operand" ""))
16951 (match_scratch:SF 2 "r")]
16952 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16953 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16954 [(set (match_dup 2) (match_dup 1))
16955 (set (match_dup 0) (match_dup 2))])
16956
16957 ;; Don't move an immediate directly to memory when the instruction
16958 ;; gets too big.
16959 (define_peephole2
16960 [(match_scratch:SWI124 1 "<r>")
16961 (set (match_operand:SWI124 0 "memory_operand" "")
16962 (const_int 0))]
16963 "optimize_insn_for_speed_p ()
16964 && !TARGET_USE_MOV0
16965 && TARGET_SPLIT_LONG_MOVES
16966 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16967 && peep2_regno_dead_p (0, FLAGS_REG)"
16968 [(parallel [(set (match_dup 2) (const_int 0))
16969 (clobber (reg:CC FLAGS_REG))])
16970 (set (match_dup 0) (match_dup 1))]
16971 "operands[2] = gen_lowpart (SImode, operands[1]);")
16972
16973 (define_peephole2
16974 [(match_scratch:SWI124 2 "<r>")
16975 (set (match_operand:SWI124 0 "memory_operand" "")
16976 (match_operand:SWI124 1 "immediate_operand" ""))]
16977 "optimize_insn_for_speed_p ()
16978 && TARGET_SPLIT_LONG_MOVES
16979 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16980 [(set (match_dup 2) (match_dup 1))
16981 (set (match_dup 0) (match_dup 2))])
16982
16983 ;; Don't compare memory with zero, load and use a test instead.
16984 (define_peephole2
16985 [(set (match_operand 0 "flags_reg_operand" "")
16986 (match_operator 1 "compare_operator"
16987 [(match_operand:SI 2 "memory_operand" "")
16988 (const_int 0)]))
16989 (match_scratch:SI 3 "r")]
16990 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16991 [(set (match_dup 3) (match_dup 2))
16992 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16993
16994 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16995 ;; Don't split NOTs with a displacement operand, because resulting XOR
16996 ;; will not be pairable anyway.
16997 ;;
16998 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16999 ;; represented using a modRM byte. The XOR replacement is long decoded,
17000 ;; so this split helps here as well.
17001 ;;
17002 ;; Note: Can't do this as a regular split because we can't get proper
17003 ;; lifetime information then.
17004
17005 (define_peephole2
17006 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17007 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17008 "optimize_insn_for_speed_p ()
17009 && ((TARGET_NOT_UNPAIRABLE
17010 && (!MEM_P (operands[0])
17011 || !memory_displacement_operand (operands[0], <MODE>mode)))
17012 || (TARGET_NOT_VECTORMODE
17013 && long_memory_operand (operands[0], <MODE>mode)))
17014 && peep2_regno_dead_p (0, FLAGS_REG)"
17015 [(parallel [(set (match_dup 0)
17016 (xor:SWI124 (match_dup 1) (const_int -1)))
17017 (clobber (reg:CC FLAGS_REG))])])
17018
17019 ;; Non pairable "test imm, reg" instructions can be translated to
17020 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17021 ;; byte opcode instead of two, have a short form for byte operands),
17022 ;; so do it for other CPUs as well. Given that the value was dead,
17023 ;; this should not create any new dependencies. Pass on the sub-word
17024 ;; versions if we're concerned about partial register stalls.
17025
17026 (define_peephole2
17027 [(set (match_operand 0 "flags_reg_operand" "")
17028 (match_operator 1 "compare_operator"
17029 [(and:SI (match_operand:SI 2 "register_operand" "")
17030 (match_operand:SI 3 "immediate_operand" ""))
17031 (const_int 0)]))]
17032 "ix86_match_ccmode (insn, CCNOmode)
17033 && (true_regnum (operands[2]) != AX_REG
17034 || satisfies_constraint_K (operands[3]))
17035 && peep2_reg_dead_p (1, operands[2])"
17036 [(parallel
17037 [(set (match_dup 0)
17038 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17039 (const_int 0)]))
17040 (set (match_dup 2)
17041 (and:SI (match_dup 2) (match_dup 3)))])])
17042
17043 ;; We don't need to handle HImode case, because it will be promoted to SImode
17044 ;; on ! TARGET_PARTIAL_REG_STALL
17045
17046 (define_peephole2
17047 [(set (match_operand 0 "flags_reg_operand" "")
17048 (match_operator 1 "compare_operator"
17049 [(and:QI (match_operand:QI 2 "register_operand" "")
17050 (match_operand:QI 3 "immediate_operand" ""))
17051 (const_int 0)]))]
17052 "! TARGET_PARTIAL_REG_STALL
17053 && ix86_match_ccmode (insn, CCNOmode)
17054 && true_regnum (operands[2]) != AX_REG
17055 && peep2_reg_dead_p (1, operands[2])"
17056 [(parallel
17057 [(set (match_dup 0)
17058 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17059 (const_int 0)]))
17060 (set (match_dup 2)
17061 (and:QI (match_dup 2) (match_dup 3)))])])
17062
17063 (define_peephole2
17064 [(set (match_operand 0 "flags_reg_operand" "")
17065 (match_operator 1 "compare_operator"
17066 [(and:SI
17067 (zero_extract:SI
17068 (match_operand 2 "ext_register_operand" "")
17069 (const_int 8)
17070 (const_int 8))
17071 (match_operand 3 "const_int_operand" ""))
17072 (const_int 0)]))]
17073 "! TARGET_PARTIAL_REG_STALL
17074 && ix86_match_ccmode (insn, CCNOmode)
17075 && true_regnum (operands[2]) != AX_REG
17076 && peep2_reg_dead_p (1, operands[2])"
17077 [(parallel [(set (match_dup 0)
17078 (match_op_dup 1
17079 [(and:SI
17080 (zero_extract:SI
17081 (match_dup 2)
17082 (const_int 8)
17083 (const_int 8))
17084 (match_dup 3))
17085 (const_int 0)]))
17086 (set (zero_extract:SI (match_dup 2)
17087 (const_int 8)
17088 (const_int 8))
17089 (and:SI
17090 (zero_extract:SI
17091 (match_dup 2)
17092 (const_int 8)
17093 (const_int 8))
17094 (match_dup 3)))])])
17095
17096 ;; Don't do logical operations with memory inputs.
17097 (define_peephole2
17098 [(match_scratch:SI 2 "r")
17099 (parallel [(set (match_operand:SI 0 "register_operand" "")
17100 (match_operator:SI 3 "arith_or_logical_operator"
17101 [(match_dup 0)
17102 (match_operand:SI 1 "memory_operand" "")]))
17103 (clobber (reg:CC FLAGS_REG))])]
17104 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17105 [(set (match_dup 2) (match_dup 1))
17106 (parallel [(set (match_dup 0)
17107 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17108 (clobber (reg:CC FLAGS_REG))])])
17109
17110 (define_peephole2
17111 [(match_scratch:SI 2 "r")
17112 (parallel [(set (match_operand:SI 0 "register_operand" "")
17113 (match_operator:SI 3 "arith_or_logical_operator"
17114 [(match_operand:SI 1 "memory_operand" "")
17115 (match_dup 0)]))
17116 (clobber (reg:CC FLAGS_REG))])]
17117 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17118 [(set (match_dup 2) (match_dup 1))
17119 (parallel [(set (match_dup 0)
17120 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17121 (clobber (reg:CC FLAGS_REG))])])
17122
17123 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17124 ;; refers to the destination of the load!
17125
17126 (define_peephole2
17127 [(set (match_operand:SI 0 "register_operand" "")
17128 (match_operand:SI 1 "register_operand" ""))
17129 (parallel [(set (match_dup 0)
17130 (match_operator:SI 3 "commutative_operator"
17131 [(match_dup 0)
17132 (match_operand:SI 2 "memory_operand" "")]))
17133 (clobber (reg:CC FLAGS_REG))])]
17134 "REGNO (operands[0]) != REGNO (operands[1])
17135 && GENERAL_REGNO_P (REGNO (operands[0]))
17136 && GENERAL_REGNO_P (REGNO (operands[1]))"
17137 [(set (match_dup 0) (match_dup 4))
17138 (parallel [(set (match_dup 0)
17139 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17140 (clobber (reg:CC FLAGS_REG))])]
17141 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17142
17143 (define_peephole2
17144 [(set (match_operand 0 "register_operand" "")
17145 (match_operand 1 "register_operand" ""))
17146 (set (match_dup 0)
17147 (match_operator 3 "commutative_operator"
17148 [(match_dup 0)
17149 (match_operand 2 "memory_operand" "")]))]
17150 "REGNO (operands[0]) != REGNO (operands[1])
17151 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17152 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17153 [(set (match_dup 0) (match_dup 2))
17154 (set (match_dup 0)
17155 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17156
17157 ; Don't do logical operations with memory outputs
17158 ;
17159 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17160 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17161 ; the same decoder scheduling characteristics as the original.
17162
17163 (define_peephole2
17164 [(match_scratch:SI 2 "r")
17165 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17166 (match_operator:SI 3 "arith_or_logical_operator"
17167 [(match_dup 0)
17168 (match_operand:SI 1 "nonmemory_operand" "")]))
17169 (clobber (reg:CC FLAGS_REG))])]
17170 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17171 /* Do not split stack checking probes. */
17172 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17173 [(set (match_dup 2) (match_dup 0))
17174 (parallel [(set (match_dup 2)
17175 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17176 (clobber (reg:CC FLAGS_REG))])
17177 (set (match_dup 0) (match_dup 2))])
17178
17179 (define_peephole2
17180 [(match_scratch:SI 2 "r")
17181 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17182 (match_operator:SI 3 "arith_or_logical_operator"
17183 [(match_operand:SI 1 "nonmemory_operand" "")
17184 (match_dup 0)]))
17185 (clobber (reg:CC FLAGS_REG))])]
17186 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17187 /* Do not split stack checking probes. */
17188 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17189 [(set (match_dup 2) (match_dup 0))
17190 (parallel [(set (match_dup 2)
17191 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17192 (clobber (reg:CC FLAGS_REG))])
17193 (set (match_dup 0) (match_dup 2))])
17194
17195 ;; Attempt to use arith or logical operations with memory outputs with
17196 ;; setting of flags.
17197 (define_peephole2
17198 [(set (match_operand:SWI 0 "register_operand" "")
17199 (match_operand:SWI 1 "memory_operand" ""))
17200 (parallel [(set (match_dup 0)
17201 (match_operator:SWI 3 "plusminuslogic_operator"
17202 [(match_dup 0)
17203 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17204 (clobber (reg:CC FLAGS_REG))])
17205 (set (match_dup 1) (match_dup 0))
17206 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17207 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17208 && peep2_reg_dead_p (4, operands[0])
17209 && !reg_overlap_mentioned_p (operands[0], operands[1])
17210 && ix86_match_ccmode (peep2_next_insn (3),
17211 (GET_CODE (operands[3]) == PLUS
17212 || GET_CODE (operands[3]) == MINUS)
17213 ? CCGOCmode : CCNOmode)"
17214 [(parallel [(set (match_dup 4) (match_dup 5))
17215 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17216 (match_dup 2)]))])]
17217 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17218 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17219 copy_rtx (operands[1]),
17220 copy_rtx (operands[2]));
17221 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17222 operands[5], const0_rtx);")
17223
17224 (define_peephole2
17225 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17226 (match_operator:SWI 2 "plusminuslogic_operator"
17227 [(match_dup 0)
17228 (match_operand:SWI 1 "memory_operand" "")]))
17229 (clobber (reg:CC FLAGS_REG))])
17230 (set (match_dup 1) (match_dup 0))
17231 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17232 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17233 && GET_CODE (operands[2]) != MINUS
17234 && peep2_reg_dead_p (3, operands[0])
17235 && !reg_overlap_mentioned_p (operands[0], operands[1])
17236 && ix86_match_ccmode (peep2_next_insn (2),
17237 GET_CODE (operands[2]) == PLUS
17238 ? CCGOCmode : CCNOmode)"
17239 [(parallel [(set (match_dup 3) (match_dup 4))
17240 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17241 (match_dup 0)]))])]
17242 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17243 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17244 copy_rtx (operands[1]),
17245 copy_rtx (operands[0]));
17246 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17247 operands[4], const0_rtx);")
17248
17249 (define_peephole2
17250 [(set (match_operand:SWI12 0 "register_operand" "")
17251 (match_operand:SWI12 1 "memory_operand" ""))
17252 (parallel [(set (match_operand:SI 4 "register_operand" "")
17253 (match_operator:SI 3 "plusminuslogic_operator"
17254 [(match_dup 4)
17255 (match_operand:SI 2 "nonmemory_operand" "")]))
17256 (clobber (reg:CC FLAGS_REG))])
17257 (set (match_dup 1) (match_dup 0))
17258 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17259 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17260 && REG_P (operands[0]) && REG_P (operands[4])
17261 && REGNO (operands[0]) == REGNO (operands[4])
17262 && peep2_reg_dead_p (4, operands[0])
17263 && !reg_overlap_mentioned_p (operands[0], operands[1])
17264 && ix86_match_ccmode (peep2_next_insn (3),
17265 (GET_CODE (operands[3]) == PLUS
17266 || GET_CODE (operands[3]) == MINUS)
17267 ? CCGOCmode : CCNOmode)"
17268 [(parallel [(set (match_dup 4) (match_dup 5))
17269 (set (match_dup 1) (match_dup 6))])]
17270 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17271 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17272 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17273 copy_rtx (operands[1]), operands[2]);
17274 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17275 operands[5], const0_rtx);
17276 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17277 copy_rtx (operands[1]),
17278 copy_rtx (operands[2]));")
17279
17280 ;; Attempt to always use XOR for zeroing registers.
17281 (define_peephole2
17282 [(set (match_operand 0 "register_operand" "")
17283 (match_operand 1 "const0_operand" ""))]
17284 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17285 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17286 && GENERAL_REG_P (operands[0])
17287 && peep2_regno_dead_p (0, FLAGS_REG)"
17288 [(parallel [(set (match_dup 0) (const_int 0))
17289 (clobber (reg:CC FLAGS_REG))])]
17290 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17291
17292 (define_peephole2
17293 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17294 (const_int 0))]
17295 "(GET_MODE (operands[0]) == QImode
17296 || GET_MODE (operands[0]) == HImode)
17297 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17298 && peep2_regno_dead_p (0, FLAGS_REG)"
17299 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17300 (clobber (reg:CC FLAGS_REG))])])
17301
17302 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17303 (define_peephole2
17304 [(set (match_operand:SWI248 0 "register_operand" "")
17305 (const_int -1))]
17306 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17307 && peep2_regno_dead_p (0, FLAGS_REG)"
17308 [(parallel [(set (match_dup 0) (const_int -1))
17309 (clobber (reg:CC FLAGS_REG))])]
17310 {
17311 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17312 operands[0] = gen_lowpart (SImode, operands[0]);
17313 })
17314
17315 ;; Attempt to convert simple lea to add/shift.
17316 ;; These can be created by move expanders.
17317
17318 (define_peephole2
17319 [(set (match_operand:SWI48 0 "register_operand" "")
17320 (plus:SWI48 (match_dup 0)
17321 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17322 "peep2_regno_dead_p (0, FLAGS_REG)"
17323 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17324 (clobber (reg:CC FLAGS_REG))])])
17325
17326 (define_peephole2
17327 [(set (match_operand:SI 0 "register_operand" "")
17328 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17329 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17330 "TARGET_64BIT
17331 && peep2_regno_dead_p (0, FLAGS_REG)
17332 && REGNO (operands[0]) == REGNO (operands[1])"
17333 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17334 (clobber (reg:CC FLAGS_REG))])]
17335 "operands[2] = gen_lowpart (SImode, operands[2]);")
17336
17337 (define_peephole2
17338 [(set (match_operand:SWI48 0 "register_operand" "")
17339 (mult:SWI48 (match_dup 0)
17340 (match_operand:SWI48 1 "const_int_operand" "")))]
17341 "exact_log2 (INTVAL (operands[1])) >= 0
17342 && peep2_regno_dead_p (0, FLAGS_REG)"
17343 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17344 (clobber (reg:CC FLAGS_REG))])]
17345 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17346
17347 (define_peephole2
17348 [(set (match_operand:SI 0 "register_operand" "")
17349 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17350 (match_operand:DI 2 "const_int_operand" "")) 0))]
17351 "TARGET_64BIT
17352 && exact_log2 (INTVAL (operands[2])) >= 0
17353 && REGNO (operands[0]) == REGNO (operands[1])
17354 && peep2_regno_dead_p (0, FLAGS_REG)"
17355 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17356 (clobber (reg:CC FLAGS_REG))])]
17357 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17358
17359 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17360 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17361 ;; On many CPUs it is also faster, since special hardware to avoid esp
17362 ;; dependencies is present.
17363
17364 ;; While some of these conversions may be done using splitters, we use
17365 ;; peepholes in order to allow combine_stack_adjustments pass to see
17366 ;; nonobfuscated RTL.
17367
17368 ;; Convert prologue esp subtractions to push.
17369 ;; We need register to push. In order to keep verify_flow_info happy we have
17370 ;; two choices
17371 ;; - use scratch and clobber it in order to avoid dependencies
17372 ;; - use already live register
17373 ;; We can't use the second way right now, since there is no reliable way how to
17374 ;; verify that given register is live. First choice will also most likely in
17375 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17376 ;; call clobbered registers are dead. We may want to use base pointer as an
17377 ;; alternative when no register is available later.
17378
17379 (define_peephole2
17380 [(match_scratch:P 1 "r")
17381 (parallel [(set (reg:P SP_REG)
17382 (plus:P (reg:P SP_REG)
17383 (match_operand:P 0 "const_int_operand" "")))
17384 (clobber (reg:CC FLAGS_REG))
17385 (clobber (mem:BLK (scratch)))])]
17386 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17387 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17388 [(clobber (match_dup 1))
17389 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17390 (clobber (mem:BLK (scratch)))])])
17391
17392 (define_peephole2
17393 [(match_scratch:P 1 "r")
17394 (parallel [(set (reg:P SP_REG)
17395 (plus:P (reg:P SP_REG)
17396 (match_operand:P 0 "const_int_operand" "")))
17397 (clobber (reg:CC FLAGS_REG))
17398 (clobber (mem:BLK (scratch)))])]
17399 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17400 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17401 [(clobber (match_dup 1))
17402 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17403 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17404 (clobber (mem:BLK (scratch)))])])
17405
17406 ;; Convert esp subtractions to push.
17407 (define_peephole2
17408 [(match_scratch:P 1 "r")
17409 (parallel [(set (reg:P SP_REG)
17410 (plus:P (reg:P SP_REG)
17411 (match_operand:P 0 "const_int_operand" "")))
17412 (clobber (reg:CC FLAGS_REG))])]
17413 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17414 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17415 [(clobber (match_dup 1))
17416 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17417
17418 (define_peephole2
17419 [(match_scratch:P 1 "r")
17420 (parallel [(set (reg:P SP_REG)
17421 (plus:P (reg:P SP_REG)
17422 (match_operand:P 0 "const_int_operand" "")))
17423 (clobber (reg:CC FLAGS_REG))])]
17424 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17425 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17426 [(clobber (match_dup 1))
17427 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17428 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17429
17430 ;; Convert epilogue deallocator to pop.
17431 (define_peephole2
17432 [(match_scratch:P 1 "r")
17433 (parallel [(set (reg:P SP_REG)
17434 (plus:P (reg:P SP_REG)
17435 (match_operand:P 0 "const_int_operand" "")))
17436 (clobber (reg:CC FLAGS_REG))
17437 (clobber (mem:BLK (scratch)))])]
17438 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17439 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17440 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17441 (clobber (mem:BLK (scratch)))])])
17442
17443 ;; Two pops case is tricky, since pop causes dependency
17444 ;; on destination register. We use two registers if available.
17445 (define_peephole2
17446 [(match_scratch:P 1 "r")
17447 (match_scratch:P 2 "r")
17448 (parallel [(set (reg:P SP_REG)
17449 (plus:P (reg:P SP_REG)
17450 (match_operand:P 0 "const_int_operand" "")))
17451 (clobber (reg:CC FLAGS_REG))
17452 (clobber (mem:BLK (scratch)))])]
17453 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17454 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17455 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17456 (clobber (mem:BLK (scratch)))])
17457 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17458
17459 (define_peephole2
17460 [(match_scratch:P 1 "r")
17461 (parallel [(set (reg:P SP_REG)
17462 (plus:P (reg:P SP_REG)
17463 (match_operand:P 0 "const_int_operand" "")))
17464 (clobber (reg:CC FLAGS_REG))
17465 (clobber (mem:BLK (scratch)))])]
17466 "optimize_insn_for_size_p ()
17467 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17468 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17469 (clobber (mem:BLK (scratch)))])
17470 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17471
17472 ;; Convert esp additions to pop.
17473 (define_peephole2
17474 [(match_scratch:P 1 "r")
17475 (parallel [(set (reg:P SP_REG)
17476 (plus:P (reg:P SP_REG)
17477 (match_operand:P 0 "const_int_operand" "")))
17478 (clobber (reg:CC FLAGS_REG))])]
17479 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17480 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17481
17482 ;; Two pops case is tricky, since pop causes dependency
17483 ;; on destination register. We use two registers if available.
17484 (define_peephole2
17485 [(match_scratch:P 1 "r")
17486 (match_scratch:P 2 "r")
17487 (parallel [(set (reg:P SP_REG)
17488 (plus:P (reg:P SP_REG)
17489 (match_operand:P 0 "const_int_operand" "")))
17490 (clobber (reg:CC FLAGS_REG))])]
17491 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17492 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17493 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17494
17495 (define_peephole2
17496 [(match_scratch:P 1 "r")
17497 (parallel [(set (reg:P SP_REG)
17498 (plus:P (reg:P SP_REG)
17499 (match_operand:P 0 "const_int_operand" "")))
17500 (clobber (reg:CC FLAGS_REG))])]
17501 "optimize_insn_for_size_p ()
17502 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17503 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17504 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17505 \f
17506 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17507 ;; required and register dies. Similarly for 128 to -128.
17508 (define_peephole2
17509 [(set (match_operand 0 "flags_reg_operand" "")
17510 (match_operator 1 "compare_operator"
17511 [(match_operand 2 "register_operand" "")
17512 (match_operand 3 "const_int_operand" "")]))]
17513 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17514 && incdec_operand (operands[3], GET_MODE (operands[3])))
17515 || (!TARGET_FUSE_CMP_AND_BRANCH
17516 && INTVAL (operands[3]) == 128))
17517 && ix86_match_ccmode (insn, CCGCmode)
17518 && peep2_reg_dead_p (1, operands[2])"
17519 [(parallel [(set (match_dup 0)
17520 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17521 (clobber (match_dup 2))])])
17522 \f
17523 ;; Convert imul by three, five and nine into lea
17524 (define_peephole2
17525 [(parallel
17526 [(set (match_operand:SWI48 0 "register_operand" "")
17527 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17528 (match_operand:SWI48 2 "const359_operand" "")))
17529 (clobber (reg:CC FLAGS_REG))])]
17530 "!TARGET_PARTIAL_REG_STALL
17531 || <MODE>mode == SImode
17532 || optimize_function_for_size_p (cfun)"
17533 [(set (match_dup 0)
17534 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17535 (match_dup 1)))]
17536 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17537
17538 (define_peephole2
17539 [(parallel
17540 [(set (match_operand:SWI48 0 "register_operand" "")
17541 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17542 (match_operand:SWI48 2 "const359_operand" "")))
17543 (clobber (reg:CC FLAGS_REG))])]
17544 "optimize_insn_for_speed_p ()
17545 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17546 [(set (match_dup 0) (match_dup 1))
17547 (set (match_dup 0)
17548 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17549 (match_dup 0)))]
17550 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17551
17552 ;; imul $32bit_imm, mem, reg is vector decoded, while
17553 ;; imul $32bit_imm, reg, reg is direct decoded.
17554 (define_peephole2
17555 [(match_scratch:SWI48 3 "r")
17556 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17557 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17558 (match_operand:SWI48 2 "immediate_operand" "")))
17559 (clobber (reg:CC FLAGS_REG))])]
17560 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17561 && !satisfies_constraint_K (operands[2])"
17562 [(set (match_dup 3) (match_dup 1))
17563 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17564 (clobber (reg:CC FLAGS_REG))])])
17565
17566 (define_peephole2
17567 [(match_scratch:SI 3 "r")
17568 (parallel [(set (match_operand:DI 0 "register_operand" "")
17569 (zero_extend:DI
17570 (mult:SI (match_operand:SI 1 "memory_operand" "")
17571 (match_operand:SI 2 "immediate_operand" ""))))
17572 (clobber (reg:CC FLAGS_REG))])]
17573 "TARGET_64BIT
17574 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17575 && !satisfies_constraint_K (operands[2])"
17576 [(set (match_dup 3) (match_dup 1))
17577 (parallel [(set (match_dup 0)
17578 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17579 (clobber (reg:CC FLAGS_REG))])])
17580
17581 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17582 ;; Convert it into imul reg, reg
17583 ;; It would be better to force assembler to encode instruction using long
17584 ;; immediate, but there is apparently no way to do so.
17585 (define_peephole2
17586 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17587 (mult:SWI248
17588 (match_operand:SWI248 1 "nonimmediate_operand" "")
17589 (match_operand:SWI248 2 "const_int_operand" "")))
17590 (clobber (reg:CC FLAGS_REG))])
17591 (match_scratch:SWI248 3 "r")]
17592 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17593 && satisfies_constraint_K (operands[2])"
17594 [(set (match_dup 3) (match_dup 2))
17595 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17596 (clobber (reg:CC FLAGS_REG))])]
17597 {
17598 if (!rtx_equal_p (operands[0], operands[1]))
17599 emit_move_insn (operands[0], operands[1]);
17600 })
17601
17602 ;; After splitting up read-modify operations, array accesses with memory
17603 ;; operands might end up in form:
17604 ;; sall $2, %eax
17605 ;; movl 4(%esp), %edx
17606 ;; addl %edx, %eax
17607 ;; instead of pre-splitting:
17608 ;; sall $2, %eax
17609 ;; addl 4(%esp), %eax
17610 ;; Turn it into:
17611 ;; movl 4(%esp), %edx
17612 ;; leal (%edx,%eax,4), %eax
17613
17614 (define_peephole2
17615 [(match_scratch:P 5 "r")
17616 (parallel [(set (match_operand 0 "register_operand" "")
17617 (ashift (match_operand 1 "register_operand" "")
17618 (match_operand 2 "const_int_operand" "")))
17619 (clobber (reg:CC FLAGS_REG))])
17620 (parallel [(set (match_operand 3 "register_operand" "")
17621 (plus (match_dup 0)
17622 (match_operand 4 "x86_64_general_operand" "")))
17623 (clobber (reg:CC FLAGS_REG))])]
17624 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17625 /* Validate MODE for lea. */
17626 && ((!TARGET_PARTIAL_REG_STALL
17627 && (GET_MODE (operands[0]) == QImode
17628 || GET_MODE (operands[0]) == HImode))
17629 || GET_MODE (operands[0]) == SImode
17630 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17631 && (rtx_equal_p (operands[0], operands[3])
17632 || peep2_reg_dead_p (2, operands[0]))
17633 /* We reorder load and the shift. */
17634 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17635 [(set (match_dup 5) (match_dup 4))
17636 (set (match_dup 0) (match_dup 1))]
17637 {
17638 enum machine_mode op1mode = GET_MODE (operands[1]);
17639 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17640 int scale = 1 << INTVAL (operands[2]);
17641 rtx index = gen_lowpart (Pmode, operands[1]);
17642 rtx base = gen_lowpart (Pmode, operands[5]);
17643 rtx dest = gen_lowpart (mode, operands[3]);
17644
17645 operands[1] = gen_rtx_PLUS (Pmode, base,
17646 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17647 operands[5] = base;
17648 if (mode != Pmode)
17649 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17650 if (op1mode != Pmode)
17651 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17652 operands[0] = dest;
17653 })
17654 \f
17655 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17656 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17657 ;; caught for use by garbage collectors and the like. Using an insn that
17658 ;; maps to SIGILL makes it more likely the program will rightfully die.
17659 ;; Keeping with tradition, "6" is in honor of #UD.
17660 (define_insn "trap"
17661 [(trap_if (const_int 1) (const_int 6))]
17662 ""
17663 { return ASM_SHORT "0x0b0f"; }
17664 [(set_attr "length" "2")])
17665
17666 (define_expand "prefetch"
17667 [(prefetch (match_operand 0 "address_operand" "")
17668 (match_operand:SI 1 "const_int_operand" "")
17669 (match_operand:SI 2 "const_int_operand" ""))]
17670 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17671 {
17672 int rw = INTVAL (operands[1]);
17673 int locality = INTVAL (operands[2]);
17674
17675 gcc_assert (rw == 0 || rw == 1);
17676 gcc_assert (locality >= 0 && locality <= 3);
17677 gcc_assert (GET_MODE (operands[0]) == Pmode
17678 || GET_MODE (operands[0]) == VOIDmode);
17679
17680 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17681 supported by SSE counterpart or the SSE prefetch is not available
17682 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17683 of locality. */
17684 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17685 operands[2] = GEN_INT (3);
17686 else
17687 operands[1] = const0_rtx;
17688 })
17689
17690 (define_insn "*prefetch_sse_<mode>"
17691 [(prefetch (match_operand:P 0 "address_operand" "p")
17692 (const_int 0)
17693 (match_operand:SI 1 "const_int_operand" ""))]
17694 "TARGET_PREFETCH_SSE"
17695 {
17696 static const char * const patterns[4] = {
17697 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17698 };
17699
17700 int locality = INTVAL (operands[1]);
17701 gcc_assert (locality >= 0 && locality <= 3);
17702
17703 return patterns[locality];
17704 }
17705 [(set_attr "type" "sse")
17706 (set_attr "atom_sse_attr" "prefetch")
17707 (set (attr "length_address")
17708 (symbol_ref "memory_address_length (operands[0])"))
17709 (set_attr "memory" "none")])
17710
17711 (define_insn "*prefetch_3dnow_<mode>"
17712 [(prefetch (match_operand:P 0 "address_operand" "p")
17713 (match_operand:SI 1 "const_int_operand" "n")
17714 (const_int 3))]
17715 "TARGET_3DNOW"
17716 {
17717 if (INTVAL (operands[1]) == 0)
17718 return "prefetch\t%a0";
17719 else
17720 return "prefetchw\t%a0";
17721 }
17722 [(set_attr "type" "mmx")
17723 (set (attr "length_address")
17724 (symbol_ref "memory_address_length (operands[0])"))
17725 (set_attr "memory" "none")])
17726
17727 (define_expand "stack_protect_set"
17728 [(match_operand 0 "memory_operand" "")
17729 (match_operand 1 "memory_operand" "")]
17730 ""
17731 {
17732 rtx (*insn)(rtx, rtx);
17733
17734 #ifdef TARGET_THREAD_SSP_OFFSET
17735 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17736 insn = (TARGET_LP64
17737 ? gen_stack_tls_protect_set_di
17738 : gen_stack_tls_protect_set_si);
17739 #else
17740 insn = (TARGET_LP64
17741 ? gen_stack_protect_set_di
17742 : gen_stack_protect_set_si);
17743 #endif
17744
17745 emit_insn (insn (operands[0], operands[1]));
17746 DONE;
17747 })
17748
17749 (define_insn "stack_protect_set_<mode>"
17750 [(set (match_operand:PTR 0 "memory_operand" "=m")
17751 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17752 UNSPEC_SP_SET))
17753 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17754 (clobber (reg:CC FLAGS_REG))]
17755 ""
17756 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17757 [(set_attr "type" "multi")])
17758
17759 (define_insn "stack_tls_protect_set_<mode>"
17760 [(set (match_operand:PTR 0 "memory_operand" "=m")
17761 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17762 UNSPEC_SP_TLS_SET))
17763 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17764 (clobber (reg:CC FLAGS_REG))]
17765 ""
17766 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17767 [(set_attr "type" "multi")])
17768
17769 (define_expand "stack_protect_test"
17770 [(match_operand 0 "memory_operand" "")
17771 (match_operand 1 "memory_operand" "")
17772 (match_operand 2 "" "")]
17773 ""
17774 {
17775 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17776
17777 rtx (*insn)(rtx, rtx, rtx);
17778
17779 #ifdef TARGET_THREAD_SSP_OFFSET
17780 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17781 insn = (TARGET_LP64
17782 ? gen_stack_tls_protect_test_di
17783 : gen_stack_tls_protect_test_si);
17784 #else
17785 insn = (TARGET_LP64
17786 ? gen_stack_protect_test_di
17787 : gen_stack_protect_test_si);
17788 #endif
17789
17790 emit_insn (insn (flags, operands[0], operands[1]));
17791
17792 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17793 flags, const0_rtx, operands[2]));
17794 DONE;
17795 })
17796
17797 (define_insn "stack_protect_test_<mode>"
17798 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17799 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17800 (match_operand:PTR 2 "memory_operand" "m")]
17801 UNSPEC_SP_TEST))
17802 (clobber (match_scratch:PTR 3 "=&r"))]
17803 ""
17804 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17805 [(set_attr "type" "multi")])
17806
17807 (define_insn "stack_tls_protect_test_<mode>"
17808 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17809 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17810 (match_operand:PTR 2 "const_int_operand" "i")]
17811 UNSPEC_SP_TLS_TEST))
17812 (clobber (match_scratch:PTR 3 "=r"))]
17813 ""
17814 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17815 [(set_attr "type" "multi")])
17816
17817 (define_insn "sse4_2_crc32<mode>"
17818 [(set (match_operand:SI 0 "register_operand" "=r")
17819 (unspec:SI
17820 [(match_operand:SI 1 "register_operand" "0")
17821 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17822 UNSPEC_CRC32))]
17823 "TARGET_SSE4_2 || TARGET_CRC32"
17824 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17825 [(set_attr "type" "sselog1")
17826 (set_attr "prefix_rep" "1")
17827 (set_attr "prefix_extra" "1")
17828 (set (attr "prefix_data16")
17829 (if_then_else (match_operand:HI 2 "" "")
17830 (const_string "1")
17831 (const_string "*")))
17832 (set (attr "prefix_rex")
17833 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17834 (const_string "1")
17835 (const_string "*")))
17836 (set_attr "mode" "SI")])
17837
17838 (define_insn "sse4_2_crc32di"
17839 [(set (match_operand:DI 0 "register_operand" "=r")
17840 (unspec:DI
17841 [(match_operand:DI 1 "register_operand" "0")
17842 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17843 UNSPEC_CRC32))]
17844 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17845 "crc32{q}\t{%2, %0|%0, %2}"
17846 [(set_attr "type" "sselog1")
17847 (set_attr "prefix_rep" "1")
17848 (set_attr "prefix_extra" "1")
17849 (set_attr "mode" "DI")])
17850
17851 (define_expand "rdpmc"
17852 [(match_operand:DI 0 "register_operand" "")
17853 (match_operand:SI 1 "register_operand" "")]
17854 ""
17855 {
17856 rtx reg = gen_reg_rtx (DImode);
17857 rtx si;
17858
17859 /* Force operand 1 into ECX. */
17860 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17861 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17862 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17863 UNSPECV_RDPMC);
17864
17865 if (TARGET_64BIT)
17866 {
17867 rtvec vec = rtvec_alloc (2);
17868 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17869 rtx upper = gen_reg_rtx (DImode);
17870 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17871 gen_rtvec (1, const0_rtx),
17872 UNSPECV_RDPMC);
17873 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17874 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17875 emit_insn (load);
17876 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17877 NULL, 1, OPTAB_DIRECT);
17878 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17879 OPTAB_DIRECT);
17880 }
17881 else
17882 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17883 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17884 DONE;
17885 })
17886
17887 (define_insn "*rdpmc"
17888 [(set (match_operand:DI 0 "register_operand" "=A")
17889 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17890 UNSPECV_RDPMC))]
17891 "!TARGET_64BIT"
17892 "rdpmc"
17893 [(set_attr "type" "other")
17894 (set_attr "length" "2")])
17895
17896 (define_insn "*rdpmc_rex64"
17897 [(set (match_operand:DI 0 "register_operand" "=a")
17898 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17899 UNSPECV_RDPMC))
17900 (set (match_operand:DI 1 "register_operand" "=d")
17901 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17902 "TARGET_64BIT"
17903 "rdpmc"
17904 [(set_attr "type" "other")
17905 (set_attr "length" "2")])
17906
17907 (define_expand "rdtsc"
17908 [(set (match_operand:DI 0 "register_operand" "")
17909 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17910 ""
17911 {
17912 if (TARGET_64BIT)
17913 {
17914 rtvec vec = rtvec_alloc (2);
17915 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17916 rtx upper = gen_reg_rtx (DImode);
17917 rtx lower = gen_reg_rtx (DImode);
17918 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17919 gen_rtvec (1, const0_rtx),
17920 UNSPECV_RDTSC);
17921 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17922 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17923 emit_insn (load);
17924 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17925 NULL, 1, OPTAB_DIRECT);
17926 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17927 OPTAB_DIRECT);
17928 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17929 DONE;
17930 }
17931 })
17932
17933 (define_insn "*rdtsc"
17934 [(set (match_operand:DI 0 "register_operand" "=A")
17935 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17936 "!TARGET_64BIT"
17937 "rdtsc"
17938 [(set_attr "type" "other")
17939 (set_attr "length" "2")])
17940
17941 (define_insn "*rdtsc_rex64"
17942 [(set (match_operand:DI 0 "register_operand" "=a")
17943 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17944 (set (match_operand:DI 1 "register_operand" "=d")
17945 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17946 "TARGET_64BIT"
17947 "rdtsc"
17948 [(set_attr "type" "other")
17949 (set_attr "length" "2")])
17950
17951 (define_expand "rdtscp"
17952 [(match_operand:DI 0 "register_operand" "")
17953 (match_operand:SI 1 "memory_operand" "")]
17954 ""
17955 {
17956 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17957 gen_rtvec (1, const0_rtx),
17958 UNSPECV_RDTSCP);
17959 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17960 gen_rtvec (1, const0_rtx),
17961 UNSPECV_RDTSCP);
17962 rtx reg = gen_reg_rtx (DImode);
17963 rtx tmp = gen_reg_rtx (SImode);
17964
17965 if (TARGET_64BIT)
17966 {
17967 rtvec vec = rtvec_alloc (3);
17968 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17969 rtx upper = gen_reg_rtx (DImode);
17970 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17971 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17972 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17973 emit_insn (load);
17974 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17975 NULL, 1, OPTAB_DIRECT);
17976 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17977 OPTAB_DIRECT);
17978 }
17979 else
17980 {
17981 rtvec vec = rtvec_alloc (2);
17982 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17983 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17984 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17985 emit_insn (load);
17986 }
17987 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17988 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17989 DONE;
17990 })
17991
17992 (define_insn "*rdtscp"
17993 [(set (match_operand:DI 0 "register_operand" "=A")
17994 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17995 (set (match_operand:SI 1 "register_operand" "=c")
17996 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17997 "!TARGET_64BIT"
17998 "rdtscp"
17999 [(set_attr "type" "other")
18000 (set_attr "length" "3")])
18001
18002 (define_insn "*rdtscp_rex64"
18003 [(set (match_operand:DI 0 "register_operand" "=a")
18004 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18005 (set (match_operand:DI 1 "register_operand" "=d")
18006 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18007 (set (match_operand:SI 2 "register_operand" "=c")
18008 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18009 "TARGET_64BIT"
18010 "rdtscp"
18011 [(set_attr "type" "other")
18012 (set_attr "length" "3")])
18013
18014 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18015 ;;
18016 ;; LWP instructions
18017 ;;
18018 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18019
18020 (define_expand "lwp_llwpcb"
18021 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18022 UNSPECV_LLWP_INTRINSIC)]
18023 "TARGET_LWP")
18024
18025 (define_insn "*lwp_llwpcb<mode>1"
18026 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18027 UNSPECV_LLWP_INTRINSIC)]
18028 "TARGET_LWP"
18029 "llwpcb\t%0"
18030 [(set_attr "type" "lwp")
18031 (set_attr "mode" "<MODE>")
18032 (set_attr "length" "5")])
18033
18034 (define_expand "lwp_slwpcb"
18035 [(set (match_operand 0 "register_operand" "=r")
18036 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18037 "TARGET_LWP"
18038 {
18039 rtx (*insn)(rtx);
18040
18041 insn = (TARGET_64BIT
18042 ? gen_lwp_slwpcbdi
18043 : gen_lwp_slwpcbsi);
18044
18045 emit_insn (insn (operands[0]));
18046 DONE;
18047 })
18048
18049 (define_insn "lwp_slwpcb<mode>"
18050 [(set (match_operand:P 0 "register_operand" "=r")
18051 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18052 "TARGET_LWP"
18053 "slwpcb\t%0"
18054 [(set_attr "type" "lwp")
18055 (set_attr "mode" "<MODE>")
18056 (set_attr "length" "5")])
18057
18058 (define_expand "lwp_lwpval<mode>3"
18059 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18060 (match_operand:SI 2 "nonimmediate_operand" "rm")
18061 (match_operand:SI 3 "const_int_operand" "i")]
18062 UNSPECV_LWPVAL_INTRINSIC)]
18063 "TARGET_LWP"
18064 "/* Avoid unused variable warning. */
18065 (void) operand0;")
18066
18067 (define_insn "*lwp_lwpval<mode>3_1"
18068 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18069 (match_operand:SI 1 "nonimmediate_operand" "rm")
18070 (match_operand:SI 2 "const_int_operand" "i")]
18071 UNSPECV_LWPVAL_INTRINSIC)]
18072 "TARGET_LWP"
18073 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18074 [(set_attr "type" "lwp")
18075 (set_attr "mode" "<MODE>")
18076 (set (attr "length")
18077 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18078
18079 (define_expand "lwp_lwpins<mode>3"
18080 [(set (reg:CCC FLAGS_REG)
18081 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18082 (match_operand:SI 2 "nonimmediate_operand" "rm")
18083 (match_operand:SI 3 "const_int_operand" "i")]
18084 UNSPECV_LWPINS_INTRINSIC))
18085 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18086 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18087 "TARGET_LWP")
18088
18089 (define_insn "*lwp_lwpins<mode>3_1"
18090 [(set (reg:CCC FLAGS_REG)
18091 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18092 (match_operand:SI 1 "nonimmediate_operand" "rm")
18093 (match_operand:SI 2 "const_int_operand" "i")]
18094 UNSPECV_LWPINS_INTRINSIC))]
18095 "TARGET_LWP"
18096 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18097 [(set_attr "type" "lwp")
18098 (set_attr "mode" "<MODE>")
18099 (set (attr "length")
18100 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18101
18102 (define_insn "rdfsbase<mode>"
18103 [(set (match_operand:SWI48 0 "register_operand" "=r")
18104 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18105 "TARGET_64BIT && TARGET_FSGSBASE"
18106 "rdfsbase %0"
18107 [(set_attr "type" "other")
18108 (set_attr "prefix_extra" "2")])
18109
18110 (define_insn "rdgsbase<mode>"
18111 [(set (match_operand:SWI48 0 "register_operand" "=r")
18112 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18113 "TARGET_64BIT && TARGET_FSGSBASE"
18114 "rdgsbase %0"
18115 [(set_attr "type" "other")
18116 (set_attr "prefix_extra" "2")])
18117
18118 (define_insn "wrfsbase<mode>"
18119 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18120 UNSPECV_WRFSBASE)]
18121 "TARGET_64BIT && TARGET_FSGSBASE"
18122 "wrfsbase %0"
18123 [(set_attr "type" "other")
18124 (set_attr "prefix_extra" "2")])
18125
18126 (define_insn "wrgsbase<mode>"
18127 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18128 UNSPECV_WRGSBASE)]
18129 "TARGET_64BIT && TARGET_FSGSBASE"
18130 "wrgsbase %0"
18131 [(set_attr "type" "other")
18132 (set_attr "prefix_extra" "2")])
18133
18134 (define_insn "rdrand<mode>_1"
18135 [(set (match_operand:SWI248 0 "register_operand" "=r")
18136 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18137 (set (reg:CCC FLAGS_REG)
18138 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18139 "TARGET_RDRND"
18140 "rdrand\t%0"
18141 [(set_attr "type" "other")
18142 (set_attr "prefix_extra" "1")])
18143
18144 (define_expand "pause"
18145 [(set (match_dup 0)
18146 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18147 ""
18148 {
18149 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18150 MEM_VOLATILE_P (operands[0]) = 1;
18151 })
18152
18153 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18154 ;; They have the same encoding.
18155 (define_insn "*pause"
18156 [(set (match_operand:BLK 0 "" "")
18157 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18158 ""
18159 "rep; nop"
18160 [(set_attr "length" "2")
18161 (set_attr "memory" "unknown")])
18162
18163 (include "mmx.md")
18164 (include "sse.md")
18165 (include "sync.md")