winnt.c (i386_pe_seh_end_prologue): Move code to ...
[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, 2012
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 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; K -- print HLE lock prefix
62 ;; Y -- print condition for XOP pcom* instruction.
63 ;; + -- print a branch hint as 'cs' or 'ds' prefix
64 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
65 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
66 ;; @ -- print a segment register of thread base pointer load
67 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
68
69 (define_c_enum "unspec" [
70 ;; Relocation specifiers
71 UNSPEC_GOT
72 UNSPEC_GOTOFF
73 UNSPEC_GOTPCREL
74 UNSPEC_GOTTPOFF
75 UNSPEC_TPOFF
76 UNSPEC_NTPOFF
77 UNSPEC_DTPOFF
78 UNSPEC_GOTNTPOFF
79 UNSPEC_INDNTPOFF
80 UNSPEC_PLTOFF
81 UNSPEC_MACHOPIC_OFFSET
82 UNSPEC_PCREL
83
84 ;; Prologue support
85 UNSPEC_STACK_ALLOC
86 UNSPEC_SET_GOT
87 UNSPEC_SET_RIP
88 UNSPEC_SET_GOT_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
90 UNSPEC_STACK_CHECK
91
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_MS_TO_SYSV_CALL
112 UNSPEC_CALL_NEEDS_VZEROUPPER
113 UNSPEC_PAUSE
114 UNSPEC_LEA_ADDR
115 UNSPEC_XBEGIN_ABORT
116
117 ;; For SSE/MMX support:
118 UNSPEC_FIX_NOTRUNC
119 UNSPEC_MASKMOV
120 UNSPEC_MOVMSK
121 UNSPEC_RCP
122 UNSPEC_RSQRT
123 UNSPEC_PSADBW
124
125 ;; Generic math support
126 UNSPEC_COPYSIGN
127 UNSPEC_IEEE_MIN ; not commutative
128 UNSPEC_IEEE_MAX ; not commutative
129
130 ;; x87 Floating point
131 UNSPEC_SIN
132 UNSPEC_COS
133 UNSPEC_FPATAN
134 UNSPEC_FYL2X
135 UNSPEC_FYL2XP1
136 UNSPEC_FRNDINT
137 UNSPEC_FIST
138 UNSPEC_F2XM1
139 UNSPEC_TAN
140 UNSPEC_FXAM
141
142 ;; x87 Rounding
143 UNSPEC_FRNDINT_FLOOR
144 UNSPEC_FRNDINT_CEIL
145 UNSPEC_FRNDINT_TRUNC
146 UNSPEC_FRNDINT_MASK_PM
147 UNSPEC_FIST_FLOOR
148 UNSPEC_FIST_CEIL
149
150 ;; x87 Double output FP
151 UNSPEC_SINCOS_COS
152 UNSPEC_SINCOS_SIN
153 UNSPEC_XTRACT_FRACT
154 UNSPEC_XTRACT_EXP
155 UNSPEC_FSCALE_FRACT
156 UNSPEC_FSCALE_EXP
157 UNSPEC_FPREM_F
158 UNSPEC_FPREM_U
159 UNSPEC_FPREM1_F
160 UNSPEC_FPREM1_U
161
162 UNSPEC_C2_FLAG
163 UNSPEC_FXAM_MEM
164
165 ;; SSP patterns
166 UNSPEC_SP_SET
167 UNSPEC_SP_TEST
168 UNSPEC_SP_TLS_SET
169 UNSPEC_SP_TLS_TEST
170
171 ;; For ROUND support
172 UNSPEC_ROUND
173
174 ;; For CRC32 support
175 UNSPEC_CRC32
176
177 ;; For BMI support
178 UNSPEC_BEXTR
179
180 ;; For BMI2 support
181 UNSPEC_PDEP
182 UNSPEC_PEXT
183 ])
184
185 (define_c_enum "unspecv" [
186 UNSPECV_BLOCKAGE
187 UNSPECV_STACK_PROBE
188 UNSPECV_PROBE_STACK_RANGE
189 UNSPECV_ALIGN
190 UNSPECV_PROLOGUE_USE
191 UNSPECV_SPLIT_STACK_RETURN
192 UNSPECV_CLD
193 UNSPECV_NOPS
194 UNSPECV_RDTSC
195 UNSPECV_RDTSCP
196 UNSPECV_RDPMC
197 UNSPECV_LLWP_INTRINSIC
198 UNSPECV_SLWP_INTRINSIC
199 UNSPECV_LWPVAL_INTRINSIC
200 UNSPECV_LWPINS_INTRINSIC
201 UNSPECV_RDFSBASE
202 UNSPECV_RDGSBASE
203 UNSPECV_WRFSBASE
204 UNSPECV_WRGSBASE
205
206 ;; For RDRAND support
207 UNSPECV_RDRAND
208
209 ;; For RTM support
210 UNSPECV_XBEGIN
211 UNSPECV_XEND
212 UNSPECV_XABORT
213 UNSPECV_XTEST
214 ])
215
216 ;; Constants to represent rounding modes in the ROUND instruction
217 (define_constants
218 [(ROUND_FLOOR 0x1)
219 (ROUND_CEIL 0x2)
220 (ROUND_TRUNC 0x3)
221 (ROUND_MXCSR 0x4)
222 (ROUND_NO_EXC 0x8)
223 ])
224
225 ;; Constants to represent pcomtrue/pcomfalse variants
226 (define_constants
227 [(PCOM_FALSE 0)
228 (PCOM_TRUE 1)
229 (COM_FALSE_S 2)
230 (COM_FALSE_P 3)
231 (COM_TRUE_S 4)
232 (COM_TRUE_P 5)
233 ])
234
235 ;; Constants used in the XOP pperm instruction
236 (define_constants
237 [(PPERM_SRC 0x00) /* copy source */
238 (PPERM_INVERT 0x20) /* invert source */
239 (PPERM_REVERSE 0x40) /* bit reverse source */
240 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
241 (PPERM_ZERO 0x80) /* all 0's */
242 (PPERM_ONES 0xa0) /* all 1's */
243 (PPERM_SIGN 0xc0) /* propagate sign bit */
244 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
245 (PPERM_SRC1 0x00) /* use first source byte */
246 (PPERM_SRC2 0x10) /* use second source byte */
247 ])
248
249 ;; Registers by name.
250 (define_constants
251 [(AX_REG 0)
252 (DX_REG 1)
253 (CX_REG 2)
254 (BX_REG 3)
255 (SI_REG 4)
256 (DI_REG 5)
257 (BP_REG 6)
258 (SP_REG 7)
259 (ST0_REG 8)
260 (ST1_REG 9)
261 (ST2_REG 10)
262 (ST3_REG 11)
263 (ST4_REG 12)
264 (ST5_REG 13)
265 (ST6_REG 14)
266 (ST7_REG 15)
267 (FLAGS_REG 17)
268 (FPSR_REG 18)
269 (FPCR_REG 19)
270 (XMM0_REG 21)
271 (XMM1_REG 22)
272 (XMM2_REG 23)
273 (XMM3_REG 24)
274 (XMM4_REG 25)
275 (XMM5_REG 26)
276 (XMM6_REG 27)
277 (XMM7_REG 28)
278 (MM0_REG 29)
279 (MM1_REG 30)
280 (MM2_REG 31)
281 (MM3_REG 32)
282 (MM4_REG 33)
283 (MM5_REG 34)
284 (MM6_REG 35)
285 (MM7_REG 36)
286 (R8_REG 37)
287 (R9_REG 38)
288 (R10_REG 39)
289 (R11_REG 40)
290 (R12_REG 41)
291 (R13_REG 42)
292 (XMM8_REG 45)
293 (XMM9_REG 46)
294 (XMM10_REG 47)
295 (XMM11_REG 48)
296 (XMM12_REG 49)
297 (XMM13_REG 50)
298 (XMM14_REG 51)
299 (XMM15_REG 52)
300 ])
301
302 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
303 ;; from i386.c.
304
305 ;; In C guard expressions, put expressions which may be compile-time
306 ;; constants first. This allows for better optimization. For
307 ;; example, write "TARGET_64BIT && reload_completed", not
308 ;; "reload_completed && TARGET_64BIT".
309
310 \f
311 ;; Processor type.
312 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
313 atom,generic64,amdfam10,bdver1,bdver2,btver1"
314 (const (symbol_ref "ix86_schedule")))
315
316 ;; A basic instruction type. Refinements due to arguments to be
317 ;; provided in other attributes.
318 (define_attr "type"
319 "other,multi,
320 alu,alu1,negnot,imov,imovx,lea,
321 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
322 icmp,test,ibr,setcc,icmov,
323 push,pop,call,callv,leave,
324 str,bitmanip,
325 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
326 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
327 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
328 ssemuladd,sse4arg,lwp,
329 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
330 (const_string "other"))
331
332 ;; Main data type used by the insn
333 (define_attr "mode"
334 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
335 (const_string "unknown"))
336
337 ;; The CPU unit operations uses.
338 (define_attr "unit" "integer,i387,sse,mmx,unknown"
339 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
340 (const_string "i387")
341 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
342 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
343 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
344 (const_string "sse")
345 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
346 (const_string "mmx")
347 (eq_attr "type" "other")
348 (const_string "unknown")]
349 (const_string "integer")))
350
351 ;; The (bounding maximum) length of an instruction immediate.
352 (define_attr "length_immediate" ""
353 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
354 bitmanip,imulx")
355 (const_int 0)
356 (eq_attr "unit" "i387,sse,mmx")
357 (const_int 0)
358 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
359 rotate,rotatex,rotate1,imul,icmp,push,pop")
360 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
361 (eq_attr "type" "imov,test")
362 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
363 (eq_attr "type" "call")
364 (if_then_else (match_operand 0 "constant_call_address_operand")
365 (const_int 4)
366 (const_int 0))
367 (eq_attr "type" "callv")
368 (if_then_else (match_operand 1 "constant_call_address_operand")
369 (const_int 4)
370 (const_int 0))
371 ;; We don't know the size before shorten_branches. Expect
372 ;; the instruction to fit for better scheduling.
373 (eq_attr "type" "ibr")
374 (const_int 1)
375 ]
376 (symbol_ref "/* Update immediate_length and other attributes! */
377 gcc_unreachable (),1")))
378
379 ;; The (bounding maximum) length of an instruction address.
380 (define_attr "length_address" ""
381 (cond [(eq_attr "type" "str,other,multi,fxch")
382 (const_int 0)
383 (and (eq_attr "type" "call")
384 (match_operand 0 "constant_call_address_operand"))
385 (const_int 0)
386 (and (eq_attr "type" "callv")
387 (match_operand 1 "constant_call_address_operand"))
388 (const_int 0)
389 ]
390 (symbol_ref "ix86_attr_length_address_default (insn)")))
391
392 ;; Set when length prefix is used.
393 (define_attr "prefix_data16" ""
394 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
395 (const_int 0)
396 (eq_attr "mode" "HI")
397 (const_int 1)
398 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
399 (const_int 1)
400 ]
401 (const_int 0)))
402
403 ;; Set when string REP prefix is used.
404 (define_attr "prefix_rep" ""
405 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
406 (const_int 0)
407 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
408 (const_int 1)
409 ]
410 (const_int 0)))
411
412 ;; Set when 0f opcode prefix is used.
413 (define_attr "prefix_0f" ""
414 (if_then_else
415 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
416 (eq_attr "unit" "sse,mmx"))
417 (const_int 1)
418 (const_int 0)))
419
420 ;; Set when REX opcode prefix is used.
421 (define_attr "prefix_rex" ""
422 (cond [(not (match_test "TARGET_64BIT"))
423 (const_int 0)
424 (and (eq_attr "mode" "DI")
425 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
426 (eq_attr "unit" "!mmx")))
427 (const_int 1)
428 (and (eq_attr "mode" "QI")
429 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
430 (const_int 1)
431 (match_test "x86_extended_reg_mentioned_p (insn)")
432 (const_int 1)
433 (and (eq_attr "type" "imovx")
434 (match_operand:QI 1 "ext_QIreg_operand"))
435 (const_int 1)
436 ]
437 (const_int 0)))
438
439 ;; There are also additional prefixes in 3DNOW, SSSE3.
440 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
441 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
442 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
443 (define_attr "prefix_extra" ""
444 (cond [(eq_attr "type" "ssemuladd,sse4arg")
445 (const_int 2)
446 (eq_attr "type" "sseiadd1,ssecvt1")
447 (const_int 1)
448 ]
449 (const_int 0)))
450
451 ;; Prefix used: original, VEX or maybe VEX.
452 (define_attr "prefix" "orig,vex,maybe_vex"
453 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
454 (const_string "vex")
455 (const_string "orig")))
456
457 ;; VEX W bit is used.
458 (define_attr "prefix_vex_w" "" (const_int 0))
459
460 ;; The length of VEX prefix
461 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
462 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
463 ;; still prefix_0f 1, with prefix_extra 1.
464 (define_attr "length_vex" ""
465 (if_then_else (and (eq_attr "prefix_0f" "1")
466 (eq_attr "prefix_extra" "0"))
467 (if_then_else (eq_attr "prefix_vex_w" "1")
468 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
469 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
470 (if_then_else (eq_attr "prefix_vex_w" "1")
471 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
472 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
473
474 ;; Set when modrm byte is used.
475 (define_attr "modrm" ""
476 (cond [(eq_attr "type" "str,leave")
477 (const_int 0)
478 (eq_attr "unit" "i387")
479 (const_int 0)
480 (and (eq_attr "type" "incdec")
481 (and (not (match_test "TARGET_64BIT"))
482 (ior (match_operand:SI 1 "register_operand")
483 (match_operand:HI 1 "register_operand"))))
484 (const_int 0)
485 (and (eq_attr "type" "push")
486 (not (match_operand 1 "memory_operand")))
487 (const_int 0)
488 (and (eq_attr "type" "pop")
489 (not (match_operand 0 "memory_operand")))
490 (const_int 0)
491 (and (eq_attr "type" "imov")
492 (and (not (eq_attr "mode" "DI"))
493 (ior (and (match_operand 0 "register_operand")
494 (match_operand 1 "immediate_operand"))
495 (ior (and (match_operand 0 "ax_reg_operand")
496 (match_operand 1 "memory_displacement_only_operand"))
497 (and (match_operand 0 "memory_displacement_only_operand")
498 (match_operand 1 "ax_reg_operand"))))))
499 (const_int 0)
500 (and (eq_attr "type" "call")
501 (match_operand 0 "constant_call_address_operand"))
502 (const_int 0)
503 (and (eq_attr "type" "callv")
504 (match_operand 1 "constant_call_address_operand"))
505 (const_int 0)
506 (and (eq_attr "type" "alu,alu1,icmp,test")
507 (match_operand 0 "ax_reg_operand"))
508 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
509 ]
510 (const_int 1)))
511
512 ;; The (bounding maximum) length of an instruction in bytes.
513 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
514 ;; Later we may want to split them and compute proper length as for
515 ;; other insns.
516 (define_attr "length" ""
517 (cond [(eq_attr "type" "other,multi,fistp,frndint")
518 (const_int 16)
519 (eq_attr "type" "fcmp")
520 (const_int 4)
521 (eq_attr "unit" "i387")
522 (plus (const_int 2)
523 (plus (attr "prefix_data16")
524 (attr "length_address")))
525 (ior (eq_attr "prefix" "vex")
526 (and (eq_attr "prefix" "maybe_vex")
527 (match_test "TARGET_AVX")))
528 (plus (attr "length_vex")
529 (plus (attr "length_immediate")
530 (plus (attr "modrm")
531 (attr "length_address"))))]
532 (plus (plus (attr "modrm")
533 (plus (attr "prefix_0f")
534 (plus (attr "prefix_rex")
535 (plus (attr "prefix_extra")
536 (const_int 1)))))
537 (plus (attr "prefix_rep")
538 (plus (attr "prefix_data16")
539 (plus (attr "length_immediate")
540 (attr "length_address")))))))
541
542 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
543 ;; `store' if there is a simple memory reference therein, or `unknown'
544 ;; if the instruction is complex.
545
546 (define_attr "memory" "none,load,store,both,unknown"
547 (cond [(eq_attr "type" "other,multi,str,lwp")
548 (const_string "unknown")
549 (eq_attr "type" "lea,fcmov,fpspc")
550 (const_string "none")
551 (eq_attr "type" "fistp,leave")
552 (const_string "both")
553 (eq_attr "type" "frndint")
554 (const_string "load")
555 (eq_attr "type" "push")
556 (if_then_else (match_operand 1 "memory_operand")
557 (const_string "both")
558 (const_string "store"))
559 (eq_attr "type" "pop")
560 (if_then_else (match_operand 0 "memory_operand")
561 (const_string "both")
562 (const_string "load"))
563 (eq_attr "type" "setcc")
564 (if_then_else (match_operand 0 "memory_operand")
565 (const_string "store")
566 (const_string "none"))
567 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
568 (if_then_else (ior (match_operand 0 "memory_operand")
569 (match_operand 1 "memory_operand"))
570 (const_string "load")
571 (const_string "none"))
572 (eq_attr "type" "ibr")
573 (if_then_else (match_operand 0 "memory_operand")
574 (const_string "load")
575 (const_string "none"))
576 (eq_attr "type" "call")
577 (if_then_else (match_operand 0 "constant_call_address_operand")
578 (const_string "none")
579 (const_string "load"))
580 (eq_attr "type" "callv")
581 (if_then_else (match_operand 1 "constant_call_address_operand")
582 (const_string "none")
583 (const_string "load"))
584 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
585 (match_operand 1 "memory_operand"))
586 (const_string "both")
587 (and (match_operand 0 "memory_operand")
588 (match_operand 1 "memory_operand"))
589 (const_string "both")
590 (match_operand 0 "memory_operand")
591 (const_string "store")
592 (match_operand 1 "memory_operand")
593 (const_string "load")
594 (and (eq_attr "type"
595 "!alu1,negnot,ishift1,
596 imov,imovx,icmp,test,bitmanip,
597 fmov,fcmp,fsgn,
598 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
599 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
600 (match_operand 2 "memory_operand"))
601 (const_string "load")
602 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
603 (match_operand 3 "memory_operand"))
604 (const_string "load")
605 ]
606 (const_string "none")))
607
608 ;; Indicates if an instruction has both an immediate and a displacement.
609
610 (define_attr "imm_disp" "false,true,unknown"
611 (cond [(eq_attr "type" "other,multi")
612 (const_string "unknown")
613 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
614 (and (match_operand 0 "memory_displacement_operand")
615 (match_operand 1 "immediate_operand")))
616 (const_string "true")
617 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
618 (and (match_operand 0 "memory_displacement_operand")
619 (match_operand 2 "immediate_operand")))
620 (const_string "true")
621 ]
622 (const_string "false")))
623
624 ;; Indicates if an FP operation has an integer source.
625
626 (define_attr "fp_int_src" "false,true"
627 (const_string "false"))
628
629 ;; Defines rounding mode of an FP operation.
630
631 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
632 (const_string "any"))
633
634 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
635 (define_attr "use_carry" "0,1" (const_string "0"))
636
637 ;; Define attribute to indicate unaligned ssemov insns
638 (define_attr "movu" "0,1" (const_string "0"))
639
640 ;; Used to control the "enabled" attribute on a per-instruction basis.
641 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,avx2,noavx2,bmi2"
642 (const_string "base"))
643
644 (define_attr "enabled" ""
645 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
646 (eq_attr "isa" "sse2_noavx")
647 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
648 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
649 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
650 (eq_attr "isa" "sse4_noavx")
651 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
652 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
653 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
654 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
655 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
656 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
657 ]
658 (const_int 1)))
659
660 ;; Describe a user's asm statement.
661 (define_asm_attributes
662 [(set_attr "length" "128")
663 (set_attr "type" "multi")])
664
665 (define_code_iterator plusminus [plus minus])
666
667 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
668
669 ;; Base name for define_insn
670 (define_code_attr plusminus_insn
671 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
672 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
673
674 ;; Base name for insn mnemonic.
675 (define_code_attr plusminus_mnemonic
676 [(plus "add") (ss_plus "adds") (us_plus "addus")
677 (minus "sub") (ss_minus "subs") (us_minus "subus")])
678 (define_code_attr plusminus_carry_mnemonic
679 [(plus "adc") (minus "sbb")])
680
681 ;; Mark commutative operators as such in constraints.
682 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
683 (minus "") (ss_minus "") (us_minus "")])
684
685 ;; Mapping of max and min
686 (define_code_iterator maxmin [smax smin umax umin])
687
688 ;; Mapping of signed max and min
689 (define_code_iterator smaxmin [smax smin])
690
691 ;; Mapping of unsigned max and min
692 (define_code_iterator umaxmin [umax umin])
693
694 ;; Base name for integer and FP insn mnemonic
695 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
696 (umax "maxu") (umin "minu")])
697 (define_code_attr maxmin_float [(smax "max") (smin "min")])
698
699 ;; Mapping of logic operators
700 (define_code_iterator any_logic [and ior xor])
701 (define_code_iterator any_or [ior xor])
702
703 ;; Base name for insn mnemonic.
704 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
705
706 ;; Mapping of logic-shift operators
707 (define_code_iterator any_lshift [ashift lshiftrt])
708
709 ;; Mapping of shift-right operators
710 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
711
712 ;; Mapping of all shift operators
713 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
714
715 ;; Base name for define_insn
716 (define_code_attr shift_insn
717 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
718
719 ;; Base name for insn mnemonic.
720 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
721 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
722
723 ;; Mapping of rotate operators
724 (define_code_iterator any_rotate [rotate rotatert])
725
726 ;; Base name for define_insn
727 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
728
729 ;; Base name for insn mnemonic.
730 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
731
732 ;; Mapping of abs neg operators
733 (define_code_iterator absneg [abs neg])
734
735 ;; Base name for x87 insn mnemonic.
736 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
737
738 ;; Used in signed and unsigned widening multiplications.
739 (define_code_iterator any_extend [sign_extend zero_extend])
740
741 ;; Prefix for insn menmonic.
742 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
743
744 ;; Prefix for define_insn
745 (define_code_attr u [(sign_extend "") (zero_extend "u")])
746 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
747
748 ;; All integer modes.
749 (define_mode_iterator SWI1248x [QI HI SI DI])
750
751 ;; All integer modes without QImode.
752 (define_mode_iterator SWI248x [HI SI DI])
753
754 ;; All integer modes without QImode and HImode.
755 (define_mode_iterator SWI48x [SI DI])
756
757 ;; All integer modes without SImode and DImode.
758 (define_mode_iterator SWI12 [QI HI])
759
760 ;; All integer modes without DImode.
761 (define_mode_iterator SWI124 [QI HI SI])
762
763 ;; All integer modes without QImode and DImode.
764 (define_mode_iterator SWI24 [HI SI])
765
766 ;; Single word integer modes.
767 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
768
769 ;; Single word integer modes without QImode.
770 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
771
772 ;; Single word integer modes without QImode and HImode.
773 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
774
775 ;; All math-dependant single and double word integer modes.
776 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
777 (HI "TARGET_HIMODE_MATH")
778 SI DI (TI "TARGET_64BIT")])
779
780 ;; Math-dependant single word integer modes.
781 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
782 (HI "TARGET_HIMODE_MATH")
783 SI (DI "TARGET_64BIT")])
784
785 ;; Math-dependant integer modes without DImode.
786 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
787 (HI "TARGET_HIMODE_MATH")
788 SI])
789
790 ;; Math-dependant single word integer modes without QImode.
791 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
792 SI (DI "TARGET_64BIT")])
793
794 ;; Double word integer modes.
795 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
796 (TI "TARGET_64BIT")])
797
798 ;; Double word integer modes as mode attribute.
799 (define_mode_attr DWI [(SI "DI") (DI "TI")])
800 (define_mode_attr dwi [(SI "di") (DI "ti")])
801
802 ;; Half mode for double word integer modes.
803 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
804 (DI "TARGET_64BIT")])
805
806 ;; Instruction suffix for integer modes.
807 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
808
809 ;; Pointer size prefix for integer modes (Intel asm dialect)
810 (define_mode_attr iptrsize [(QI "BYTE")
811 (HI "WORD")
812 (SI "DWORD")
813 (DI "QWORD")])
814
815 ;; Register class for integer modes.
816 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
817
818 ;; Immediate operand constraint for integer modes.
819 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
820
821 ;; General operand constraint for word modes.
822 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
823
824 ;; Immediate operand constraint for double integer modes.
825 (define_mode_attr di [(SI "nF") (DI "e")])
826
827 ;; Immediate operand constraint for shifts.
828 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
829
830 ;; General operand predicate for integer modes.
831 (define_mode_attr general_operand
832 [(QI "general_operand")
833 (HI "general_operand")
834 (SI "x86_64_general_operand")
835 (DI "x86_64_general_operand")
836 (TI "x86_64_general_operand")])
837
838 ;; General sign/zero extend operand predicate for integer modes.
839 (define_mode_attr general_szext_operand
840 [(QI "general_operand")
841 (HI "general_operand")
842 (SI "x86_64_szext_general_operand")
843 (DI "x86_64_szext_general_operand")])
844
845 ;; Immediate operand predicate for integer modes.
846 (define_mode_attr immediate_operand
847 [(QI "immediate_operand")
848 (HI "immediate_operand")
849 (SI "x86_64_immediate_operand")
850 (DI "x86_64_immediate_operand")])
851
852 ;; Nonmemory operand predicate for integer modes.
853 (define_mode_attr nonmemory_operand
854 [(QI "nonmemory_operand")
855 (HI "nonmemory_operand")
856 (SI "x86_64_nonmemory_operand")
857 (DI "x86_64_nonmemory_operand")])
858
859 ;; Operand predicate for shifts.
860 (define_mode_attr shift_operand
861 [(QI "nonimmediate_operand")
862 (HI "nonimmediate_operand")
863 (SI "nonimmediate_operand")
864 (DI "shiftdi_operand")
865 (TI "register_operand")])
866
867 ;; Operand predicate for shift argument.
868 (define_mode_attr shift_immediate_operand
869 [(QI "const_1_to_31_operand")
870 (HI "const_1_to_31_operand")
871 (SI "const_1_to_31_operand")
872 (DI "const_1_to_63_operand")])
873
874 ;; Input operand predicate for arithmetic left shifts.
875 (define_mode_attr ashl_input_operand
876 [(QI "nonimmediate_operand")
877 (HI "nonimmediate_operand")
878 (SI "nonimmediate_operand")
879 (DI "ashldi_input_operand")
880 (TI "reg_or_pm1_operand")])
881
882 ;; SSE and x87 SFmode and DFmode floating point modes
883 (define_mode_iterator MODEF [SF DF])
884
885 ;; All x87 floating point modes
886 (define_mode_iterator X87MODEF [SF DF XF])
887
888 ;; SSE instruction suffix for various modes
889 (define_mode_attr ssemodesuffix
890 [(SF "ss") (DF "sd")
891 (V8SF "ps") (V4DF "pd")
892 (V4SF "ps") (V2DF "pd")
893 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
894 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
895
896 ;; SSE vector suffix for floating point modes
897 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
898
899 ;; SSE vector mode corresponding to a scalar mode
900 (define_mode_attr ssevecmode
901 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
902
903 ;; Instruction suffix for REX 64bit operators.
904 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
905
906 ;; This mode iterator allows :P to be used for patterns that operate on
907 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
908 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
909
910 ;; This mode iterator allows :W to be used for patterns that operate on
911 ;; word_mode sized quantities.
912 (define_mode_iterator W
913 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
914
915 ;; This mode iterator allows :PTR to be used for patterns that operate on
916 ;; ptr_mode sized quantities.
917 (define_mode_iterator PTR
918 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
919 \f
920 ;; Scheduling descriptions
921
922 (include "pentium.md")
923 (include "ppro.md")
924 (include "k6.md")
925 (include "athlon.md")
926 (include "bdver1.md")
927 (include "geode.md")
928 (include "atom.md")
929 (include "core2.md")
930
931 \f
932 ;; Operand and operator predicates and constraints
933
934 (include "predicates.md")
935 (include "constraints.md")
936
937 \f
938 ;; Compare and branch/compare and store instructions.
939
940 (define_expand "cbranch<mode>4"
941 [(set (reg:CC FLAGS_REG)
942 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
943 (match_operand:SDWIM 2 "<general_operand>")))
944 (set (pc) (if_then_else
945 (match_operator 0 "ordered_comparison_operator"
946 [(reg:CC FLAGS_REG) (const_int 0)])
947 (label_ref (match_operand 3))
948 (pc)))]
949 ""
950 {
951 if (MEM_P (operands[1]) && MEM_P (operands[2]))
952 operands[1] = force_reg (<MODE>mode, operands[1]);
953 ix86_expand_branch (GET_CODE (operands[0]),
954 operands[1], operands[2], operands[3]);
955 DONE;
956 })
957
958 (define_expand "cstore<mode>4"
959 [(set (reg:CC FLAGS_REG)
960 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
961 (match_operand:SWIM 3 "<general_operand>")))
962 (set (match_operand:QI 0 "register_operand")
963 (match_operator 1 "ordered_comparison_operator"
964 [(reg:CC FLAGS_REG) (const_int 0)]))]
965 ""
966 {
967 if (MEM_P (operands[2]) && MEM_P (operands[3]))
968 operands[2] = force_reg (<MODE>mode, operands[2]);
969 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
970 operands[2], operands[3]);
971 DONE;
972 })
973
974 (define_expand "cmp<mode>_1"
975 [(set (reg:CC FLAGS_REG)
976 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
977 (match_operand:SWI48 1 "<general_operand>")))])
978
979 (define_insn "*cmp<mode>_ccno_1"
980 [(set (reg FLAGS_REG)
981 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
982 (match_operand:SWI 1 "const0_operand")))]
983 "ix86_match_ccmode (insn, CCNOmode)"
984 "@
985 test{<imodesuffix>}\t%0, %0
986 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
987 [(set_attr "type" "test,icmp")
988 (set_attr "length_immediate" "0,1")
989 (set_attr "mode" "<MODE>")])
990
991 (define_insn "*cmp<mode>_1"
992 [(set (reg FLAGS_REG)
993 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
994 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
995 "ix86_match_ccmode (insn, CCmode)"
996 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
997 [(set_attr "type" "icmp")
998 (set_attr "mode" "<MODE>")])
999
1000 (define_insn "*cmp<mode>_minus_1"
1001 [(set (reg FLAGS_REG)
1002 (compare
1003 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1004 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1005 (const_int 0)))]
1006 "ix86_match_ccmode (insn, CCGOCmode)"
1007 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1008 [(set_attr "type" "icmp")
1009 (set_attr "mode" "<MODE>")])
1010
1011 (define_insn "*cmpqi_ext_1"
1012 [(set (reg FLAGS_REG)
1013 (compare
1014 (match_operand:QI 0 "general_operand" "Qm")
1015 (subreg:QI
1016 (zero_extract:SI
1017 (match_operand 1 "ext_register_operand" "Q")
1018 (const_int 8)
1019 (const_int 8)) 0)))]
1020 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1021 "cmp{b}\t{%h1, %0|%0, %h1}"
1022 [(set_attr "type" "icmp")
1023 (set_attr "mode" "QI")])
1024
1025 (define_insn "*cmpqi_ext_1_rex64"
1026 [(set (reg FLAGS_REG)
1027 (compare
1028 (match_operand:QI 0 "register_operand" "Q")
1029 (subreg:QI
1030 (zero_extract:SI
1031 (match_operand 1 "ext_register_operand" "Q")
1032 (const_int 8)
1033 (const_int 8)) 0)))]
1034 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1035 "cmp{b}\t{%h1, %0|%0, %h1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "QI")])
1038
1039 (define_insn "*cmpqi_ext_2"
1040 [(set (reg FLAGS_REG)
1041 (compare
1042 (subreg:QI
1043 (zero_extract:SI
1044 (match_operand 0 "ext_register_operand" "Q")
1045 (const_int 8)
1046 (const_int 8)) 0)
1047 (match_operand:QI 1 "const0_operand")))]
1048 "ix86_match_ccmode (insn, CCNOmode)"
1049 "test{b}\t%h0, %h0"
1050 [(set_attr "type" "test")
1051 (set_attr "length_immediate" "0")
1052 (set_attr "mode" "QI")])
1053
1054 (define_expand "cmpqi_ext_3"
1055 [(set (reg:CC FLAGS_REG)
1056 (compare:CC
1057 (subreg:QI
1058 (zero_extract:SI
1059 (match_operand 0 "ext_register_operand")
1060 (const_int 8)
1061 (const_int 8)) 0)
1062 (match_operand:QI 1 "immediate_operand")))])
1063
1064 (define_insn "*cmpqi_ext_3_insn"
1065 [(set (reg FLAGS_REG)
1066 (compare
1067 (subreg:QI
1068 (zero_extract:SI
1069 (match_operand 0 "ext_register_operand" "Q")
1070 (const_int 8)
1071 (const_int 8)) 0)
1072 (match_operand:QI 1 "general_operand" "Qmn")))]
1073 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1074 "cmp{b}\t{%1, %h0|%h0, %1}"
1075 [(set_attr "type" "icmp")
1076 (set_attr "modrm" "1")
1077 (set_attr "mode" "QI")])
1078
1079 (define_insn "*cmpqi_ext_3_insn_rex64"
1080 [(set (reg FLAGS_REG)
1081 (compare
1082 (subreg:QI
1083 (zero_extract:SI
1084 (match_operand 0 "ext_register_operand" "Q")
1085 (const_int 8)
1086 (const_int 8)) 0)
1087 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1088 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1089 "cmp{b}\t{%1, %h0|%h0, %1}"
1090 [(set_attr "type" "icmp")
1091 (set_attr "modrm" "1")
1092 (set_attr "mode" "QI")])
1093
1094 (define_insn "*cmpqi_ext_4"
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 (subreg:QI
1103 (zero_extract:SI
1104 (match_operand 1 "ext_register_operand" "Q")
1105 (const_int 8)
1106 (const_int 8)) 0)))]
1107 "ix86_match_ccmode (insn, CCmode)"
1108 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1109 [(set_attr "type" "icmp")
1110 (set_attr "mode" "QI")])
1111
1112 ;; These implement float point compares.
1113 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1114 ;; which would allow mix and match FP modes on the compares. Which is what
1115 ;; the old patterns did, but with many more of them.
1116
1117 (define_expand "cbranchxf4"
1118 [(set (reg:CC FLAGS_REG)
1119 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1120 (match_operand:XF 2 "nonmemory_operand")))
1121 (set (pc) (if_then_else
1122 (match_operator 0 "ix86_fp_comparison_operator"
1123 [(reg:CC FLAGS_REG)
1124 (const_int 0)])
1125 (label_ref (match_operand 3))
1126 (pc)))]
1127 "TARGET_80387"
1128 {
1129 ix86_expand_branch (GET_CODE (operands[0]),
1130 operands[1], operands[2], operands[3]);
1131 DONE;
1132 })
1133
1134 (define_expand "cstorexf4"
1135 [(set (reg:CC FLAGS_REG)
1136 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1137 (match_operand:XF 3 "nonmemory_operand")))
1138 (set (match_operand:QI 0 "register_operand")
1139 (match_operator 1 "ix86_fp_comparison_operator"
1140 [(reg:CC FLAGS_REG)
1141 (const_int 0)]))]
1142 "TARGET_80387"
1143 {
1144 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1145 operands[2], operands[3]);
1146 DONE;
1147 })
1148
1149 (define_expand "cbranch<mode>4"
1150 [(set (reg:CC FLAGS_REG)
1151 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1152 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1153 (set (pc) (if_then_else
1154 (match_operator 0 "ix86_fp_comparison_operator"
1155 [(reg:CC FLAGS_REG)
1156 (const_int 0)])
1157 (label_ref (match_operand 3))
1158 (pc)))]
1159 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1160 {
1161 ix86_expand_branch (GET_CODE (operands[0]),
1162 operands[1], operands[2], operands[3]);
1163 DONE;
1164 })
1165
1166 (define_expand "cstore<mode>4"
1167 [(set (reg:CC FLAGS_REG)
1168 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1169 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1170 (set (match_operand:QI 0 "register_operand")
1171 (match_operator 1 "ix86_fp_comparison_operator"
1172 [(reg:CC FLAGS_REG)
1173 (const_int 0)]))]
1174 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1175 {
1176 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1177 operands[2], operands[3]);
1178 DONE;
1179 })
1180
1181 (define_expand "cbranchcc4"
1182 [(set (pc) (if_then_else
1183 (match_operator 0 "comparison_operator"
1184 [(match_operand 1 "flags_reg_operand")
1185 (match_operand 2 "const0_operand")])
1186 (label_ref (match_operand 3))
1187 (pc)))]
1188 ""
1189 {
1190 ix86_expand_branch (GET_CODE (operands[0]),
1191 operands[1], operands[2], operands[3]);
1192 DONE;
1193 })
1194
1195 (define_expand "cstorecc4"
1196 [(set (match_operand:QI 0 "register_operand")
1197 (match_operator 1 "comparison_operator"
1198 [(match_operand 2 "flags_reg_operand")
1199 (match_operand 3 "const0_operand")]))]
1200 ""
1201 {
1202 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1203 operands[2], operands[3]);
1204 DONE;
1205 })
1206
1207
1208 ;; FP compares, step 1:
1209 ;; Set the FP condition codes.
1210 ;;
1211 ;; CCFPmode compare with exceptions
1212 ;; CCFPUmode compare with no exceptions
1213
1214 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1215 ;; used to manage the reg stack popping would not be preserved.
1216
1217 (define_insn "*cmpfp_0"
1218 [(set (match_operand:HI 0 "register_operand" "=a")
1219 (unspec:HI
1220 [(compare:CCFP
1221 (match_operand 1 "register_operand" "f")
1222 (match_operand 2 "const0_operand"))]
1223 UNSPEC_FNSTSW))]
1224 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1225 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1226 "* return output_fp_compare (insn, operands, false, false);"
1227 [(set_attr "type" "multi")
1228 (set_attr "unit" "i387")
1229 (set (attr "mode")
1230 (cond [(match_operand:SF 1)
1231 (const_string "SF")
1232 (match_operand:DF 1)
1233 (const_string "DF")
1234 ]
1235 (const_string "XF")))])
1236
1237 (define_insn_and_split "*cmpfp_0_cc"
1238 [(set (reg:CCFP FLAGS_REG)
1239 (compare:CCFP
1240 (match_operand 1 "register_operand" "f")
1241 (match_operand 2 "const0_operand")))
1242 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1243 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1244 && TARGET_SAHF && !TARGET_CMOVE
1245 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1246 "#"
1247 "&& reload_completed"
1248 [(set (match_dup 0)
1249 (unspec:HI
1250 [(compare:CCFP (match_dup 1)(match_dup 2))]
1251 UNSPEC_FNSTSW))
1252 (set (reg:CC FLAGS_REG)
1253 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1254 ""
1255 [(set_attr "type" "multi")
1256 (set_attr "unit" "i387")
1257 (set (attr "mode")
1258 (cond [(match_operand:SF 1)
1259 (const_string "SF")
1260 (match_operand:DF 1)
1261 (const_string "DF")
1262 ]
1263 (const_string "XF")))])
1264
1265 (define_insn "*cmpfp_xf"
1266 [(set (match_operand:HI 0 "register_operand" "=a")
1267 (unspec:HI
1268 [(compare:CCFP
1269 (match_operand:XF 1 "register_operand" "f")
1270 (match_operand:XF 2 "register_operand" "f"))]
1271 UNSPEC_FNSTSW))]
1272 "TARGET_80387"
1273 "* return output_fp_compare (insn, operands, false, false);"
1274 [(set_attr "type" "multi")
1275 (set_attr "unit" "i387")
1276 (set_attr "mode" "XF")])
1277
1278 (define_insn_and_split "*cmpfp_xf_cc"
1279 [(set (reg:CCFP FLAGS_REG)
1280 (compare:CCFP
1281 (match_operand:XF 1 "register_operand" "f")
1282 (match_operand:XF 2 "register_operand" "f")))
1283 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1284 "TARGET_80387
1285 && TARGET_SAHF && !TARGET_CMOVE"
1286 "#"
1287 "&& reload_completed"
1288 [(set (match_dup 0)
1289 (unspec:HI
1290 [(compare:CCFP (match_dup 1)(match_dup 2))]
1291 UNSPEC_FNSTSW))
1292 (set (reg:CC FLAGS_REG)
1293 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1294 ""
1295 [(set_attr "type" "multi")
1296 (set_attr "unit" "i387")
1297 (set_attr "mode" "XF")])
1298
1299 (define_insn "*cmpfp_<mode>"
1300 [(set (match_operand:HI 0 "register_operand" "=a")
1301 (unspec:HI
1302 [(compare:CCFP
1303 (match_operand:MODEF 1 "register_operand" "f")
1304 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1305 UNSPEC_FNSTSW))]
1306 "TARGET_80387"
1307 "* return output_fp_compare (insn, operands, false, false);"
1308 [(set_attr "type" "multi")
1309 (set_attr "unit" "i387")
1310 (set_attr "mode" "<MODE>")])
1311
1312 (define_insn_and_split "*cmpfp_<mode>_cc"
1313 [(set (reg:CCFP FLAGS_REG)
1314 (compare:CCFP
1315 (match_operand:MODEF 1 "register_operand" "f")
1316 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1317 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1318 "TARGET_80387
1319 && TARGET_SAHF && !TARGET_CMOVE"
1320 "#"
1321 "&& reload_completed"
1322 [(set (match_dup 0)
1323 (unspec:HI
1324 [(compare:CCFP (match_dup 1)(match_dup 2))]
1325 UNSPEC_FNSTSW))
1326 (set (reg:CC FLAGS_REG)
1327 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1328 ""
1329 [(set_attr "type" "multi")
1330 (set_attr "unit" "i387")
1331 (set_attr "mode" "<MODE>")])
1332
1333 (define_insn "*cmpfp_u"
1334 [(set (match_operand:HI 0 "register_operand" "=a")
1335 (unspec:HI
1336 [(compare:CCFPU
1337 (match_operand 1 "register_operand" "f")
1338 (match_operand 2 "register_operand" "f"))]
1339 UNSPEC_FNSTSW))]
1340 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1341 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1342 "* return output_fp_compare (insn, operands, false, true);"
1343 [(set_attr "type" "multi")
1344 (set_attr "unit" "i387")
1345 (set (attr "mode")
1346 (cond [(match_operand:SF 1)
1347 (const_string "SF")
1348 (match_operand:DF 1)
1349 (const_string "DF")
1350 ]
1351 (const_string "XF")))])
1352
1353 (define_insn_and_split "*cmpfp_u_cc"
1354 [(set (reg:CCFPU FLAGS_REG)
1355 (compare:CCFPU
1356 (match_operand 1 "register_operand" "f")
1357 (match_operand 2 "register_operand" "f")))
1358 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1359 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1360 && TARGET_SAHF && !TARGET_CMOVE
1361 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1362 "#"
1363 "&& reload_completed"
1364 [(set (match_dup 0)
1365 (unspec:HI
1366 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1367 UNSPEC_FNSTSW))
1368 (set (reg:CC FLAGS_REG)
1369 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1370 ""
1371 [(set_attr "type" "multi")
1372 (set_attr "unit" "i387")
1373 (set (attr "mode")
1374 (cond [(match_operand:SF 1)
1375 (const_string "SF")
1376 (match_operand:DF 1)
1377 (const_string "DF")
1378 ]
1379 (const_string "XF")))])
1380
1381 (define_insn "*cmpfp_<mode>"
1382 [(set (match_operand:HI 0 "register_operand" "=a")
1383 (unspec:HI
1384 [(compare:CCFP
1385 (match_operand 1 "register_operand" "f")
1386 (match_operator 3 "float_operator"
1387 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1388 UNSPEC_FNSTSW))]
1389 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1390 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1391 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1392 "* return output_fp_compare (insn, operands, false, false);"
1393 [(set_attr "type" "multi")
1394 (set_attr "unit" "i387")
1395 (set_attr "fp_int_src" "true")
1396 (set_attr "mode" "<MODE>")])
1397
1398 (define_insn_and_split "*cmpfp_<mode>_cc"
1399 [(set (reg:CCFP FLAGS_REG)
1400 (compare:CCFP
1401 (match_operand 1 "register_operand" "f")
1402 (match_operator 3 "float_operator"
1403 [(match_operand:SWI24 2 "memory_operand" "m")])))
1404 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1405 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1406 && TARGET_SAHF && !TARGET_CMOVE
1407 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1408 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1409 "#"
1410 "&& reload_completed"
1411 [(set (match_dup 0)
1412 (unspec:HI
1413 [(compare:CCFP
1414 (match_dup 1)
1415 (match_op_dup 3 [(match_dup 2)]))]
1416 UNSPEC_FNSTSW))
1417 (set (reg:CC FLAGS_REG)
1418 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1419 ""
1420 [(set_attr "type" "multi")
1421 (set_attr "unit" "i387")
1422 (set_attr "fp_int_src" "true")
1423 (set_attr "mode" "<MODE>")])
1424
1425 ;; FP compares, step 2
1426 ;; Move the fpsw to ax.
1427
1428 (define_insn "x86_fnstsw_1"
1429 [(set (match_operand:HI 0 "register_operand" "=a")
1430 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1431 "TARGET_80387"
1432 "fnstsw\t%0"
1433 [(set (attr "length")
1434 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1435 (set_attr "mode" "SI")
1436 (set_attr "unit" "i387")])
1437
1438 ;; FP compares, step 3
1439 ;; Get ax into flags, general case.
1440
1441 (define_insn "x86_sahf_1"
1442 [(set (reg:CC FLAGS_REG)
1443 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1444 UNSPEC_SAHF))]
1445 "TARGET_SAHF"
1446 {
1447 #ifndef HAVE_AS_IX86_SAHF
1448 if (TARGET_64BIT)
1449 return ASM_BYTE "0x9e";
1450 else
1451 #endif
1452 return "sahf";
1453 }
1454 [(set_attr "length" "1")
1455 (set_attr "athlon_decode" "vector")
1456 (set_attr "amdfam10_decode" "direct")
1457 (set_attr "bdver1_decode" "direct")
1458 (set_attr "mode" "SI")])
1459
1460 ;; Pentium Pro can do steps 1 through 3 in one go.
1461 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1462 ;; (these i387 instructions set flags directly)
1463 (define_insn "*cmpfp_i_mixed"
1464 [(set (reg:CCFP FLAGS_REG)
1465 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1466 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1467 "TARGET_MIX_SSE_I387
1468 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1469 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1470 "* return output_fp_compare (insn, operands, true, false);"
1471 [(set_attr "type" "fcmp,ssecomi")
1472 (set_attr "prefix" "orig,maybe_vex")
1473 (set (attr "mode")
1474 (if_then_else (match_operand:SF 1)
1475 (const_string "SF")
1476 (const_string "DF")))
1477 (set (attr "prefix_rep")
1478 (if_then_else (eq_attr "type" "ssecomi")
1479 (const_string "0")
1480 (const_string "*")))
1481 (set (attr "prefix_data16")
1482 (cond [(eq_attr "type" "fcmp")
1483 (const_string "*")
1484 (eq_attr "mode" "DF")
1485 (const_string "1")
1486 ]
1487 (const_string "0")))
1488 (set_attr "athlon_decode" "vector")
1489 (set_attr "amdfam10_decode" "direct")
1490 (set_attr "bdver1_decode" "double")])
1491
1492 (define_insn "*cmpfp_i_sse"
1493 [(set (reg:CCFP FLAGS_REG)
1494 (compare:CCFP (match_operand 0 "register_operand" "x")
1495 (match_operand 1 "nonimmediate_operand" "xm")))]
1496 "TARGET_SSE_MATH
1497 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1498 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1499 "* return output_fp_compare (insn, operands, true, false);"
1500 [(set_attr "type" "ssecomi")
1501 (set_attr "prefix" "maybe_vex")
1502 (set (attr "mode")
1503 (if_then_else (match_operand:SF 1)
1504 (const_string "SF")
1505 (const_string "DF")))
1506 (set_attr "prefix_rep" "0")
1507 (set (attr "prefix_data16")
1508 (if_then_else (eq_attr "mode" "DF")
1509 (const_string "1")
1510 (const_string "0")))
1511 (set_attr "athlon_decode" "vector")
1512 (set_attr "amdfam10_decode" "direct")
1513 (set_attr "bdver1_decode" "double")])
1514
1515 (define_insn "*cmpfp_i_i387"
1516 [(set (reg:CCFP FLAGS_REG)
1517 (compare:CCFP (match_operand 0 "register_operand" "f")
1518 (match_operand 1 "register_operand" "f")))]
1519 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1520 && TARGET_CMOVE
1521 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1522 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1523 "* return output_fp_compare (insn, operands, true, false);"
1524 [(set_attr "type" "fcmp")
1525 (set (attr "mode")
1526 (cond [(match_operand:SF 1)
1527 (const_string "SF")
1528 (match_operand:DF 1)
1529 (const_string "DF")
1530 ]
1531 (const_string "XF")))
1532 (set_attr "athlon_decode" "vector")
1533 (set_attr "amdfam10_decode" "direct")
1534 (set_attr "bdver1_decode" "double")])
1535
1536 (define_insn "*cmpfp_iu_mixed"
1537 [(set (reg:CCFPU FLAGS_REG)
1538 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1539 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1540 "TARGET_MIX_SSE_I387
1541 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1542 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1543 "* return output_fp_compare (insn, operands, true, true);"
1544 [(set_attr "type" "fcmp,ssecomi")
1545 (set_attr "prefix" "orig,maybe_vex")
1546 (set (attr "mode")
1547 (if_then_else (match_operand:SF 1)
1548 (const_string "SF")
1549 (const_string "DF")))
1550 (set (attr "prefix_rep")
1551 (if_then_else (eq_attr "type" "ssecomi")
1552 (const_string "0")
1553 (const_string "*")))
1554 (set (attr "prefix_data16")
1555 (cond [(eq_attr "type" "fcmp")
1556 (const_string "*")
1557 (eq_attr "mode" "DF")
1558 (const_string "1")
1559 ]
1560 (const_string "0")))
1561 (set_attr "athlon_decode" "vector")
1562 (set_attr "amdfam10_decode" "direct")
1563 (set_attr "bdver1_decode" "double")])
1564
1565 (define_insn "*cmpfp_iu_sse"
1566 [(set (reg:CCFPU FLAGS_REG)
1567 (compare:CCFPU (match_operand 0 "register_operand" "x")
1568 (match_operand 1 "nonimmediate_operand" "xm")))]
1569 "TARGET_SSE_MATH
1570 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1571 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1572 "* return output_fp_compare (insn, operands, true, true);"
1573 [(set_attr "type" "ssecomi")
1574 (set_attr "prefix" "maybe_vex")
1575 (set (attr "mode")
1576 (if_then_else (match_operand:SF 1)
1577 (const_string "SF")
1578 (const_string "DF")))
1579 (set_attr "prefix_rep" "0")
1580 (set (attr "prefix_data16")
1581 (if_then_else (eq_attr "mode" "DF")
1582 (const_string "1")
1583 (const_string "0")))
1584 (set_attr "athlon_decode" "vector")
1585 (set_attr "amdfam10_decode" "direct")
1586 (set_attr "bdver1_decode" "double")])
1587
1588 (define_insn "*cmpfp_iu_387"
1589 [(set (reg:CCFPU FLAGS_REG)
1590 (compare:CCFPU (match_operand 0 "register_operand" "f")
1591 (match_operand 1 "register_operand" "f")))]
1592 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1593 && TARGET_CMOVE
1594 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1595 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1596 "* return output_fp_compare (insn, operands, true, true);"
1597 [(set_attr "type" "fcmp")
1598 (set (attr "mode")
1599 (cond [(match_operand:SF 1)
1600 (const_string "SF")
1601 (match_operand:DF 1)
1602 (const_string "DF")
1603 ]
1604 (const_string "XF")))
1605 (set_attr "athlon_decode" "vector")
1606 (set_attr "amdfam10_decode" "direct")
1607 (set_attr "bdver1_decode" "direct")])
1608 \f
1609 ;; Push/pop instructions.
1610
1611 (define_insn "*push<mode>2"
1612 [(set (match_operand:DWI 0 "push_operand" "=<")
1613 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1614 ""
1615 "#"
1616 [(set_attr "type" "multi")
1617 (set_attr "mode" "<MODE>")])
1618
1619 (define_split
1620 [(set (match_operand:TI 0 "push_operand")
1621 (match_operand:TI 1 "general_operand"))]
1622 "TARGET_64BIT && reload_completed
1623 && !SSE_REG_P (operands[1])"
1624 [(const_int 0)]
1625 "ix86_split_long_move (operands); DONE;")
1626
1627 (define_insn "*pushdi2_rex64"
1628 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1629 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1630 "TARGET_64BIT"
1631 "@
1632 push{q}\t%1
1633 #"
1634 [(set_attr "type" "push,multi")
1635 (set_attr "mode" "DI")])
1636
1637 ;; Convert impossible pushes of immediate to existing instructions.
1638 ;; First try to get scratch register and go through it. In case this
1639 ;; fails, push sign extended lower part first and then overwrite
1640 ;; upper part by 32bit move.
1641 (define_peephole2
1642 [(match_scratch:DI 2 "r")
1643 (set (match_operand:DI 0 "push_operand")
1644 (match_operand:DI 1 "immediate_operand"))]
1645 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1646 && !x86_64_immediate_operand (operands[1], DImode)"
1647 [(set (match_dup 2) (match_dup 1))
1648 (set (match_dup 0) (match_dup 2))])
1649
1650 ;; We need to define this as both peepholer and splitter for case
1651 ;; peephole2 pass is not run.
1652 ;; "&& 1" is needed to keep it from matching the previous pattern.
1653 (define_peephole2
1654 [(set (match_operand:DI 0 "push_operand")
1655 (match_operand:DI 1 "immediate_operand"))]
1656 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1657 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1658 [(set (match_dup 0) (match_dup 1))
1659 (set (match_dup 2) (match_dup 3))]
1660 {
1661 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1662
1663 operands[1] = gen_lowpart (DImode, operands[2]);
1664 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1665 GEN_INT (4)));
1666 })
1667
1668 (define_split
1669 [(set (match_operand:DI 0 "push_operand")
1670 (match_operand:DI 1 "immediate_operand"))]
1671 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1672 ? epilogue_completed : reload_completed)
1673 && !symbolic_operand (operands[1], DImode)
1674 && !x86_64_immediate_operand (operands[1], DImode)"
1675 [(set (match_dup 0) (match_dup 1))
1676 (set (match_dup 2) (match_dup 3))]
1677 {
1678 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1679
1680 operands[1] = gen_lowpart (DImode, operands[2]);
1681 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1682 GEN_INT (4)));
1683 })
1684
1685 (define_split
1686 [(set (match_operand:DI 0 "push_operand")
1687 (match_operand:DI 1 "general_operand"))]
1688 "!TARGET_64BIT && reload_completed
1689 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1690 [(const_int 0)]
1691 "ix86_split_long_move (operands); DONE;")
1692
1693 (define_insn "*pushsi2"
1694 [(set (match_operand:SI 0 "push_operand" "=<")
1695 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1696 "!TARGET_64BIT"
1697 "push{l}\t%1"
1698 [(set_attr "type" "push")
1699 (set_attr "mode" "SI")])
1700
1701 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1702 ;; "push a byte/word". But actually we use pushl, which has the effect
1703 ;; of rounding the amount pushed up to a word.
1704
1705 ;; For TARGET_64BIT we always round up to 8 bytes.
1706 (define_insn "*push<mode>2_rex64"
1707 [(set (match_operand:SWI124 0 "push_operand" "=X")
1708 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1709 "TARGET_64BIT"
1710 "push{q}\t%q1"
1711 [(set_attr "type" "push")
1712 (set_attr "mode" "DI")])
1713
1714 (define_insn "*push<mode>2"
1715 [(set (match_operand:SWI12 0 "push_operand" "=X")
1716 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1717 "!TARGET_64BIT"
1718 "push{l}\t%k1"
1719 [(set_attr "type" "push")
1720 (set_attr "mode" "SI")])
1721
1722 (define_insn "*push<mode>2_prologue"
1723 [(set (match_operand:W 0 "push_operand" "=<")
1724 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1725 (clobber (mem:BLK (scratch)))]
1726 ""
1727 "push{<imodesuffix>}\t%1"
1728 [(set_attr "type" "push")
1729 (set_attr "mode" "<MODE>")])
1730
1731 (define_insn "*pop<mode>1"
1732 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1733 (match_operand:W 1 "pop_operand" ">"))]
1734 ""
1735 "pop{<imodesuffix>}\t%0"
1736 [(set_attr "type" "pop")
1737 (set_attr "mode" "<MODE>")])
1738
1739 (define_insn "*pop<mode>1_epilogue"
1740 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1741 (match_operand:W 1 "pop_operand" ">"))
1742 (clobber (mem:BLK (scratch)))]
1743 ""
1744 "pop{<imodesuffix>}\t%0"
1745 [(set_attr "type" "pop")
1746 (set_attr "mode" "<MODE>")])
1747 \f
1748 ;; Move instructions.
1749
1750 (define_expand "movoi"
1751 [(set (match_operand:OI 0 "nonimmediate_operand")
1752 (match_operand:OI 1 "general_operand"))]
1753 "TARGET_AVX"
1754 "ix86_expand_move (OImode, operands); DONE;")
1755
1756 (define_expand "movti"
1757 [(set (match_operand:TI 0 "nonimmediate_operand")
1758 (match_operand:TI 1 "nonimmediate_operand"))]
1759 "TARGET_64BIT || TARGET_SSE"
1760 {
1761 if (TARGET_64BIT)
1762 ix86_expand_move (TImode, operands);
1763 else if (push_operand (operands[0], TImode))
1764 ix86_expand_push (TImode, operands[1]);
1765 else
1766 ix86_expand_vector_move (TImode, operands);
1767 DONE;
1768 })
1769
1770 ;; This expands to what emit_move_complex would generate if we didn't
1771 ;; have a movti pattern. Having this avoids problems with reload on
1772 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1773 ;; to have around all the time.
1774 (define_expand "movcdi"
1775 [(set (match_operand:CDI 0 "nonimmediate_operand")
1776 (match_operand:CDI 1 "general_operand"))]
1777 ""
1778 {
1779 if (push_operand (operands[0], CDImode))
1780 emit_move_complex_push (CDImode, operands[0], operands[1]);
1781 else
1782 emit_move_complex_parts (operands[0], operands[1]);
1783 DONE;
1784 })
1785
1786 (define_expand "mov<mode>"
1787 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1788 (match_operand:SWI1248x 1 "general_operand"))]
1789 ""
1790 "ix86_expand_move (<MODE>mode, operands); DONE;")
1791
1792 (define_insn "*mov<mode>_xor"
1793 [(set (match_operand:SWI48 0 "register_operand" "=r")
1794 (match_operand:SWI48 1 "const0_operand"))
1795 (clobber (reg:CC FLAGS_REG))]
1796 "reload_completed"
1797 "xor{l}\t%k0, %k0"
1798 [(set_attr "type" "alu1")
1799 (set_attr "mode" "SI")
1800 (set_attr "length_immediate" "0")])
1801
1802 (define_insn "*mov<mode>_or"
1803 [(set (match_operand:SWI48 0 "register_operand" "=r")
1804 (match_operand:SWI48 1 "const_int_operand"))
1805 (clobber (reg:CC FLAGS_REG))]
1806 "reload_completed
1807 && operands[1] == constm1_rtx"
1808 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1809 [(set_attr "type" "alu1")
1810 (set_attr "mode" "<MODE>")
1811 (set_attr "length_immediate" "1")])
1812
1813 (define_insn "*movoi_internal_avx"
1814 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1815 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1816 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1817 {
1818 switch (which_alternative)
1819 {
1820 case 0:
1821 return standard_sse_constant_opcode (insn, operands[1]);
1822 case 1:
1823 case 2:
1824 if (misaligned_operand (operands[0], OImode)
1825 || misaligned_operand (operands[1], OImode))
1826 {
1827 if (get_attr_mode (insn) == MODE_V8SF)
1828 return "vmovups\t{%1, %0|%0, %1}";
1829 else
1830 return "vmovdqu\t{%1, %0|%0, %1}";
1831 }
1832 else
1833 {
1834 if (get_attr_mode (insn) == MODE_V8SF)
1835 return "vmovaps\t{%1, %0|%0, %1}";
1836 else
1837 return "vmovdqa\t{%1, %0|%0, %1}";
1838 }
1839 default:
1840 gcc_unreachable ();
1841 }
1842 }
1843 [(set_attr "type" "sselog1,ssemov,ssemov")
1844 (set_attr "prefix" "vex")
1845 (set (attr "mode")
1846 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1847 (const_string "V8SF")
1848 (and (eq_attr "alternative" "2")
1849 (match_test "TARGET_SSE_TYPELESS_STORES"))
1850 (const_string "V8SF")
1851 ]
1852 (const_string "OI")))])
1853
1854 (define_insn "*movti_internal_rex64"
1855 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1856 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1857 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1858 {
1859 switch (which_alternative)
1860 {
1861 case 0:
1862 case 1:
1863 return "#";
1864 case 2:
1865 return standard_sse_constant_opcode (insn, operands[1]);
1866 case 3:
1867 case 4:
1868 /* TDmode values are passed as TImode on the stack. Moving them
1869 to stack may result in unaligned memory access. */
1870 if (misaligned_operand (operands[0], TImode)
1871 || misaligned_operand (operands[1], TImode))
1872 {
1873 if (get_attr_mode (insn) == MODE_V4SF)
1874 return "%vmovups\t{%1, %0|%0, %1}";
1875 else
1876 return "%vmovdqu\t{%1, %0|%0, %1}";
1877 }
1878 else
1879 {
1880 if (get_attr_mode (insn) == MODE_V4SF)
1881 return "%vmovaps\t{%1, %0|%0, %1}";
1882 else
1883 return "%vmovdqa\t{%1, %0|%0, %1}";
1884 }
1885 default:
1886 gcc_unreachable ();
1887 }
1888 }
1889 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1890 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1891 (set (attr "mode")
1892 (cond [(eq_attr "alternative" "0,1")
1893 (const_string "DI")
1894 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1895 (const_string "V4SF")
1896 (and (eq_attr "alternative" "4")
1897 (match_test "TARGET_SSE_TYPELESS_STORES"))
1898 (const_string "V4SF")
1899 (match_test "TARGET_AVX")
1900 (const_string "TI")
1901 (match_test "optimize_function_for_size_p (cfun)")
1902 (const_string "V4SF")
1903 ]
1904 (const_string "TI")))])
1905
1906 (define_split
1907 [(set (match_operand:TI 0 "nonimmediate_operand")
1908 (match_operand:TI 1 "general_operand"))]
1909 "reload_completed
1910 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1911 [(const_int 0)]
1912 "ix86_split_long_move (operands); DONE;")
1913
1914 (define_insn "*movti_internal_sse"
1915 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1916 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1917 "TARGET_SSE && !TARGET_64BIT
1918 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1919 {
1920 switch (which_alternative)
1921 {
1922 case 0:
1923 return standard_sse_constant_opcode (insn, operands[1]);
1924 case 1:
1925 case 2:
1926 /* TDmode values are passed as TImode on the stack. Moving them
1927 to stack may result in unaligned memory access. */
1928 if (misaligned_operand (operands[0], TImode)
1929 || misaligned_operand (operands[1], TImode))
1930 {
1931 if (get_attr_mode (insn) == MODE_V4SF)
1932 return "%vmovups\t{%1, %0|%0, %1}";
1933 else
1934 return "%vmovdqu\t{%1, %0|%0, %1}";
1935 }
1936 else
1937 {
1938 if (get_attr_mode (insn) == MODE_V4SF)
1939 return "%vmovaps\t{%1, %0|%0, %1}";
1940 else
1941 return "%vmovdqa\t{%1, %0|%0, %1}";
1942 }
1943 default:
1944 gcc_unreachable ();
1945 }
1946 }
1947 [(set_attr "type" "sselog1,ssemov,ssemov")
1948 (set_attr "prefix" "maybe_vex")
1949 (set (attr "mode")
1950 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1951 (const_string "V4SF")
1952 (and (eq_attr "alternative" "2")
1953 (match_test "TARGET_SSE_TYPELESS_STORES"))
1954 (const_string "V4SF")
1955 (match_test "TARGET_AVX")
1956 (const_string "TI")
1957 (ior (not (match_test "TARGET_SSE2"))
1958 (match_test "optimize_function_for_size_p (cfun)"))
1959 (const_string "V4SF")
1960 ]
1961 (const_string "TI")))])
1962
1963 (define_insn "*movdi_internal_rex64"
1964 [(set (match_operand:DI 0 "nonimmediate_operand"
1965 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1966 (match_operand:DI 1 "general_operand"
1967 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1968 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1969 {
1970 switch (get_attr_type (insn))
1971 {
1972 case TYPE_SSECVT:
1973 if (SSE_REG_P (operands[0]))
1974 return "movq2dq\t{%1, %0|%0, %1}";
1975 else
1976 return "movdq2q\t{%1, %0|%0, %1}";
1977
1978 case TYPE_SSEMOV:
1979 if (get_attr_mode (insn) == MODE_V4SF)
1980 return "%vmovaps\t{%1, %0|%0, %1}";
1981 else if (get_attr_mode (insn) == MODE_TI)
1982 return "%vmovdqa\t{%1, %0|%0, %1}";
1983
1984 /* Handle broken assemblers that require movd instead of movq. */
1985 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1986 return "%vmovd\t{%1, %0|%0, %1}";
1987 else
1988 return "%vmovq\t{%1, %0|%0, %1}";
1989
1990 case TYPE_MMXMOV:
1991 /* Handle broken assemblers that require movd instead of movq. */
1992 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1993 return "movd\t{%1, %0|%0, %1}";
1994 else
1995 return "movq\t{%1, %0|%0, %1}";
1996
1997 case TYPE_SSELOG1:
1998 return standard_sse_constant_opcode (insn, operands[1]);
1999
2000 case TYPE_MMX:
2001 return "pxor\t%0, %0";
2002
2003 case TYPE_MULTI:
2004 return "#";
2005
2006 case TYPE_LEA:
2007 return "lea{q}\t{%E1, %0|%0, %E1}";
2008
2009 default:
2010 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2011 if (get_attr_mode (insn) == MODE_SI)
2012 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2013 else if (which_alternative == 2)
2014 return "movabs{q}\t{%1, %0|%0, %1}";
2015 else if (ix86_use_lea_for_mov (insn, operands))
2016 return "lea{q}\t{%E1, %0|%0, %E1}";
2017 else
2018 return "mov{q}\t{%1, %0|%0, %1}";
2019 }
2020 }
2021 [(set (attr "type")
2022 (cond [(eq_attr "alternative" "4")
2023 (const_string "multi")
2024 (eq_attr "alternative" "5")
2025 (const_string "mmx")
2026 (eq_attr "alternative" "6,7,8,9")
2027 (const_string "mmxmov")
2028 (eq_attr "alternative" "10")
2029 (const_string "sselog1")
2030 (eq_attr "alternative" "11,12,13,14,15")
2031 (const_string "ssemov")
2032 (eq_attr "alternative" "16,17")
2033 (const_string "ssecvt")
2034 (match_operand 1 "pic_32bit_operand")
2035 (const_string "lea")
2036 ]
2037 (const_string "imov")))
2038 (set (attr "modrm")
2039 (if_then_else
2040 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2041 (const_string "0")
2042 (const_string "*")))
2043 (set (attr "length_immediate")
2044 (if_then_else
2045 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2046 (const_string "8")
2047 (const_string "*")))
2048 (set (attr "prefix_rex")
2049 (if_then_else (eq_attr "alternative" "8,9")
2050 (const_string "1")
2051 (const_string "*")))
2052 (set (attr "prefix_data16")
2053 (if_then_else (eq_attr "alternative" "11")
2054 (const_string "1")
2055 (const_string "*")))
2056 (set (attr "prefix")
2057 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2058 (const_string "maybe_vex")
2059 (const_string "orig")))
2060 (set (attr "mode")
2061 (cond [(eq_attr "alternative" "0,4")
2062 (const_string "SI")
2063 (eq_attr "alternative" "10,12")
2064 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2065 (const_string "V4SF")
2066 (match_test "TARGET_AVX")
2067 (const_string "TI")
2068 (match_test "optimize_function_for_size_p (cfun)")
2069 (const_string "V4SF")
2070 ]
2071 (const_string "TI"))
2072 ]
2073 (const_string "DI")))])
2074
2075 ;; Reload patterns to support multi-word load/store
2076 ;; with non-offsetable address.
2077 (define_expand "reload_noff_store"
2078 [(parallel [(match_operand 0 "memory_operand" "=m")
2079 (match_operand 1 "register_operand" "r")
2080 (match_operand:DI 2 "register_operand" "=&r")])]
2081 "TARGET_64BIT"
2082 {
2083 rtx mem = operands[0];
2084 rtx addr = XEXP (mem, 0);
2085
2086 emit_move_insn (operands[2], addr);
2087 mem = replace_equiv_address_nv (mem, operands[2]);
2088
2089 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2090 DONE;
2091 })
2092
2093 (define_expand "reload_noff_load"
2094 [(parallel [(match_operand 0 "register_operand" "=r")
2095 (match_operand 1 "memory_operand" "m")
2096 (match_operand:DI 2 "register_operand" "=r")])]
2097 "TARGET_64BIT"
2098 {
2099 rtx mem = operands[1];
2100 rtx addr = XEXP (mem, 0);
2101
2102 emit_move_insn (operands[2], addr);
2103 mem = replace_equiv_address_nv (mem, operands[2]);
2104
2105 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2106 DONE;
2107 })
2108
2109 ;; Convert impossible stores of immediate to existing instructions.
2110 ;; First try to get scratch register and go through it. In case this
2111 ;; fails, move by 32bit parts.
2112 (define_peephole2
2113 [(match_scratch:DI 2 "r")
2114 (set (match_operand:DI 0 "memory_operand")
2115 (match_operand:DI 1 "immediate_operand"))]
2116 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2117 && !x86_64_immediate_operand (operands[1], DImode)"
2118 [(set (match_dup 2) (match_dup 1))
2119 (set (match_dup 0) (match_dup 2))])
2120
2121 ;; We need to define this as both peepholer and splitter for case
2122 ;; peephole2 pass is not run.
2123 ;; "&& 1" is needed to keep it from matching the previous pattern.
2124 (define_peephole2
2125 [(set (match_operand:DI 0 "memory_operand")
2126 (match_operand:DI 1 "immediate_operand"))]
2127 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2128 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2129 [(set (match_dup 2) (match_dup 3))
2130 (set (match_dup 4) (match_dup 5))]
2131 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2132
2133 (define_split
2134 [(set (match_operand:DI 0 "memory_operand")
2135 (match_operand:DI 1 "immediate_operand"))]
2136 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2137 ? epilogue_completed : reload_completed)
2138 && !symbolic_operand (operands[1], DImode)
2139 && !x86_64_immediate_operand (operands[1], DImode)"
2140 [(set (match_dup 2) (match_dup 3))
2141 (set (match_dup 4) (match_dup 5))]
2142 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2143
2144 (define_insn "*movdi_internal"
2145 [(set (match_operand:DI 0 "nonimmediate_operand"
2146 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2147 (match_operand:DI 1 "general_operand"
2148 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2149 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2150 {
2151 switch (get_attr_type (insn))
2152 {
2153 case TYPE_SSECVT:
2154 if (SSE_REG_P (operands[0]))
2155 return "movq2dq\t{%1, %0|%0, %1}";
2156 else
2157 return "movdq2q\t{%1, %0|%0, %1}";
2158
2159 case TYPE_SSEMOV:
2160 switch (get_attr_mode (insn))
2161 {
2162 case MODE_TI:
2163 return "%vmovdqa\t{%1, %0|%0, %1}";
2164 case MODE_DI:
2165 return "%vmovq\t{%1, %0|%0, %1}";
2166 case MODE_V4SF:
2167 return "%vmovaps\t{%1, %0|%0, %1}";
2168 case MODE_V2SF:
2169 return "movlps\t{%1, %0|%0, %1}";
2170 default:
2171 gcc_unreachable ();
2172 }
2173
2174 case TYPE_MMXMOV:
2175 return "movq\t{%1, %0|%0, %1}";
2176
2177 case TYPE_SSELOG1:
2178 return standard_sse_constant_opcode (insn, operands[1]);
2179
2180 case TYPE_MMX:
2181 return "pxor\t%0, %0";
2182
2183 case TYPE_MULTI:
2184 return "#";
2185
2186 default:
2187 gcc_unreachable ();
2188 }
2189 }
2190 [(set (attr "isa")
2191 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2192 (const_string "sse2")
2193 (eq_attr "alternative" "9,10,11,12")
2194 (const_string "noavx")
2195 ]
2196 (const_string "*")))
2197 (set (attr "type")
2198 (cond [(eq_attr "alternative" "0,1")
2199 (const_string "multi")
2200 (eq_attr "alternative" "2")
2201 (const_string "mmx")
2202 (eq_attr "alternative" "3,4")
2203 (const_string "mmxmov")
2204 (eq_attr "alternative" "5,9")
2205 (const_string "sselog1")
2206 (eq_attr "alternative" "13,14")
2207 (const_string "ssecvt")
2208 ]
2209 (const_string "ssemov")))
2210 (set (attr "prefix")
2211 (if_then_else (eq_attr "alternative" "5,6,7,8")
2212 (const_string "maybe_vex")
2213 (const_string "orig")))
2214 (set (attr "mode")
2215 (cond [(eq_attr "alternative" "9,11")
2216 (const_string "V4SF")
2217 (eq_attr "alternative" "10,12")
2218 (const_string "V2SF")
2219 (eq_attr "alternative" "5,7")
2220 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2221 (const_string "V4SF")
2222 (match_test "TARGET_AVX")
2223 (const_string "TI")
2224 (match_test "optimize_function_for_size_p (cfun)")
2225 (const_string "V4SF")
2226 ]
2227 (const_string "TI"))
2228 ]
2229 (const_string "DI")))])
2230
2231 (define_split
2232 [(set (match_operand:DI 0 "nonimmediate_operand")
2233 (match_operand:DI 1 "general_operand"))]
2234 "!TARGET_64BIT && reload_completed
2235 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2236 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2237 [(const_int 0)]
2238 "ix86_split_long_move (operands); DONE;")
2239
2240 (define_insn "*movsi_internal"
2241 [(set (match_operand:SI 0 "nonimmediate_operand"
2242 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2243 (match_operand:SI 1 "general_operand"
2244 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2245 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2246 {
2247 switch (get_attr_type (insn))
2248 {
2249 case TYPE_SSELOG1:
2250 return standard_sse_constant_opcode (insn, operands[1]);
2251
2252 case TYPE_SSEMOV:
2253 switch (get_attr_mode (insn))
2254 {
2255 case MODE_TI:
2256 return "%vmovdqa\t{%1, %0|%0, %1}";
2257 case MODE_V4SF:
2258 return "%vmovaps\t{%1, %0|%0, %1}";
2259 case MODE_SI:
2260 return "%vmovd\t{%1, %0|%0, %1}";
2261 case MODE_SF:
2262 return "%vmovss\t{%1, %0|%0, %1}";
2263 default:
2264 gcc_unreachable ();
2265 }
2266
2267 case TYPE_MMX:
2268 return "pxor\t%0, %0";
2269
2270 case TYPE_MMXMOV:
2271 if (get_attr_mode (insn) == MODE_DI)
2272 return "movq\t{%1, %0|%0, %1}";
2273 return "movd\t{%1, %0|%0, %1}";
2274
2275 case TYPE_LEA:
2276 return "lea{l}\t{%E1, %0|%0, %E1}";
2277
2278 default:
2279 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2280 if (ix86_use_lea_for_mov (insn, operands))
2281 return "lea{l}\t{%E1, %0|%0, %E1}";
2282 else
2283 return "mov{l}\t{%1, %0|%0, %1}";
2284 }
2285 }
2286 [(set (attr "type")
2287 (cond [(eq_attr "alternative" "2")
2288 (const_string "mmx")
2289 (eq_attr "alternative" "3,4,5")
2290 (const_string "mmxmov")
2291 (eq_attr "alternative" "6")
2292 (const_string "sselog1")
2293 (eq_attr "alternative" "7,8,9,10,11")
2294 (const_string "ssemov")
2295 (match_operand 1 "pic_32bit_operand")
2296 (const_string "lea")
2297 ]
2298 (const_string "imov")))
2299 (set (attr "prefix")
2300 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2301 (const_string "orig")
2302 (const_string "maybe_vex")))
2303 (set (attr "prefix_data16")
2304 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2305 (const_string "1")
2306 (const_string "*")))
2307 (set (attr "mode")
2308 (cond [(eq_attr "alternative" "2,3")
2309 (const_string "DI")
2310 (eq_attr "alternative" "6,7")
2311 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2312 (const_string "V4SF")
2313 (match_test "TARGET_AVX")
2314 (const_string "TI")
2315 (ior (not (match_test "TARGET_SSE2"))
2316 (match_test "optimize_function_for_size_p (cfun)"))
2317 (const_string "V4SF")
2318 ]
2319 (const_string "TI"))
2320 (and (eq_attr "alternative" "8,9,10,11")
2321 (not (match_test "TARGET_SSE2")))
2322 (const_string "SF")
2323 ]
2324 (const_string "SI")))])
2325
2326 (define_insn "*movhi_internal"
2327 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2328 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2329 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2330 {
2331 switch (get_attr_type (insn))
2332 {
2333 case TYPE_IMOVX:
2334 /* movzwl is faster than movw on p2 due to partial word stalls,
2335 though not as fast as an aligned movl. */
2336 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2337 default:
2338 if (get_attr_mode (insn) == MODE_SI)
2339 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2340 else
2341 return "mov{w}\t{%1, %0|%0, %1}";
2342 }
2343 }
2344 [(set (attr "type")
2345 (cond [(match_test "optimize_function_for_size_p (cfun)")
2346 (const_string "imov")
2347 (and (eq_attr "alternative" "0")
2348 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2349 (not (match_test "TARGET_HIMODE_MATH"))))
2350 (const_string "imov")
2351 (and (eq_attr "alternative" "1,2")
2352 (match_operand:HI 1 "aligned_operand"))
2353 (const_string "imov")
2354 (and (match_test "TARGET_MOVX")
2355 (eq_attr "alternative" "0,2"))
2356 (const_string "imovx")
2357 ]
2358 (const_string "imov")))
2359 (set (attr "mode")
2360 (cond [(eq_attr "type" "imovx")
2361 (const_string "SI")
2362 (and (eq_attr "alternative" "1,2")
2363 (match_operand:HI 1 "aligned_operand"))
2364 (const_string "SI")
2365 (and (eq_attr "alternative" "0")
2366 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2367 (not (match_test "TARGET_HIMODE_MATH"))))
2368 (const_string "SI")
2369 ]
2370 (const_string "HI")))])
2371
2372 ;; Situation is quite tricky about when to choose full sized (SImode) move
2373 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2374 ;; partial register dependency machines (such as AMD Athlon), where QImode
2375 ;; moves issue extra dependency and for partial register stalls machines
2376 ;; that don't use QImode patterns (and QImode move cause stall on the next
2377 ;; instruction).
2378 ;;
2379 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2380 ;; register stall machines with, where we use QImode instructions, since
2381 ;; partial register stall can be caused there. Then we use movzx.
2382 (define_insn "*movqi_internal"
2383 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2384 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2385 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2386 {
2387 switch (get_attr_type (insn))
2388 {
2389 case TYPE_IMOVX:
2390 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2391 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2392 default:
2393 if (get_attr_mode (insn) == MODE_SI)
2394 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2395 else
2396 return "mov{b}\t{%1, %0|%0, %1}";
2397 }
2398 }
2399 [(set (attr "type")
2400 (cond [(and (eq_attr "alternative" "5")
2401 (not (match_operand:QI 1 "aligned_operand")))
2402 (const_string "imovx")
2403 (match_test "optimize_function_for_size_p (cfun)")
2404 (const_string "imov")
2405 (and (eq_attr "alternative" "3")
2406 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2407 (not (match_test "TARGET_QIMODE_MATH"))))
2408 (const_string "imov")
2409 (eq_attr "alternative" "3,5")
2410 (const_string "imovx")
2411 (and (match_test "TARGET_MOVX")
2412 (eq_attr "alternative" "2"))
2413 (const_string "imovx")
2414 ]
2415 (const_string "imov")))
2416 (set (attr "mode")
2417 (cond [(eq_attr "alternative" "3,4,5")
2418 (const_string "SI")
2419 (eq_attr "alternative" "6")
2420 (const_string "QI")
2421 (eq_attr "type" "imovx")
2422 (const_string "SI")
2423 (and (eq_attr "type" "imov")
2424 (and (eq_attr "alternative" "0,1")
2425 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2426 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2427 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2428 (const_string "SI")
2429 ;; Avoid partial register stalls when not using QImode arithmetic
2430 (and (eq_attr "type" "imov")
2431 (and (eq_attr "alternative" "0,1")
2432 (and (match_test "TARGET_PARTIAL_REG_STALL")
2433 (not (match_test "TARGET_QIMODE_MATH")))))
2434 (const_string "SI")
2435 ]
2436 (const_string "QI")))])
2437
2438 ;; Stores and loads of ax to arbitrary constant address.
2439 ;; We fake an second form of instruction to force reload to load address
2440 ;; into register when rax is not available
2441 (define_insn "*movabs<mode>_1"
2442 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2443 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2444 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2445 "@
2446 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2447 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2448 [(set_attr "type" "imov")
2449 (set_attr "modrm" "0,*")
2450 (set_attr "length_address" "8,0")
2451 (set_attr "length_immediate" "0,*")
2452 (set_attr "memory" "store")
2453 (set_attr "mode" "<MODE>")])
2454
2455 (define_insn "*movabs<mode>_2"
2456 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2457 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2458 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2459 "@
2460 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2461 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2462 [(set_attr "type" "imov")
2463 (set_attr "modrm" "0,*")
2464 (set_attr "length_address" "8,0")
2465 (set_attr "length_immediate" "0")
2466 (set_attr "memory" "load")
2467 (set_attr "mode" "<MODE>")])
2468
2469 (define_insn "swap<mode>"
2470 [(set (match_operand:SWI48 0 "register_operand" "+r")
2471 (match_operand:SWI48 1 "register_operand" "+r"))
2472 (set (match_dup 1)
2473 (match_dup 0))]
2474 ""
2475 "xchg{<imodesuffix>}\t%1, %0"
2476 [(set_attr "type" "imov")
2477 (set_attr "mode" "<MODE>")
2478 (set_attr "pent_pair" "np")
2479 (set_attr "athlon_decode" "vector")
2480 (set_attr "amdfam10_decode" "double")
2481 (set_attr "bdver1_decode" "double")])
2482
2483 (define_insn "*swap<mode>_1"
2484 [(set (match_operand:SWI12 0 "register_operand" "+r")
2485 (match_operand:SWI12 1 "register_operand" "+r"))
2486 (set (match_dup 1)
2487 (match_dup 0))]
2488 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2489 "xchg{l}\t%k1, %k0"
2490 [(set_attr "type" "imov")
2491 (set_attr "mode" "SI")
2492 (set_attr "pent_pair" "np")
2493 (set_attr "athlon_decode" "vector")
2494 (set_attr "amdfam10_decode" "double")
2495 (set_attr "bdver1_decode" "double")])
2496
2497 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2498 ;; is disabled for AMDFAM10
2499 (define_insn "*swap<mode>_2"
2500 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2501 (match_operand:SWI12 1 "register_operand" "+<r>"))
2502 (set (match_dup 1)
2503 (match_dup 0))]
2504 "TARGET_PARTIAL_REG_STALL"
2505 "xchg{<imodesuffix>}\t%1, %0"
2506 [(set_attr "type" "imov")
2507 (set_attr "mode" "<MODE>")
2508 (set_attr "pent_pair" "np")
2509 (set_attr "athlon_decode" "vector")])
2510
2511 (define_expand "movstrict<mode>"
2512 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2513 (match_operand:SWI12 1 "general_operand"))]
2514 ""
2515 {
2516 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2517 FAIL;
2518 if (GET_CODE (operands[0]) == SUBREG
2519 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2520 FAIL;
2521 /* Don't generate memory->memory moves, go through a register */
2522 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2523 operands[1] = force_reg (<MODE>mode, operands[1]);
2524 })
2525
2526 (define_insn "*movstrict<mode>_1"
2527 [(set (strict_low_part
2528 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2529 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2530 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2531 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2532 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2533 [(set_attr "type" "imov")
2534 (set_attr "mode" "<MODE>")])
2535
2536 (define_insn "*movstrict<mode>_xor"
2537 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2538 (match_operand:SWI12 1 "const0_operand"))
2539 (clobber (reg:CC FLAGS_REG))]
2540 "reload_completed"
2541 "xor{<imodesuffix>}\t%0, %0"
2542 [(set_attr "type" "alu1")
2543 (set_attr "mode" "<MODE>")
2544 (set_attr "length_immediate" "0")])
2545
2546 (define_insn "*mov<mode>_extv_1"
2547 [(set (match_operand:SWI24 0 "register_operand" "=R")
2548 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2549 (const_int 8)
2550 (const_int 8)))]
2551 ""
2552 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2553 [(set_attr "type" "imovx")
2554 (set_attr "mode" "SI")])
2555
2556 (define_insn "*movqi_extv_1_rex64"
2557 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2558 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2559 (const_int 8)
2560 (const_int 8)))]
2561 "TARGET_64BIT"
2562 {
2563 switch (get_attr_type (insn))
2564 {
2565 case TYPE_IMOVX:
2566 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2567 default:
2568 return "mov{b}\t{%h1, %0|%0, %h1}";
2569 }
2570 }
2571 [(set (attr "type")
2572 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2573 (match_test "TARGET_MOVX"))
2574 (const_string "imovx")
2575 (const_string "imov")))
2576 (set (attr "mode")
2577 (if_then_else (eq_attr "type" "imovx")
2578 (const_string "SI")
2579 (const_string "QI")))])
2580
2581 (define_insn "*movqi_extv_1"
2582 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2583 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2584 (const_int 8)
2585 (const_int 8)))]
2586 "!TARGET_64BIT"
2587 {
2588 switch (get_attr_type (insn))
2589 {
2590 case TYPE_IMOVX:
2591 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2592 default:
2593 return "mov{b}\t{%h1, %0|%0, %h1}";
2594 }
2595 }
2596 [(set (attr "type")
2597 (if_then_else (and (match_operand:QI 0 "register_operand")
2598 (ior (not (match_operand:QI 0 "QIreg_operand"))
2599 (match_test "TARGET_MOVX")))
2600 (const_string "imovx")
2601 (const_string "imov")))
2602 (set (attr "mode")
2603 (if_then_else (eq_attr "type" "imovx")
2604 (const_string "SI")
2605 (const_string "QI")))])
2606
2607 (define_insn "*mov<mode>_extzv_1"
2608 [(set (match_operand:SWI48 0 "register_operand" "=R")
2609 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2610 (const_int 8)
2611 (const_int 8)))]
2612 ""
2613 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2614 [(set_attr "type" "imovx")
2615 (set_attr "mode" "SI")])
2616
2617 (define_insn "*movqi_extzv_2_rex64"
2618 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2619 (subreg:QI
2620 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2621 (const_int 8)
2622 (const_int 8)) 0))]
2623 "TARGET_64BIT"
2624 {
2625 switch (get_attr_type (insn))
2626 {
2627 case TYPE_IMOVX:
2628 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2629 default:
2630 return "mov{b}\t{%h1, %0|%0, %h1}";
2631 }
2632 }
2633 [(set (attr "type")
2634 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2635 (match_test "TARGET_MOVX"))
2636 (const_string "imovx")
2637 (const_string "imov")))
2638 (set (attr "mode")
2639 (if_then_else (eq_attr "type" "imovx")
2640 (const_string "SI")
2641 (const_string "QI")))])
2642
2643 (define_insn "*movqi_extzv_2"
2644 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2645 (subreg:QI
2646 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2647 (const_int 8)
2648 (const_int 8)) 0))]
2649 "!TARGET_64BIT"
2650 {
2651 switch (get_attr_type (insn))
2652 {
2653 case TYPE_IMOVX:
2654 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2655 default:
2656 return "mov{b}\t{%h1, %0|%0, %h1}";
2657 }
2658 }
2659 [(set (attr "type")
2660 (if_then_else (and (match_operand:QI 0 "register_operand")
2661 (ior (not (match_operand:QI 0 "QIreg_operand"))
2662 (match_test "TARGET_MOVX")))
2663 (const_string "imovx")
2664 (const_string "imov")))
2665 (set (attr "mode")
2666 (if_then_else (eq_attr "type" "imovx")
2667 (const_string "SI")
2668 (const_string "QI")))])
2669
2670 (define_expand "mov<mode>_insv_1"
2671 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2672 (const_int 8)
2673 (const_int 8))
2674 (match_operand:SWI48 1 "nonmemory_operand"))])
2675
2676 (define_insn "*mov<mode>_insv_1_rex64"
2677 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2678 (const_int 8)
2679 (const_int 8))
2680 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2681 "TARGET_64BIT"
2682 "mov{b}\t{%b1, %h0|%h0, %b1}"
2683 [(set_attr "type" "imov")
2684 (set_attr "mode" "QI")])
2685
2686 (define_insn "*movsi_insv_1"
2687 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2688 (const_int 8)
2689 (const_int 8))
2690 (match_operand:SI 1 "general_operand" "Qmn"))]
2691 "!TARGET_64BIT"
2692 "mov{b}\t{%b1, %h0|%h0, %b1}"
2693 [(set_attr "type" "imov")
2694 (set_attr "mode" "QI")])
2695
2696 (define_insn "*movqi_insv_2"
2697 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2698 (const_int 8)
2699 (const_int 8))
2700 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2701 (const_int 8)))]
2702 ""
2703 "mov{b}\t{%h1, %h0|%h0, %h1}"
2704 [(set_attr "type" "imov")
2705 (set_attr "mode" "QI")])
2706 \f
2707 ;; Floating point push instructions.
2708
2709 (define_insn "*pushtf"
2710 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2711 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2712 "TARGET_SSE"
2713 {
2714 /* This insn should be already split before reg-stack. */
2715 gcc_unreachable ();
2716 }
2717 [(set_attr "type" "multi")
2718 (set_attr "unit" "sse,*,*")
2719 (set_attr "mode" "TF,SI,SI")])
2720
2721 ;; %%% Kill this when call knows how to work this out.
2722 (define_split
2723 [(set (match_operand:TF 0 "push_operand")
2724 (match_operand:TF 1 "sse_reg_operand"))]
2725 "TARGET_SSE && reload_completed"
2726 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2727 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2728
2729 (define_insn "*pushxf"
2730 [(set (match_operand:XF 0 "push_operand" "=<,<")
2731 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2732 "optimize_function_for_speed_p (cfun)"
2733 {
2734 /* This insn should be already split before reg-stack. */
2735 gcc_unreachable ();
2736 }
2737 [(set_attr "type" "multi")
2738 (set_attr "unit" "i387,*")
2739 (set_attr "mode" "XF,SI")])
2740
2741 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2742 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2743 ;; Pushing using integer instructions is longer except for constants
2744 ;; and direct memory references (assuming that any given constant is pushed
2745 ;; only once, but this ought to be handled elsewhere).
2746
2747 (define_insn "*pushxf_nointeger"
2748 [(set (match_operand:XF 0 "push_operand" "=<,<")
2749 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2750 "optimize_function_for_size_p (cfun)"
2751 {
2752 /* This insn should be already split before reg-stack. */
2753 gcc_unreachable ();
2754 }
2755 [(set_attr "type" "multi")
2756 (set_attr "unit" "i387,*")
2757 (set_attr "mode" "XF,SI")])
2758
2759 ;; %%% Kill this when call knows how to work this out.
2760 (define_split
2761 [(set (match_operand:XF 0 "push_operand")
2762 (match_operand:XF 1 "fp_register_operand"))]
2763 "reload_completed"
2764 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2765 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2766 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2767
2768 (define_insn "*pushdf_rex64"
2769 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2770 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2771 "TARGET_64BIT"
2772 {
2773 /* This insn should be already split before reg-stack. */
2774 gcc_unreachable ();
2775 }
2776 [(set_attr "type" "multi")
2777 (set_attr "unit" "i387,*,*")
2778 (set_attr "mode" "DF,DI,DF")])
2779
2780 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2781 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2782 ;; On the average, pushdf using integers can be still shorter.
2783
2784 (define_insn "*pushdf"
2785 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2786 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2787 "!TARGET_64BIT"
2788 {
2789 /* This insn should be already split before reg-stack. */
2790 gcc_unreachable ();
2791 }
2792 [(set_attr "isa" "*,*,sse2")
2793 (set_attr "type" "multi")
2794 (set_attr "unit" "i387,*,*")
2795 (set_attr "mode" "DF,DI,DF")])
2796
2797 ;; %%% Kill this when call knows how to work this out.
2798 (define_split
2799 [(set (match_operand:DF 0 "push_operand")
2800 (match_operand:DF 1 "any_fp_register_operand"))]
2801 "reload_completed"
2802 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2803 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2804
2805 (define_insn "*pushsf_rex64"
2806 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2807 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2808 "TARGET_64BIT"
2809 {
2810 /* Anything else should be already split before reg-stack. */
2811 gcc_assert (which_alternative == 1);
2812 return "push{q}\t%q1";
2813 }
2814 [(set_attr "type" "multi,push,multi")
2815 (set_attr "unit" "i387,*,*")
2816 (set_attr "mode" "SF,DI,SF")])
2817
2818 (define_insn "*pushsf"
2819 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2820 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2821 "!TARGET_64BIT"
2822 {
2823 /* Anything else should be already split before reg-stack. */
2824 gcc_assert (which_alternative == 1);
2825 return "push{l}\t%1";
2826 }
2827 [(set_attr "type" "multi,push,multi")
2828 (set_attr "unit" "i387,*,*")
2829 (set_attr "mode" "SF,SI,SF")])
2830
2831 ;; %%% Kill this when call knows how to work this out.
2832 (define_split
2833 [(set (match_operand:SF 0 "push_operand")
2834 (match_operand:SF 1 "any_fp_register_operand"))]
2835 "reload_completed"
2836 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2837 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2838 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2839
2840 (define_split
2841 [(set (match_operand:SF 0 "push_operand")
2842 (match_operand:SF 1 "memory_operand"))]
2843 "reload_completed
2844 && (operands[2] = find_constant_src (insn))"
2845 [(set (match_dup 0) (match_dup 2))])
2846
2847 (define_split
2848 [(set (match_operand 0 "push_operand")
2849 (match_operand 1 "general_operand"))]
2850 "reload_completed
2851 && (GET_MODE (operands[0]) == TFmode
2852 || GET_MODE (operands[0]) == XFmode
2853 || GET_MODE (operands[0]) == DFmode)
2854 && !ANY_FP_REG_P (operands[1])"
2855 [(const_int 0)]
2856 "ix86_split_long_move (operands); DONE;")
2857 \f
2858 ;; Floating point move instructions.
2859
2860 (define_expand "movtf"
2861 [(set (match_operand:TF 0 "nonimmediate_operand")
2862 (match_operand:TF 1 "nonimmediate_operand"))]
2863 "TARGET_SSE"
2864 {
2865 ix86_expand_move (TFmode, operands);
2866 DONE;
2867 })
2868
2869 (define_expand "mov<mode>"
2870 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2871 (match_operand:X87MODEF 1 "general_operand"))]
2872 ""
2873 "ix86_expand_move (<MODE>mode, operands); DONE;")
2874
2875 (define_insn "*movtf_internal"
2876 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2877 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,F*r"))]
2878 "TARGET_SSE
2879 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2880 && (!can_create_pseudo_p ()
2881 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2882 || GET_CODE (operands[1]) != CONST_DOUBLE
2883 || (optimize_function_for_size_p (cfun)
2884 && standard_sse_constant_p (operands[1])
2885 && !memory_operand (operands[0], TFmode))
2886 || (!TARGET_MEMORY_MISMATCH_STALL
2887 && memory_operand (operands[0], TFmode)))"
2888 {
2889 switch (which_alternative)
2890 {
2891 case 0:
2892 return standard_sse_constant_opcode (insn, operands[1]);
2893 case 1:
2894 case 2:
2895 /* Handle misaligned load/store since we
2896 don't have movmisaligntf pattern. */
2897 if (misaligned_operand (operands[0], TFmode)
2898 || misaligned_operand (operands[1], TFmode))
2899 {
2900 if (get_attr_mode (insn) == MODE_V4SF)
2901 return "%vmovups\t{%1, %0|%0, %1}";
2902 else
2903 return "%vmovdqu\t{%1, %0|%0, %1}";
2904 }
2905 else
2906 {
2907 if (get_attr_mode (insn) == MODE_V4SF)
2908 return "%vmovaps\t{%1, %0|%0, %1}";
2909 else
2910 return "%vmovdqa\t{%1, %0|%0, %1}";
2911 }
2912
2913 case 3:
2914 case 4:
2915 return "#";
2916
2917 default:
2918 gcc_unreachable ();
2919 }
2920 }
2921 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2922 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2923 (set (attr "mode")
2924 (cond [(eq_attr "alternative" "3,4")
2925 (const_string "DI")
2926 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2927 (const_string "V4SF")
2928 (and (eq_attr "alternative" "2")
2929 (match_test "TARGET_SSE_TYPELESS_STORES"))
2930 (const_string "V4SF")
2931 (match_test "TARGET_AVX")
2932 (const_string "TI")
2933 (ior (not (match_test "TARGET_SSE2"))
2934 (match_test "optimize_function_for_size_p (cfun)"))
2935 (const_string "V4SF")
2936 ]
2937 (const_string "TI")))])
2938
2939 ;; Possible store forwarding (partial memory) stall in alternative 4.
2940 (define_insn "*movxf_internal"
2941 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2942 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2943 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2944 && (!can_create_pseudo_p ()
2945 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2946 || GET_CODE (operands[1]) != CONST_DOUBLE
2947 || (optimize_function_for_size_p (cfun)
2948 && standard_80387_constant_p (operands[1]) > 0
2949 && !memory_operand (operands[0], XFmode))
2950 || (!TARGET_MEMORY_MISMATCH_STALL
2951 && memory_operand (operands[0], XFmode)))"
2952 {
2953 switch (which_alternative)
2954 {
2955 case 0:
2956 case 1:
2957 return output_387_reg_move (insn, operands);
2958
2959 case 2:
2960 return standard_80387_constant_opcode (operands[1]);
2961
2962 case 3:
2963 case 4:
2964 return "#";
2965
2966 default:
2967 gcc_unreachable ();
2968 }
2969 }
2970 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2971 (set_attr "mode" "XF,XF,XF,SI,SI")])
2972
2973 (define_insn "*movdf_internal_rex64"
2974 [(set (match_operand:DF 0 "nonimmediate_operand"
2975 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2976 (match_operand:DF 1 "general_operand"
2977 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2978 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2979 && (!can_create_pseudo_p ()
2980 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2981 || GET_CODE (operands[1]) != CONST_DOUBLE
2982 || (optimize_function_for_size_p (cfun)
2983 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2984 && standard_80387_constant_p (operands[1]) > 0)
2985 || (TARGET_SSE2 && TARGET_SSE_MATH
2986 && standard_sse_constant_p (operands[1]))))
2987 || memory_operand (operands[0], DFmode))"
2988 {
2989 switch (which_alternative)
2990 {
2991 case 0:
2992 case 1:
2993 return output_387_reg_move (insn, operands);
2994
2995 case 2:
2996 return standard_80387_constant_opcode (operands[1]);
2997
2998 case 3:
2999 case 4:
3000 return "mov{q}\t{%1, %0|%0, %1}";
3001
3002 case 5:
3003 return "movabs{q}\t{%1, %0|%0, %1}";
3004
3005 case 6:
3006 return "#";
3007
3008 case 7:
3009 return standard_sse_constant_opcode (insn, operands[1]);
3010
3011 case 8:
3012 case 9:
3013 case 10:
3014 switch (get_attr_mode (insn))
3015 {
3016 case MODE_V2DF:
3017 return "%vmovapd\t{%1, %0|%0, %1}";
3018 case MODE_V4SF:
3019 return "%vmovaps\t{%1, %0|%0, %1}";
3020
3021 case MODE_DI:
3022 return "%vmovq\t{%1, %0|%0, %1}";
3023 case MODE_DF:
3024 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3025 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3026 return "%vmovsd\t{%1, %0|%0, %1}";
3027 case MODE_V1DF:
3028 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3029 case MODE_V2SF:
3030 return "%vmovlps\t{%1, %d0|%d0, %1}";
3031 default:
3032 gcc_unreachable ();
3033 }
3034
3035 case 11:
3036 case 12:
3037 /* Handle broken assemblers that require movd instead of movq. */
3038 return "%vmovd\t{%1, %0|%0, %1}";
3039
3040 default:
3041 gcc_unreachable();
3042 }
3043 }
3044 [(set (attr "type")
3045 (cond [(eq_attr "alternative" "0,1,2")
3046 (const_string "fmov")
3047 (eq_attr "alternative" "3,4,5")
3048 (const_string "imov")
3049 (eq_attr "alternative" "6")
3050 (const_string "multi")
3051 (eq_attr "alternative" "7")
3052 (const_string "sselog1")
3053 ]
3054 (const_string "ssemov")))
3055 (set (attr "modrm")
3056 (if_then_else
3057 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3058 (const_string "0")
3059 (const_string "*")))
3060 (set (attr "length_immediate")
3061 (if_then_else
3062 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3063 (const_string "8")
3064 (const_string "*")))
3065 (set (attr "prefix")
3066 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3067 (const_string "orig")
3068 (const_string "maybe_vex")))
3069 (set (attr "prefix_data16")
3070 (if_then_else (eq_attr "mode" "V1DF")
3071 (const_string "1")
3072 (const_string "*")))
3073 (set (attr "mode")
3074 (cond [(eq_attr "alternative" "0,1,2")
3075 (const_string "DF")
3076 (eq_attr "alternative" "3,4,5,6,11,12")
3077 (const_string "DI")
3078
3079 /* xorps is one byte shorter for !TARGET_AVX. */
3080 (eq_attr "alternative" "7")
3081 (cond [(match_test "TARGET_AVX")
3082 (const_string "V2DF")
3083 (match_test "optimize_function_for_size_p (cfun)")
3084 (const_string "V4SF")
3085 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3086 (const_string "TI")
3087 ]
3088 (const_string "V2DF"))
3089
3090 /* For architectures resolving dependencies on
3091 whole SSE registers use APD move to break dependency
3092 chains, otherwise use short move to avoid extra work.
3093
3094 movaps encodes one byte shorter for !TARGET_AVX. */
3095 (eq_attr "alternative" "8")
3096 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3097 (const_string "V4SF")
3098 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3099 (const_string "V2DF")
3100 (match_test "TARGET_AVX")
3101 (const_string "DF")
3102 (match_test "optimize_function_for_size_p (cfun)")
3103 (const_string "V4SF")
3104 ]
3105 (const_string "DF"))
3106 /* For architectures resolving dependencies on register
3107 parts we may avoid extra work to zero out upper part
3108 of register. */
3109 (eq_attr "alternative" "9")
3110 (if_then_else
3111 (match_test "TARGET_SSE_SPLIT_REGS")
3112 (const_string "V1DF")
3113 (const_string "DF"))
3114 ]
3115 (const_string "DF")))])
3116
3117 ;; Possible store forwarding (partial memory) stall in alternative 4.
3118 (define_insn "*movdf_internal"
3119 [(set (match_operand:DF 0 "nonimmediate_operand"
3120 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3121 (match_operand:DF 1 "general_operand"
3122 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3123 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3124 && (!can_create_pseudo_p ()
3125 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3126 || GET_CODE (operands[1]) != CONST_DOUBLE
3127 || (optimize_function_for_size_p (cfun)
3128 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3129 && standard_80387_constant_p (operands[1]) > 0)
3130 || (TARGET_SSE2 && TARGET_SSE_MATH
3131 && standard_sse_constant_p (operands[1])))
3132 && !memory_operand (operands[0], DFmode))
3133 || (!TARGET_MEMORY_MISMATCH_STALL
3134 && memory_operand (operands[0], DFmode)))"
3135 {
3136 switch (which_alternative)
3137 {
3138 case 0:
3139 case 1:
3140 return output_387_reg_move (insn, operands);
3141
3142 case 2:
3143 return standard_80387_constant_opcode (operands[1]);
3144
3145 case 3:
3146 case 4:
3147 return "#";
3148
3149 case 5:
3150 case 9:
3151 return standard_sse_constant_opcode (insn, operands[1]);
3152
3153 case 6:
3154 case 7:
3155 case 8:
3156 case 10:
3157 case 11:
3158 case 12:
3159 switch (get_attr_mode (insn))
3160 {
3161 case MODE_V2DF:
3162 return "%vmovapd\t{%1, %0|%0, %1}";
3163 case MODE_V4SF:
3164 return "%vmovaps\t{%1, %0|%0, %1}";
3165
3166 case MODE_DI:
3167 return "%vmovq\t{%1, %0|%0, %1}";
3168 case MODE_DF:
3169 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3170 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3171 return "%vmovsd\t{%1, %0|%0, %1}";
3172 case MODE_V1DF:
3173 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3174 case MODE_V2SF:
3175 return "%vmovlps\t{%1, %d0|%d0, %1}";
3176 default:
3177 gcc_unreachable ();
3178 }
3179
3180 default:
3181 gcc_unreachable ();
3182 }
3183 }
3184 [(set (attr "isa")
3185 (if_then_else (eq_attr "alternative" "5,6,7,8")
3186 (const_string "sse2")
3187 (const_string "*")))
3188 (set (attr "type")
3189 (cond [(eq_attr "alternative" "0,1,2")
3190 (const_string "fmov")
3191 (eq_attr "alternative" "3,4")
3192 (const_string "multi")
3193 (eq_attr "alternative" "5,9")
3194 (const_string "sselog1")
3195 ]
3196 (const_string "ssemov")))
3197 (set (attr "prefix")
3198 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3199 (const_string "orig")
3200 (const_string "maybe_vex")))
3201 (set (attr "prefix_data16")
3202 (if_then_else (eq_attr "mode" "V1DF")
3203 (const_string "1")
3204 (const_string "*")))
3205 (set (attr "mode")
3206 (cond [(eq_attr "alternative" "0,1,2")
3207 (const_string "DF")
3208 (eq_attr "alternative" "3,4")
3209 (const_string "SI")
3210
3211 /* For SSE1, we have many fewer alternatives. */
3212 (not (match_test "TARGET_SSE2"))
3213 (if_then_else
3214 (eq_attr "alternative" "5,6,9,10")
3215 (const_string "V4SF")
3216 (const_string "V2SF"))
3217
3218 /* xorps is one byte shorter for !TARGET_AVX. */
3219 (eq_attr "alternative" "5,9")
3220 (cond [(match_test "TARGET_AVX")
3221 (const_string "V2DF")
3222 (match_test "optimize_function_for_size_p (cfun)")
3223 (const_string "V4SF")
3224 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3225 (const_string "TI")
3226 ]
3227 (const_string "V2DF"))
3228
3229 /* For architectures resolving dependencies on
3230 whole SSE registers use APD move to break dependency
3231 chains, otherwise use short move to avoid extra work.
3232
3233 movaps encodes one byte shorter for !TARGET_AVX. */
3234 (eq_attr "alternative" "6,10")
3235 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3236 (const_string "V4SF")
3237 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3238 (const_string "V2DF")
3239 (match_test "TARGET_AVX")
3240 (const_string "DF")
3241 (match_test "optimize_function_for_size_p (cfun)")
3242 (const_string "V4SF")
3243 ]
3244 (const_string "DF"))
3245
3246 /* For architectures resolving dependencies on register
3247 parts we may avoid extra work to zero out upper part
3248 of register. */
3249 (eq_attr "alternative" "7,11")
3250 (if_then_else
3251 (match_test "TARGET_SSE_SPLIT_REGS")
3252 (const_string "V1DF")
3253 (const_string "DF"))
3254 ]
3255 (const_string "DF")))])
3256
3257 (define_insn "*movsf_internal"
3258 [(set (match_operand:SF 0 "nonimmediate_operand"
3259 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3260 (match_operand:SF 1 "general_operand"
3261 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3262 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3263 && (!can_create_pseudo_p ()
3264 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3265 || GET_CODE (operands[1]) != CONST_DOUBLE
3266 || (optimize_function_for_size_p (cfun)
3267 && ((!TARGET_SSE_MATH
3268 && standard_80387_constant_p (operands[1]) > 0)
3269 || (TARGET_SSE_MATH
3270 && standard_sse_constant_p (operands[1]))))
3271 || memory_operand (operands[0], SFmode))"
3272 {
3273 switch (which_alternative)
3274 {
3275 case 0:
3276 case 1:
3277 return output_387_reg_move (insn, operands);
3278
3279 case 2:
3280 return standard_80387_constant_opcode (operands[1]);
3281
3282 case 3:
3283 case 4:
3284 return "mov{l}\t{%1, %0|%0, %1}";
3285
3286 case 5:
3287 return standard_sse_constant_opcode (insn, operands[1]);
3288
3289 case 6:
3290 if (get_attr_mode (insn) == MODE_V4SF)
3291 return "%vmovaps\t{%1, %0|%0, %1}";
3292 if (TARGET_AVX)
3293 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3294
3295 case 7:
3296 case 8:
3297 return "%vmovss\t{%1, %0|%0, %1}";
3298
3299 case 9:
3300 case 10:
3301 case 14:
3302 case 15:
3303 return "movd\t{%1, %0|%0, %1}";
3304
3305 case 11:
3306 return "movq\t{%1, %0|%0, %1}";
3307
3308 case 12:
3309 case 13:
3310 return "%vmovd\t{%1, %0|%0, %1}";
3311
3312 default:
3313 gcc_unreachable ();
3314 }
3315 }
3316 [(set (attr "type")
3317 (cond [(eq_attr "alternative" "0,1,2")
3318 (const_string "fmov")
3319 (eq_attr "alternative" "3,4")
3320 (const_string "multi")
3321 (eq_attr "alternative" "5")
3322 (const_string "sselog1")
3323 (eq_attr "alternative" "9,10,11,14,15")
3324 (const_string "mmxmov")
3325 ]
3326 (const_string "ssemov")))
3327 (set (attr "prefix")
3328 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3329 (const_string "maybe_vex")
3330 (const_string "orig")))
3331 (set (attr "mode")
3332 (cond [(eq_attr "alternative" "3,4,9,10")
3333 (const_string "SI")
3334 (eq_attr "alternative" "5")
3335 (cond [(match_test "TARGET_AVX")
3336 (const_string "V4SF")
3337 (ior (not (match_test "TARGET_SSE2"))
3338 (match_test "optimize_function_for_size_p (cfun)"))
3339 (const_string "V4SF")
3340 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3341 (const_string "TI")
3342 ]
3343 (const_string "V4SF"))
3344
3345 /* For architectures resolving dependencies on
3346 whole SSE registers use APS move to break dependency
3347 chains, otherwise use short move to avoid extra work.
3348
3349 Do the same for architectures resolving dependencies on
3350 the parts. While in DF mode it is better to always handle
3351 just register parts, the SF mode is different due to lack
3352 of instructions to load just part of the register. It is
3353 better to maintain the whole registers in single format
3354 to avoid problems on using packed logical operations. */
3355 (eq_attr "alternative" "6")
3356 (if_then_else
3357 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3358 (match_test "TARGET_SSE_SPLIT_REGS"))
3359 (const_string "V4SF")
3360 (const_string "SF"))
3361 (eq_attr "alternative" "11")
3362 (const_string "DI")]
3363 (const_string "SF")))])
3364
3365 (define_split
3366 [(set (match_operand 0 "any_fp_register_operand")
3367 (match_operand 1 "memory_operand"))]
3368 "reload_completed
3369 && (GET_MODE (operands[0]) == TFmode
3370 || GET_MODE (operands[0]) == XFmode
3371 || GET_MODE (operands[0]) == DFmode
3372 || GET_MODE (operands[0]) == SFmode)
3373 && (operands[2] = find_constant_src (insn))"
3374 [(set (match_dup 0) (match_dup 2))]
3375 {
3376 rtx c = operands[2];
3377 int r = REGNO (operands[0]);
3378
3379 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3380 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3381 FAIL;
3382 })
3383
3384 (define_split
3385 [(set (match_operand 0 "any_fp_register_operand")
3386 (float_extend (match_operand 1 "memory_operand")))]
3387 "reload_completed
3388 && (GET_MODE (operands[0]) == TFmode
3389 || GET_MODE (operands[0]) == XFmode
3390 || GET_MODE (operands[0]) == DFmode)
3391 && (operands[2] = find_constant_src (insn))"
3392 [(set (match_dup 0) (match_dup 2))]
3393 {
3394 rtx c = operands[2];
3395 int r = REGNO (operands[0]);
3396
3397 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3398 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3399 FAIL;
3400 })
3401
3402 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3403 (define_split
3404 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3405 (match_operand:X87MODEF 1 "immediate_operand"))]
3406 "reload_completed
3407 && (standard_80387_constant_p (operands[1]) == 8
3408 || standard_80387_constant_p (operands[1]) == 9)"
3409 [(set (match_dup 0)(match_dup 1))
3410 (set (match_dup 0)
3411 (neg:X87MODEF (match_dup 0)))]
3412 {
3413 REAL_VALUE_TYPE r;
3414
3415 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3416 if (real_isnegzero (&r))
3417 operands[1] = CONST0_RTX (<MODE>mode);
3418 else
3419 operands[1] = CONST1_RTX (<MODE>mode);
3420 })
3421
3422 (define_split
3423 [(set (match_operand 0 "nonimmediate_operand")
3424 (match_operand 1 "general_operand"))]
3425 "reload_completed
3426 && (GET_MODE (operands[0]) == TFmode
3427 || GET_MODE (operands[0]) == XFmode
3428 || GET_MODE (operands[0]) == DFmode)
3429 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3430 [(const_int 0)]
3431 "ix86_split_long_move (operands); DONE;")
3432
3433 (define_insn "swapxf"
3434 [(set (match_operand:XF 0 "register_operand" "+f")
3435 (match_operand:XF 1 "register_operand" "+f"))
3436 (set (match_dup 1)
3437 (match_dup 0))]
3438 "TARGET_80387"
3439 {
3440 if (STACK_TOP_P (operands[0]))
3441 return "fxch\t%1";
3442 else
3443 return "fxch\t%0";
3444 }
3445 [(set_attr "type" "fxch")
3446 (set_attr "mode" "XF")])
3447
3448 (define_insn "*swap<mode>"
3449 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3450 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3451 (set (match_dup 1)
3452 (match_dup 0))]
3453 "TARGET_80387 || reload_completed"
3454 {
3455 if (STACK_TOP_P (operands[0]))
3456 return "fxch\t%1";
3457 else
3458 return "fxch\t%0";
3459 }
3460 [(set_attr "type" "fxch")
3461 (set_attr "mode" "<MODE>")])
3462 \f
3463 ;; Zero extension instructions
3464
3465 (define_expand "zero_extendsidi2"
3466 [(set (match_operand:DI 0 "nonimmediate_operand")
3467 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3468
3469 (define_insn "*zero_extendsidi2_rex64"
3470 [(set (match_operand:DI 0 "nonimmediate_operand"
3471 "=r ,o,?*Ym,?*y,?*Yi,?*x")
3472 (zero_extend:DI
3473 (match_operand:SI 1 "x86_64_zext_general_operand"
3474 "rmWz,0,r ,m ,r ,m")))]
3475 "TARGET_64BIT"
3476 "@
3477 mov{l}\t{%1, %k0|%k0, %1}
3478 #
3479 movd\t{%1, %0|%0, %1}
3480 movd\t{%1, %0|%0, %1}
3481 %vmovd\t{%1, %0|%0, %1}
3482 %vmovd\t{%1, %0|%0, %1}"
3483 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3484 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3485 (set_attr "prefix_0f" "0,*,*,*,*,*")
3486 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3487
3488 (define_insn "*zero_extendsidi2"
3489 [(set (match_operand:DI 0 "nonimmediate_operand"
3490 "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3491 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3492 "0 ,rm,r ,r ,m ,r ,m")))]
3493 "!TARGET_64BIT"
3494 "@
3495 #
3496 #
3497 #
3498 movd\t{%1, %0|%0, %1}
3499 movd\t{%1, %0|%0, %1}
3500 %vmovd\t{%1, %0|%0, %1}
3501 %vmovd\t{%1, %0|%0, %1}"
3502 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3503 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3504 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3505 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3506
3507 (define_split
3508 [(set (match_operand:DI 0 "memory_operand")
3509 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3510 "reload_completed"
3511 [(set (match_dup 4) (const_int 0))]
3512 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3513
3514 (define_split
3515 [(set (match_operand:DI 0 "register_operand")
3516 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3517 "!TARGET_64BIT && reload_completed
3518 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3519 && true_regnum (operands[0]) == true_regnum (operands[1])"
3520 [(set (match_dup 4) (const_int 0))]
3521 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3522
3523 (define_split
3524 [(set (match_operand:DI 0 "nonimmediate_operand")
3525 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3526 "!TARGET_64BIT && reload_completed
3527 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3528 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3529 [(set (match_dup 3) (match_dup 1))
3530 (set (match_dup 4) (const_int 0))]
3531 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3532
3533 (define_insn "zero_extend<mode>di2"
3534 [(set (match_operand:DI 0 "register_operand" "=r")
3535 (zero_extend:DI
3536 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3537 "TARGET_64BIT"
3538 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3539 [(set_attr "type" "imovx")
3540 (set_attr "mode" "SI")])
3541
3542 (define_expand "zero_extend<mode>si2"
3543 [(set (match_operand:SI 0 "register_operand")
3544 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3545 ""
3546 {
3547 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3548 {
3549 operands[1] = force_reg (<MODE>mode, operands[1]);
3550 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3551 DONE;
3552 }
3553 })
3554
3555 (define_insn_and_split "zero_extend<mode>si2_and"
3556 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3557 (zero_extend:SI
3558 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3559 (clobber (reg:CC FLAGS_REG))]
3560 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3561 "#"
3562 "&& reload_completed"
3563 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3564 (clobber (reg:CC FLAGS_REG))])]
3565 {
3566 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3567 {
3568 ix86_expand_clear (operands[0]);
3569
3570 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3571 emit_insn (gen_movstrict<mode>
3572 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3573 DONE;
3574 }
3575
3576 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3577 }
3578 [(set_attr "type" "alu1")
3579 (set_attr "mode" "SI")])
3580
3581 (define_insn "*zero_extend<mode>si2"
3582 [(set (match_operand:SI 0 "register_operand" "=r")
3583 (zero_extend:SI
3584 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3585 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3586 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3587 [(set_attr "type" "imovx")
3588 (set_attr "mode" "SI")])
3589
3590 (define_expand "zero_extendqihi2"
3591 [(set (match_operand:HI 0 "register_operand")
3592 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3593 ""
3594 {
3595 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3596 {
3597 operands[1] = force_reg (QImode, operands[1]);
3598 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3599 DONE;
3600 }
3601 })
3602
3603 (define_insn_and_split "zero_extendqihi2_and"
3604 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3605 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3606 (clobber (reg:CC FLAGS_REG))]
3607 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3608 "#"
3609 "&& reload_completed"
3610 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3611 (clobber (reg:CC FLAGS_REG))])]
3612 {
3613 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3614 {
3615 ix86_expand_clear (operands[0]);
3616
3617 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3618 emit_insn (gen_movstrictqi
3619 (gen_lowpart (QImode, operands[0]), operands[1]));
3620 DONE;
3621 }
3622
3623 operands[0] = gen_lowpart (SImode, operands[0]);
3624 }
3625 [(set_attr "type" "alu1")
3626 (set_attr "mode" "SI")])
3627
3628 ; zero extend to SImode to avoid partial register stalls
3629 (define_insn "*zero_extendqihi2"
3630 [(set (match_operand:HI 0 "register_operand" "=r")
3631 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3632 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3633 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3634 [(set_attr "type" "imovx")
3635 (set_attr "mode" "SI")])
3636 \f
3637 ;; Sign extension instructions
3638
3639 (define_expand "extendsidi2"
3640 [(set (match_operand:DI 0 "register_operand")
3641 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3642 ""
3643 {
3644 if (!TARGET_64BIT)
3645 {
3646 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3647 DONE;
3648 }
3649 })
3650
3651 (define_insn "*extendsidi2_rex64"
3652 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3653 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3654 "TARGET_64BIT"
3655 "@
3656 {cltq|cdqe}
3657 movs{lq|x}\t{%1, %0|%0, %1}"
3658 [(set_attr "type" "imovx")
3659 (set_attr "mode" "DI")
3660 (set_attr "prefix_0f" "0")
3661 (set_attr "modrm" "0,1")])
3662
3663 (define_insn "extendsidi2_1"
3664 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3665 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3666 (clobber (reg:CC FLAGS_REG))
3667 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3668 "!TARGET_64BIT"
3669 "#")
3670
3671 ;; Extend to memory case when source register does die.
3672 (define_split
3673 [(set (match_operand:DI 0 "memory_operand")
3674 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3675 (clobber (reg:CC FLAGS_REG))
3676 (clobber (match_operand:SI 2 "register_operand"))]
3677 "(reload_completed
3678 && dead_or_set_p (insn, operands[1])
3679 && !reg_mentioned_p (operands[1], operands[0]))"
3680 [(set (match_dup 3) (match_dup 1))
3681 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3682 (clobber (reg:CC FLAGS_REG))])
3683 (set (match_dup 4) (match_dup 1))]
3684 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3685
3686 ;; Extend to memory case when source register does not die.
3687 (define_split
3688 [(set (match_operand:DI 0 "memory_operand")
3689 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3690 (clobber (reg:CC FLAGS_REG))
3691 (clobber (match_operand:SI 2 "register_operand"))]
3692 "reload_completed"
3693 [(const_int 0)]
3694 {
3695 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3696
3697 emit_move_insn (operands[3], operands[1]);
3698
3699 /* Generate a cltd if possible and doing so it profitable. */
3700 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3701 && true_regnum (operands[1]) == AX_REG
3702 && true_regnum (operands[2]) == DX_REG)
3703 {
3704 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3705 }
3706 else
3707 {
3708 emit_move_insn (operands[2], operands[1]);
3709 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3710 }
3711 emit_move_insn (operands[4], operands[2]);
3712 DONE;
3713 })
3714
3715 ;; Extend to register case. Optimize case where source and destination
3716 ;; registers match and cases where we can use cltd.
3717 (define_split
3718 [(set (match_operand:DI 0 "register_operand")
3719 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3720 (clobber (reg:CC FLAGS_REG))
3721 (clobber (match_scratch:SI 2))]
3722 "reload_completed"
3723 [(const_int 0)]
3724 {
3725 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3726
3727 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3728 emit_move_insn (operands[3], operands[1]);
3729
3730 /* Generate a cltd if possible and doing so it profitable. */
3731 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3732 && true_regnum (operands[3]) == AX_REG
3733 && true_regnum (operands[4]) == DX_REG)
3734 {
3735 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3736 DONE;
3737 }
3738
3739 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3740 emit_move_insn (operands[4], operands[1]);
3741
3742 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3743 DONE;
3744 })
3745
3746 (define_insn "extend<mode>di2"
3747 [(set (match_operand:DI 0 "register_operand" "=r")
3748 (sign_extend:DI
3749 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3750 "TARGET_64BIT"
3751 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3752 [(set_attr "type" "imovx")
3753 (set_attr "mode" "DI")])
3754
3755 (define_insn "extendhisi2"
3756 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3757 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3758 ""
3759 {
3760 switch (get_attr_prefix_0f (insn))
3761 {
3762 case 0:
3763 return "{cwtl|cwde}";
3764 default:
3765 return "movs{wl|x}\t{%1, %0|%0, %1}";
3766 }
3767 }
3768 [(set_attr "type" "imovx")
3769 (set_attr "mode" "SI")
3770 (set (attr "prefix_0f")
3771 ;; movsx is short decodable while cwtl is vector decoded.
3772 (if_then_else (and (eq_attr "cpu" "!k6")
3773 (eq_attr "alternative" "0"))
3774 (const_string "0")
3775 (const_string "1")))
3776 (set (attr "modrm")
3777 (if_then_else (eq_attr "prefix_0f" "0")
3778 (const_string "0")
3779 (const_string "1")))])
3780
3781 (define_insn "*extendhisi2_zext"
3782 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3783 (zero_extend:DI
3784 (sign_extend:SI
3785 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3786 "TARGET_64BIT"
3787 {
3788 switch (get_attr_prefix_0f (insn))
3789 {
3790 case 0:
3791 return "{cwtl|cwde}";
3792 default:
3793 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3794 }
3795 }
3796 [(set_attr "type" "imovx")
3797 (set_attr "mode" "SI")
3798 (set (attr "prefix_0f")
3799 ;; movsx is short decodable while cwtl is vector decoded.
3800 (if_then_else (and (eq_attr "cpu" "!k6")
3801 (eq_attr "alternative" "0"))
3802 (const_string "0")
3803 (const_string "1")))
3804 (set (attr "modrm")
3805 (if_then_else (eq_attr "prefix_0f" "0")
3806 (const_string "0")
3807 (const_string "1")))])
3808
3809 (define_insn "extendqisi2"
3810 [(set (match_operand:SI 0 "register_operand" "=r")
3811 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3812 ""
3813 "movs{bl|x}\t{%1, %0|%0, %1}"
3814 [(set_attr "type" "imovx")
3815 (set_attr "mode" "SI")])
3816
3817 (define_insn "*extendqisi2_zext"
3818 [(set (match_operand:DI 0 "register_operand" "=r")
3819 (zero_extend:DI
3820 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3821 "TARGET_64BIT"
3822 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3823 [(set_attr "type" "imovx")
3824 (set_attr "mode" "SI")])
3825
3826 (define_insn "extendqihi2"
3827 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3828 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3829 ""
3830 {
3831 switch (get_attr_prefix_0f (insn))
3832 {
3833 case 0:
3834 return "{cbtw|cbw}";
3835 default:
3836 return "movs{bw|x}\t{%1, %0|%0, %1}";
3837 }
3838 }
3839 [(set_attr "type" "imovx")
3840 (set_attr "mode" "HI")
3841 (set (attr "prefix_0f")
3842 ;; movsx is short decodable while cwtl is vector decoded.
3843 (if_then_else (and (eq_attr "cpu" "!k6")
3844 (eq_attr "alternative" "0"))
3845 (const_string "0")
3846 (const_string "1")))
3847 (set (attr "modrm")
3848 (if_then_else (eq_attr "prefix_0f" "0")
3849 (const_string "0")
3850 (const_string "1")))])
3851 \f
3852 ;; Conversions between float and double.
3853
3854 ;; These are all no-ops in the model used for the 80387.
3855 ;; So just emit moves.
3856
3857 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3858 (define_split
3859 [(set (match_operand:DF 0 "push_operand")
3860 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3861 "reload_completed"
3862 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3863 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3864
3865 (define_split
3866 [(set (match_operand:XF 0 "push_operand")
3867 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3868 "reload_completed"
3869 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3870 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3871 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3872
3873 (define_expand "extendsfdf2"
3874 [(set (match_operand:DF 0 "nonimmediate_operand")
3875 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3876 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3877 {
3878 /* ??? Needed for compress_float_constant since all fp constants
3879 are TARGET_LEGITIMATE_CONSTANT_P. */
3880 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3881 {
3882 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3883 && standard_80387_constant_p (operands[1]) > 0)
3884 {
3885 operands[1] = simplify_const_unary_operation
3886 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3887 emit_move_insn_1 (operands[0], operands[1]);
3888 DONE;
3889 }
3890 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3891 }
3892 })
3893
3894 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3895 cvtss2sd:
3896 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3897 cvtps2pd xmm2,xmm1
3898 We do the conversion post reload to avoid producing of 128bit spills
3899 that might lead to ICE on 32bit target. The sequence unlikely combine
3900 anyway. */
3901 (define_split
3902 [(set (match_operand:DF 0 "register_operand")
3903 (float_extend:DF
3904 (match_operand:SF 1 "nonimmediate_operand")))]
3905 "TARGET_USE_VECTOR_FP_CONVERTS
3906 && optimize_insn_for_speed_p ()
3907 && reload_completed && SSE_REG_P (operands[0])"
3908 [(set (match_dup 2)
3909 (float_extend:V2DF
3910 (vec_select:V2SF
3911 (match_dup 3)
3912 (parallel [(const_int 0) (const_int 1)]))))]
3913 {
3914 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3915 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3916 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3917 Try to avoid move when unpacking can be done in source. */
3918 if (REG_P (operands[1]))
3919 {
3920 /* If it is unsafe to overwrite upper half of source, we need
3921 to move to destination and unpack there. */
3922 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3923 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3924 && true_regnum (operands[0]) != true_regnum (operands[1]))
3925 {
3926 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3927 emit_move_insn (tmp, operands[1]);
3928 }
3929 else
3930 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3931 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3932 operands[3]));
3933 }
3934 else
3935 emit_insn (gen_vec_setv4sf_0 (operands[3],
3936 CONST0_RTX (V4SFmode), operands[1]));
3937 })
3938
3939 (define_insn "*extendsfdf2_mixed"
3940 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3941 (float_extend:DF
3942 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3943 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3944 {
3945 switch (which_alternative)
3946 {
3947 case 0:
3948 case 1:
3949 return output_387_reg_move (insn, operands);
3950
3951 case 2:
3952 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3953
3954 default:
3955 gcc_unreachable ();
3956 }
3957 }
3958 [(set_attr "type" "fmov,fmov,ssecvt")
3959 (set_attr "prefix" "orig,orig,maybe_vex")
3960 (set_attr "mode" "SF,XF,DF")])
3961
3962 (define_insn "*extendsfdf2_sse"
3963 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3964 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3965 "TARGET_SSE2 && TARGET_SSE_MATH"
3966 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3967 [(set_attr "type" "ssecvt")
3968 (set_attr "prefix" "maybe_vex")
3969 (set_attr "mode" "DF")])
3970
3971 (define_insn "*extendsfdf2_i387"
3972 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3973 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3974 "TARGET_80387"
3975 "* return output_387_reg_move (insn, operands);"
3976 [(set_attr "type" "fmov")
3977 (set_attr "mode" "SF,XF")])
3978
3979 (define_expand "extend<mode>xf2"
3980 [(set (match_operand:XF 0 "nonimmediate_operand")
3981 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3982 "TARGET_80387"
3983 {
3984 /* ??? Needed for compress_float_constant since all fp constants
3985 are TARGET_LEGITIMATE_CONSTANT_P. */
3986 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3987 {
3988 if (standard_80387_constant_p (operands[1]) > 0)
3989 {
3990 operands[1] = simplify_const_unary_operation
3991 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3992 emit_move_insn_1 (operands[0], operands[1]);
3993 DONE;
3994 }
3995 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3996 }
3997 })
3998
3999 (define_insn "*extend<mode>xf2_i387"
4000 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4001 (float_extend:XF
4002 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4003 "TARGET_80387"
4004 "* return output_387_reg_move (insn, operands);"
4005 [(set_attr "type" "fmov")
4006 (set_attr "mode" "<MODE>,XF")])
4007
4008 ;; %%% This seems bad bad news.
4009 ;; This cannot output into an f-reg because there is no way to be sure
4010 ;; of truncating in that case. Otherwise this is just like a simple move
4011 ;; insn. So we pretend we can output to a reg in order to get better
4012 ;; register preferencing, but we really use a stack slot.
4013
4014 ;; Conversion from DFmode to SFmode.
4015
4016 (define_expand "truncdfsf2"
4017 [(set (match_operand:SF 0 "nonimmediate_operand")
4018 (float_truncate:SF
4019 (match_operand:DF 1 "nonimmediate_operand")))]
4020 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4021 {
4022 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4023 ;
4024 else if (flag_unsafe_math_optimizations)
4025 ;
4026 else
4027 {
4028 enum ix86_stack_slot slot = (virtuals_instantiated
4029 ? SLOT_TEMP
4030 : SLOT_VIRTUAL);
4031 rtx temp = assign_386_stack_local (SFmode, slot);
4032 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4033 DONE;
4034 }
4035 })
4036
4037 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4038 cvtsd2ss:
4039 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4040 cvtpd2ps xmm2,xmm1
4041 We do the conversion post reload to avoid producing of 128bit spills
4042 that might lead to ICE on 32bit target. The sequence unlikely combine
4043 anyway. */
4044 (define_split
4045 [(set (match_operand:SF 0 "register_operand")
4046 (float_truncate:SF
4047 (match_operand:DF 1 "nonimmediate_operand")))]
4048 "TARGET_USE_VECTOR_FP_CONVERTS
4049 && optimize_insn_for_speed_p ()
4050 && reload_completed && SSE_REG_P (operands[0])"
4051 [(set (match_dup 2)
4052 (vec_concat:V4SF
4053 (float_truncate:V2SF
4054 (match_dup 4))
4055 (match_dup 3)))]
4056 {
4057 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4058 operands[3] = CONST0_RTX (V2SFmode);
4059 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4060 /* Use movsd for loading from memory, unpcklpd for registers.
4061 Try to avoid move when unpacking can be done in source, or SSE3
4062 movddup is available. */
4063 if (REG_P (operands[1]))
4064 {
4065 if (!TARGET_SSE3
4066 && true_regnum (operands[0]) != true_regnum (operands[1])
4067 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4068 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4069 {
4070 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4071 emit_move_insn (tmp, operands[1]);
4072 operands[1] = tmp;
4073 }
4074 else if (!TARGET_SSE3)
4075 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4076 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4077 }
4078 else
4079 emit_insn (gen_sse2_loadlpd (operands[4],
4080 CONST0_RTX (V2DFmode), operands[1]));
4081 })
4082
4083 (define_expand "truncdfsf2_with_temp"
4084 [(parallel [(set (match_operand:SF 0)
4085 (float_truncate:SF (match_operand:DF 1)))
4086 (clobber (match_operand:SF 2))])])
4087
4088 (define_insn "*truncdfsf_fast_mixed"
4089 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4090 (float_truncate:SF
4091 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4092 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4093 {
4094 switch (which_alternative)
4095 {
4096 case 0:
4097 return output_387_reg_move (insn, operands);
4098 case 1:
4099 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4100 default:
4101 gcc_unreachable ();
4102 }
4103 }
4104 [(set_attr "type" "fmov,ssecvt")
4105 (set_attr "prefix" "orig,maybe_vex")
4106 (set_attr "mode" "SF")])
4107
4108 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4109 ;; because nothing we do here is unsafe.
4110 (define_insn "*truncdfsf_fast_sse"
4111 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4112 (float_truncate:SF
4113 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4114 "TARGET_SSE2 && TARGET_SSE_MATH"
4115 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4116 [(set_attr "type" "ssecvt")
4117 (set_attr "prefix" "maybe_vex")
4118 (set_attr "mode" "SF")])
4119
4120 (define_insn "*truncdfsf_fast_i387"
4121 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4122 (float_truncate:SF
4123 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4124 "TARGET_80387 && flag_unsafe_math_optimizations"
4125 "* return output_387_reg_move (insn, operands);"
4126 [(set_attr "type" "fmov")
4127 (set_attr "mode" "SF")])
4128
4129 (define_insn "*truncdfsf_mixed"
4130 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4131 (float_truncate:SF
4132 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4133 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4134 "TARGET_MIX_SSE_I387"
4135 {
4136 switch (which_alternative)
4137 {
4138 case 0:
4139 return output_387_reg_move (insn, operands);
4140 case 1:
4141 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4142
4143 default:
4144 return "#";
4145 }
4146 }
4147 [(set_attr "isa" "*,sse2,*,*,*")
4148 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4149 (set_attr "unit" "*,*,i387,i387,i387")
4150 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4151 (set_attr "mode" "SF")])
4152
4153 (define_insn "*truncdfsf_i387"
4154 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4155 (float_truncate:SF
4156 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4157 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4158 "TARGET_80387"
4159 {
4160 switch (which_alternative)
4161 {
4162 case 0:
4163 return output_387_reg_move (insn, operands);
4164
4165 default:
4166 return "#";
4167 }
4168 }
4169 [(set_attr "type" "fmov,multi,multi,multi")
4170 (set_attr "unit" "*,i387,i387,i387")
4171 (set_attr "mode" "SF")])
4172
4173 (define_insn "*truncdfsf2_i387_1"
4174 [(set (match_operand:SF 0 "memory_operand" "=m")
4175 (float_truncate:SF
4176 (match_operand:DF 1 "register_operand" "f")))]
4177 "TARGET_80387
4178 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4179 && !TARGET_MIX_SSE_I387"
4180 "* return output_387_reg_move (insn, operands);"
4181 [(set_attr "type" "fmov")
4182 (set_attr "mode" "SF")])
4183
4184 (define_split
4185 [(set (match_operand:SF 0 "register_operand")
4186 (float_truncate:SF
4187 (match_operand:DF 1 "fp_register_operand")))
4188 (clobber (match_operand 2))]
4189 "reload_completed"
4190 [(set (match_dup 2) (match_dup 1))
4191 (set (match_dup 0) (match_dup 2))]
4192 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4193
4194 ;; Conversion from XFmode to {SF,DF}mode
4195
4196 (define_expand "truncxf<mode>2"
4197 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4198 (float_truncate:MODEF
4199 (match_operand:XF 1 "register_operand")))
4200 (clobber (match_dup 2))])]
4201 "TARGET_80387"
4202 {
4203 if (flag_unsafe_math_optimizations)
4204 {
4205 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4206 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4207 if (reg != operands[0])
4208 emit_move_insn (operands[0], reg);
4209 DONE;
4210 }
4211 else
4212 {
4213 enum ix86_stack_slot slot = (virtuals_instantiated
4214 ? SLOT_TEMP
4215 : SLOT_VIRTUAL);
4216 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4217 }
4218 })
4219
4220 (define_insn "*truncxfsf2_mixed"
4221 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4222 (float_truncate:SF
4223 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4224 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4225 "TARGET_80387"
4226 {
4227 gcc_assert (!which_alternative);
4228 return output_387_reg_move (insn, operands);
4229 }
4230 [(set_attr "type" "fmov,multi,multi,multi")
4231 (set_attr "unit" "*,i387,i387,i387")
4232 (set_attr "mode" "SF")])
4233
4234 (define_insn "*truncxfdf2_mixed"
4235 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4236 (float_truncate:DF
4237 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4238 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4239 "TARGET_80387"
4240 {
4241 gcc_assert (!which_alternative);
4242 return output_387_reg_move (insn, operands);
4243 }
4244 [(set_attr "isa" "*,*,sse2,*")
4245 (set_attr "type" "fmov,multi,multi,multi")
4246 (set_attr "unit" "*,i387,i387,i387")
4247 (set_attr "mode" "DF")])
4248
4249 (define_insn "truncxf<mode>2_i387_noop"
4250 [(set (match_operand:MODEF 0 "register_operand" "=f")
4251 (float_truncate:MODEF
4252 (match_operand:XF 1 "register_operand" "f")))]
4253 "TARGET_80387 && flag_unsafe_math_optimizations"
4254 "* return output_387_reg_move (insn, operands);"
4255 [(set_attr "type" "fmov")
4256 (set_attr "mode" "<MODE>")])
4257
4258 (define_insn "*truncxf<mode>2_i387"
4259 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4260 (float_truncate:MODEF
4261 (match_operand:XF 1 "register_operand" "f")))]
4262 "TARGET_80387"
4263 "* return output_387_reg_move (insn, operands);"
4264 [(set_attr "type" "fmov")
4265 (set_attr "mode" "<MODE>")])
4266
4267 (define_split
4268 [(set (match_operand:MODEF 0 "register_operand")
4269 (float_truncate:MODEF
4270 (match_operand:XF 1 "register_operand")))
4271 (clobber (match_operand:MODEF 2 "memory_operand"))]
4272 "TARGET_80387 && reload_completed"
4273 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4274 (set (match_dup 0) (match_dup 2))])
4275
4276 (define_split
4277 [(set (match_operand:MODEF 0 "memory_operand")
4278 (float_truncate:MODEF
4279 (match_operand:XF 1 "register_operand")))
4280 (clobber (match_operand:MODEF 2 "memory_operand"))]
4281 "TARGET_80387"
4282 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4283 \f
4284 ;; Signed conversion to DImode.
4285
4286 (define_expand "fix_truncxfdi2"
4287 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4288 (fix:DI (match_operand:XF 1 "register_operand")))
4289 (clobber (reg:CC FLAGS_REG))])]
4290 "TARGET_80387"
4291 {
4292 if (TARGET_FISTTP)
4293 {
4294 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4295 DONE;
4296 }
4297 })
4298
4299 (define_expand "fix_trunc<mode>di2"
4300 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4301 (fix:DI (match_operand:MODEF 1 "register_operand")))
4302 (clobber (reg:CC FLAGS_REG))])]
4303 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4304 {
4305 if (TARGET_FISTTP
4306 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4307 {
4308 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4309 DONE;
4310 }
4311 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4312 {
4313 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4314 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4315 if (out != operands[0])
4316 emit_move_insn (operands[0], out);
4317 DONE;
4318 }
4319 })
4320
4321 ;; Signed conversion to SImode.
4322
4323 (define_expand "fix_truncxfsi2"
4324 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4325 (fix:SI (match_operand:XF 1 "register_operand")))
4326 (clobber (reg:CC FLAGS_REG))])]
4327 "TARGET_80387"
4328 {
4329 if (TARGET_FISTTP)
4330 {
4331 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4332 DONE;
4333 }
4334 })
4335
4336 (define_expand "fix_trunc<mode>si2"
4337 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4338 (fix:SI (match_operand:MODEF 1 "register_operand")))
4339 (clobber (reg:CC FLAGS_REG))])]
4340 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4341 {
4342 if (TARGET_FISTTP
4343 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4344 {
4345 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4346 DONE;
4347 }
4348 if (SSE_FLOAT_MODE_P (<MODE>mode))
4349 {
4350 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4351 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4352 if (out != operands[0])
4353 emit_move_insn (operands[0], out);
4354 DONE;
4355 }
4356 })
4357
4358 ;; Signed conversion to HImode.
4359
4360 (define_expand "fix_trunc<mode>hi2"
4361 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4362 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4363 (clobber (reg:CC FLAGS_REG))])]
4364 "TARGET_80387
4365 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4366 {
4367 if (TARGET_FISTTP)
4368 {
4369 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4370 DONE;
4371 }
4372 })
4373
4374 ;; Unsigned conversion to SImode.
4375
4376 (define_expand "fixuns_trunc<mode>si2"
4377 [(parallel
4378 [(set (match_operand:SI 0 "register_operand")
4379 (unsigned_fix:SI
4380 (match_operand:MODEF 1 "nonimmediate_operand")))
4381 (use (match_dup 2))
4382 (clobber (match_scratch:<ssevecmode> 3))
4383 (clobber (match_scratch:<ssevecmode> 4))])]
4384 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4385 {
4386 enum machine_mode mode = <MODE>mode;
4387 enum machine_mode vecmode = <ssevecmode>mode;
4388 REAL_VALUE_TYPE TWO31r;
4389 rtx two31;
4390
4391 if (optimize_insn_for_size_p ())
4392 FAIL;
4393
4394 real_ldexp (&TWO31r, &dconst1, 31);
4395 two31 = const_double_from_real_value (TWO31r, mode);
4396 two31 = ix86_build_const_vector (vecmode, true, two31);
4397 operands[2] = force_reg (vecmode, two31);
4398 })
4399
4400 (define_insn_and_split "*fixuns_trunc<mode>_1"
4401 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4402 (unsigned_fix:SI
4403 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4404 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4405 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4406 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4407 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4408 && optimize_function_for_speed_p (cfun)"
4409 "#"
4410 "&& reload_completed"
4411 [(const_int 0)]
4412 {
4413 ix86_split_convert_uns_si_sse (operands);
4414 DONE;
4415 })
4416
4417 ;; Unsigned conversion to HImode.
4418 ;; Without these patterns, we'll try the unsigned SI conversion which
4419 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4420
4421 (define_expand "fixuns_trunc<mode>hi2"
4422 [(set (match_dup 2)
4423 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4424 (set (match_operand:HI 0 "nonimmediate_operand")
4425 (subreg:HI (match_dup 2) 0))]
4426 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4427 "operands[2] = gen_reg_rtx (SImode);")
4428
4429 ;; When SSE is available, it is always faster to use it!
4430 (define_insn "fix_trunc<mode>di_sse"
4431 [(set (match_operand:DI 0 "register_operand" "=r,r")
4432 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4433 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4434 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4435 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4436 [(set_attr "type" "sseicvt")
4437 (set_attr "prefix" "maybe_vex")
4438 (set_attr "prefix_rex" "1")
4439 (set_attr "mode" "<MODE>")
4440 (set_attr "athlon_decode" "double,vector")
4441 (set_attr "amdfam10_decode" "double,double")
4442 (set_attr "bdver1_decode" "double,double")])
4443
4444 (define_insn "fix_trunc<mode>si_sse"
4445 [(set (match_operand:SI 0 "register_operand" "=r,r")
4446 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4447 "SSE_FLOAT_MODE_P (<MODE>mode)
4448 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4449 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4450 [(set_attr "type" "sseicvt")
4451 (set_attr "prefix" "maybe_vex")
4452 (set_attr "mode" "<MODE>")
4453 (set_attr "athlon_decode" "double,vector")
4454 (set_attr "amdfam10_decode" "double,double")
4455 (set_attr "bdver1_decode" "double,double")])
4456
4457 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4458 (define_peephole2
4459 [(set (match_operand:MODEF 0 "register_operand")
4460 (match_operand:MODEF 1 "memory_operand"))
4461 (set (match_operand:SWI48x 2 "register_operand")
4462 (fix:SWI48x (match_dup 0)))]
4463 "TARGET_SHORTEN_X87_SSE
4464 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4465 && peep2_reg_dead_p (2, operands[0])"
4466 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4467
4468 ;; Avoid vector decoded forms of the instruction.
4469 (define_peephole2
4470 [(match_scratch:DF 2 "x")
4471 (set (match_operand:SWI48x 0 "register_operand")
4472 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4473 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4474 [(set (match_dup 2) (match_dup 1))
4475 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4476
4477 (define_peephole2
4478 [(match_scratch:SF 2 "x")
4479 (set (match_operand:SWI48x 0 "register_operand")
4480 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4481 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4482 [(set (match_dup 2) (match_dup 1))
4483 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4484
4485 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4486 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4487 (fix:SWI248x (match_operand 1 "register_operand")))]
4488 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4489 && TARGET_FISTTP
4490 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4491 && (TARGET_64BIT || <MODE>mode != DImode))
4492 && TARGET_SSE_MATH)
4493 && can_create_pseudo_p ()"
4494 "#"
4495 "&& 1"
4496 [(const_int 0)]
4497 {
4498 if (memory_operand (operands[0], VOIDmode))
4499 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4500 else
4501 {
4502 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4503 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4504 operands[1],
4505 operands[2]));
4506 }
4507 DONE;
4508 }
4509 [(set_attr "type" "fisttp")
4510 (set_attr "mode" "<MODE>")])
4511
4512 (define_insn "fix_trunc<mode>_i387_fisttp"
4513 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4514 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4515 (clobber (match_scratch:XF 2 "=&1f"))]
4516 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4517 && TARGET_FISTTP
4518 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4519 && (TARGET_64BIT || <MODE>mode != DImode))
4520 && TARGET_SSE_MATH)"
4521 "* return output_fix_trunc (insn, operands, true);"
4522 [(set_attr "type" "fisttp")
4523 (set_attr "mode" "<MODE>")])
4524
4525 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4526 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4527 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4528 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4529 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4530 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4531 && TARGET_FISTTP
4532 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && (TARGET_64BIT || <MODE>mode != DImode))
4534 && TARGET_SSE_MATH)"
4535 "#"
4536 [(set_attr "type" "fisttp")
4537 (set_attr "mode" "<MODE>")])
4538
4539 (define_split
4540 [(set (match_operand:SWI248x 0 "register_operand")
4541 (fix:SWI248x (match_operand 1 "register_operand")))
4542 (clobber (match_operand:SWI248x 2 "memory_operand"))
4543 (clobber (match_scratch 3))]
4544 "reload_completed"
4545 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4546 (clobber (match_dup 3))])
4547 (set (match_dup 0) (match_dup 2))])
4548
4549 (define_split
4550 [(set (match_operand:SWI248x 0 "memory_operand")
4551 (fix:SWI248x (match_operand 1 "register_operand")))
4552 (clobber (match_operand:SWI248x 2 "memory_operand"))
4553 (clobber (match_scratch 3))]
4554 "reload_completed"
4555 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4556 (clobber (match_dup 3))])])
4557
4558 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4559 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4560 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4561 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4562 ;; function in i386.c.
4563 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4564 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4565 (fix:SWI248x (match_operand 1 "register_operand")))
4566 (clobber (reg:CC FLAGS_REG))]
4567 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4568 && !TARGET_FISTTP
4569 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4570 && (TARGET_64BIT || <MODE>mode != DImode))
4571 && can_create_pseudo_p ()"
4572 "#"
4573 "&& 1"
4574 [(const_int 0)]
4575 {
4576 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4577
4578 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4579 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4580 if (memory_operand (operands[0], VOIDmode))
4581 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4582 operands[2], operands[3]));
4583 else
4584 {
4585 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4586 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4587 operands[2], operands[3],
4588 operands[4]));
4589 }
4590 DONE;
4591 }
4592 [(set_attr "type" "fistp")
4593 (set_attr "i387_cw" "trunc")
4594 (set_attr "mode" "<MODE>")])
4595
4596 (define_insn "fix_truncdi_i387"
4597 [(set (match_operand:DI 0 "memory_operand" "=m")
4598 (fix:DI (match_operand 1 "register_operand" "f")))
4599 (use (match_operand:HI 2 "memory_operand" "m"))
4600 (use (match_operand:HI 3 "memory_operand" "m"))
4601 (clobber (match_scratch:XF 4 "=&1f"))]
4602 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4603 && !TARGET_FISTTP
4604 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4605 "* return output_fix_trunc (insn, operands, false);"
4606 [(set_attr "type" "fistp")
4607 (set_attr "i387_cw" "trunc")
4608 (set_attr "mode" "DI")])
4609
4610 (define_insn "fix_truncdi_i387_with_temp"
4611 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4612 (fix:DI (match_operand 1 "register_operand" "f,f")))
4613 (use (match_operand:HI 2 "memory_operand" "m,m"))
4614 (use (match_operand:HI 3 "memory_operand" "m,m"))
4615 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4616 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4617 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4618 && !TARGET_FISTTP
4619 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4620 "#"
4621 [(set_attr "type" "fistp")
4622 (set_attr "i387_cw" "trunc")
4623 (set_attr "mode" "DI")])
4624
4625 (define_split
4626 [(set (match_operand:DI 0 "register_operand")
4627 (fix:DI (match_operand 1 "register_operand")))
4628 (use (match_operand:HI 2 "memory_operand"))
4629 (use (match_operand:HI 3 "memory_operand"))
4630 (clobber (match_operand:DI 4 "memory_operand"))
4631 (clobber (match_scratch 5))]
4632 "reload_completed"
4633 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4634 (use (match_dup 2))
4635 (use (match_dup 3))
4636 (clobber (match_dup 5))])
4637 (set (match_dup 0) (match_dup 4))])
4638
4639 (define_split
4640 [(set (match_operand:DI 0 "memory_operand")
4641 (fix:DI (match_operand 1 "register_operand")))
4642 (use (match_operand:HI 2 "memory_operand"))
4643 (use (match_operand:HI 3 "memory_operand"))
4644 (clobber (match_operand:DI 4 "memory_operand"))
4645 (clobber (match_scratch 5))]
4646 "reload_completed"
4647 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4648 (use (match_dup 2))
4649 (use (match_dup 3))
4650 (clobber (match_dup 5))])])
4651
4652 (define_insn "fix_trunc<mode>_i387"
4653 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4654 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4655 (use (match_operand:HI 2 "memory_operand" "m"))
4656 (use (match_operand:HI 3 "memory_operand" "m"))]
4657 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4658 && !TARGET_FISTTP
4659 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4660 "* return output_fix_trunc (insn, operands, false);"
4661 [(set_attr "type" "fistp")
4662 (set_attr "i387_cw" "trunc")
4663 (set_attr "mode" "<MODE>")])
4664
4665 (define_insn "fix_trunc<mode>_i387_with_temp"
4666 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4667 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4668 (use (match_operand:HI 2 "memory_operand" "m,m"))
4669 (use (match_operand:HI 3 "memory_operand" "m,m"))
4670 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4671 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4672 && !TARGET_FISTTP
4673 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4674 "#"
4675 [(set_attr "type" "fistp")
4676 (set_attr "i387_cw" "trunc")
4677 (set_attr "mode" "<MODE>")])
4678
4679 (define_split
4680 [(set (match_operand:SWI24 0 "register_operand")
4681 (fix:SWI24 (match_operand 1 "register_operand")))
4682 (use (match_operand:HI 2 "memory_operand"))
4683 (use (match_operand:HI 3 "memory_operand"))
4684 (clobber (match_operand:SWI24 4 "memory_operand"))]
4685 "reload_completed"
4686 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4687 (use (match_dup 2))
4688 (use (match_dup 3))])
4689 (set (match_dup 0) (match_dup 4))])
4690
4691 (define_split
4692 [(set (match_operand:SWI24 0 "memory_operand")
4693 (fix:SWI24 (match_operand 1 "register_operand")))
4694 (use (match_operand:HI 2 "memory_operand"))
4695 (use (match_operand:HI 3 "memory_operand"))
4696 (clobber (match_operand:SWI24 4 "memory_operand"))]
4697 "reload_completed"
4698 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4699 (use (match_dup 2))
4700 (use (match_dup 3))])])
4701
4702 (define_insn "x86_fnstcw_1"
4703 [(set (match_operand:HI 0 "memory_operand" "=m")
4704 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4705 "TARGET_80387"
4706 "fnstcw\t%0"
4707 [(set (attr "length")
4708 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4709 (set_attr "mode" "HI")
4710 (set_attr "unit" "i387")
4711 (set_attr "bdver1_decode" "vector")])
4712
4713 (define_insn "x86_fldcw_1"
4714 [(set (reg:HI FPCR_REG)
4715 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4716 "TARGET_80387"
4717 "fldcw\t%0"
4718 [(set (attr "length")
4719 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4720 (set_attr "mode" "HI")
4721 (set_attr "unit" "i387")
4722 (set_attr "athlon_decode" "vector")
4723 (set_attr "amdfam10_decode" "vector")
4724 (set_attr "bdver1_decode" "vector")])
4725 \f
4726 ;; Conversion between fixed point and floating point.
4727
4728 ;; Even though we only accept memory inputs, the backend _really_
4729 ;; wants to be able to do this between registers.
4730
4731 (define_expand "floathi<mode>2"
4732 [(set (match_operand:X87MODEF 0 "register_operand")
4733 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4734 "TARGET_80387
4735 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4736 || TARGET_MIX_SSE_I387)")
4737
4738 ;; Pre-reload splitter to add memory clobber to the pattern.
4739 (define_insn_and_split "*floathi<mode>2_1"
4740 [(set (match_operand:X87MODEF 0 "register_operand")
4741 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4742 "TARGET_80387
4743 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4744 || TARGET_MIX_SSE_I387)
4745 && can_create_pseudo_p ()"
4746 "#"
4747 "&& 1"
4748 [(parallel [(set (match_dup 0)
4749 (float:X87MODEF (match_dup 1)))
4750 (clobber (match_dup 2))])]
4751 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4752
4753 (define_insn "*floathi<mode>2_i387_with_temp"
4754 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4755 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4756 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4757 "TARGET_80387
4758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4759 || TARGET_MIX_SSE_I387)"
4760 "#"
4761 [(set_attr "type" "fmov,multi")
4762 (set_attr "mode" "<MODE>")
4763 (set_attr "unit" "*,i387")
4764 (set_attr "fp_int_src" "true")])
4765
4766 (define_insn "*floathi<mode>2_i387"
4767 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4768 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4769 "TARGET_80387
4770 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4771 || TARGET_MIX_SSE_I387)"
4772 "fild%Z1\t%1"
4773 [(set_attr "type" "fmov")
4774 (set_attr "mode" "<MODE>")
4775 (set_attr "fp_int_src" "true")])
4776
4777 (define_split
4778 [(set (match_operand:X87MODEF 0 "register_operand")
4779 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4780 (clobber (match_operand:HI 2 "memory_operand"))]
4781 "TARGET_80387
4782 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4783 || TARGET_MIX_SSE_I387)
4784 && reload_completed"
4785 [(set (match_dup 2) (match_dup 1))
4786 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4787
4788 (define_split
4789 [(set (match_operand:X87MODEF 0 "register_operand")
4790 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4791 (clobber (match_operand:HI 2 "memory_operand"))]
4792 "TARGET_80387
4793 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4794 || TARGET_MIX_SSE_I387)
4795 && reload_completed"
4796 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4797
4798 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4799 [(set (match_operand:X87MODEF 0 "register_operand")
4800 (float:X87MODEF
4801 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4802 "TARGET_80387
4803 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4804 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4805 {
4806 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4807 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4808 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4809 {
4810 rtx reg = gen_reg_rtx (XFmode);
4811 rtx (*insn)(rtx, rtx);
4812
4813 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4814
4815 if (<X87MODEF:MODE>mode == SFmode)
4816 insn = gen_truncxfsf2;
4817 else if (<X87MODEF:MODE>mode == DFmode)
4818 insn = gen_truncxfdf2;
4819 else
4820 gcc_unreachable ();
4821
4822 emit_insn (insn (operands[0], reg));
4823 DONE;
4824 }
4825 })
4826
4827 ;; Pre-reload splitter to add memory clobber to the pattern.
4828 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4829 [(set (match_operand:X87MODEF 0 "register_operand")
4830 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4831 "((TARGET_80387
4832 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4833 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4834 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4835 || TARGET_MIX_SSE_I387))
4836 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4837 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4838 && ((<SWI48x:MODE>mode == SImode
4839 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4840 && optimize_function_for_speed_p (cfun)
4841 && flag_trapping_math)
4842 || !(TARGET_INTER_UNIT_CONVERSIONS
4843 || optimize_function_for_size_p (cfun)))))
4844 && can_create_pseudo_p ()"
4845 "#"
4846 "&& 1"
4847 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4848 (clobber (match_dup 2))])]
4849 {
4850 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4851
4852 /* Avoid store forwarding (partial memory) stall penalty
4853 by passing DImode value through XMM registers. */
4854 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4855 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4856 && optimize_function_for_speed_p (cfun))
4857 {
4858 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4859 operands[1],
4860 operands[2]));
4861 DONE;
4862 }
4863 })
4864
4865 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4866 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4867 (float:MODEF
4868 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4869 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4870 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4871 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4872 "#"
4873 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4874 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4875 (set_attr "unit" "*,i387,*,*,*")
4876 (set_attr "athlon_decode" "*,*,double,direct,double")
4877 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4878 (set_attr "bdver1_decode" "*,*,double,direct,double")
4879 (set_attr "fp_int_src" "true")])
4880
4881 (define_insn "*floatsi<mode>2_vector_mixed"
4882 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4883 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4884 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4885 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4886 "@
4887 fild%Z1\t%1
4888 #"
4889 [(set_attr "type" "fmov,sseicvt")
4890 (set_attr "mode" "<MODE>,<ssevecmode>")
4891 (set_attr "unit" "i387,*")
4892 (set_attr "athlon_decode" "*,direct")
4893 (set_attr "amdfam10_decode" "*,double")
4894 (set_attr "bdver1_decode" "*,direct")
4895 (set_attr "fp_int_src" "true")])
4896
4897 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4898 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4899 (float:MODEF
4900 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4901 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4902 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4903 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4904 "#"
4905 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4906 (set_attr "mode" "<MODEF:MODE>")
4907 (set_attr "unit" "*,i387,*,*")
4908 (set_attr "athlon_decode" "*,*,double,direct")
4909 (set_attr "amdfam10_decode" "*,*,vector,double")
4910 (set_attr "bdver1_decode" "*,*,double,direct")
4911 (set_attr "fp_int_src" "true")])
4912
4913 (define_split
4914 [(set (match_operand:MODEF 0 "register_operand")
4915 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4916 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4917 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4918 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4919 && TARGET_INTER_UNIT_CONVERSIONS
4920 && reload_completed
4921 && (SSE_REG_P (operands[0])
4922 || (GET_CODE (operands[0]) == SUBREG
4923 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4924 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4925
4926 (define_split
4927 [(set (match_operand:MODEF 0 "register_operand")
4928 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4929 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4930 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4931 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4932 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4933 && reload_completed
4934 && (SSE_REG_P (operands[0])
4935 || (GET_CODE (operands[0]) == SUBREG
4936 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4937 [(set (match_dup 2) (match_dup 1))
4938 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4939
4940 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4941 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4942 (float:MODEF
4943 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4944 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4945 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4946 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4947 "@
4948 fild%Z1\t%1
4949 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4950 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4951 [(set_attr "type" "fmov,sseicvt,sseicvt")
4952 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4953 (set_attr "mode" "<MODEF:MODE>")
4954 (set (attr "prefix_rex")
4955 (if_then_else
4956 (and (eq_attr "prefix" "maybe_vex")
4957 (match_test "<SWI48x:MODE>mode == DImode"))
4958 (const_string "1")
4959 (const_string "*")))
4960 (set_attr "unit" "i387,*,*")
4961 (set_attr "athlon_decode" "*,double,direct")
4962 (set_attr "amdfam10_decode" "*,vector,double")
4963 (set_attr "bdver1_decode" "*,double,direct")
4964 (set_attr "fp_int_src" "true")])
4965
4966 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4967 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4968 (float:MODEF
4969 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4970 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4971 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4972 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4973 "@
4974 fild%Z1\t%1
4975 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4976 [(set_attr "type" "fmov,sseicvt")
4977 (set_attr "prefix" "orig,maybe_vex")
4978 (set_attr "mode" "<MODEF:MODE>")
4979 (set (attr "prefix_rex")
4980 (if_then_else
4981 (and (eq_attr "prefix" "maybe_vex")
4982 (match_test "<SWI48x:MODE>mode == DImode"))
4983 (const_string "1")
4984 (const_string "*")))
4985 (set_attr "athlon_decode" "*,direct")
4986 (set_attr "amdfam10_decode" "*,double")
4987 (set_attr "bdver1_decode" "*,direct")
4988 (set_attr "fp_int_src" "true")])
4989
4990 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4991 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4992 (float:MODEF
4993 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4994 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4995 "TARGET_SSE2 && TARGET_SSE_MATH
4996 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4997 "#"
4998 [(set_attr "type" "sseicvt")
4999 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5000 (set_attr "athlon_decode" "double,direct,double")
5001 (set_attr "amdfam10_decode" "vector,double,double")
5002 (set_attr "bdver1_decode" "double,direct,double")
5003 (set_attr "fp_int_src" "true")])
5004
5005 (define_insn "*floatsi<mode>2_vector_sse"
5006 [(set (match_operand:MODEF 0 "register_operand" "=x")
5007 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5008 "TARGET_SSE2 && TARGET_SSE_MATH
5009 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5010 "#"
5011 [(set_attr "type" "sseicvt")
5012 (set_attr "mode" "<MODE>")
5013 (set_attr "athlon_decode" "direct")
5014 (set_attr "amdfam10_decode" "double")
5015 (set_attr "bdver1_decode" "direct")
5016 (set_attr "fp_int_src" "true")])
5017
5018 (define_split
5019 [(set (match_operand:MODEF 0 "register_operand")
5020 (float:MODEF (match_operand:SI 1 "register_operand")))
5021 (clobber (match_operand:SI 2 "memory_operand"))]
5022 "TARGET_SSE2 && TARGET_SSE_MATH
5023 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5024 && reload_completed
5025 && (SSE_REG_P (operands[0])
5026 || (GET_CODE (operands[0]) == SUBREG
5027 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5028 [(const_int 0)]
5029 {
5030 rtx op1 = operands[1];
5031
5032 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5033 <MODE>mode, 0);
5034 if (GET_CODE (op1) == SUBREG)
5035 op1 = SUBREG_REG (op1);
5036
5037 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5038 {
5039 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5040 emit_insn (gen_sse2_loadld (operands[4],
5041 CONST0_RTX (V4SImode), operands[1]));
5042 }
5043 /* We can ignore possible trapping value in the
5044 high part of SSE register for non-trapping math. */
5045 else if (SSE_REG_P (op1) && !flag_trapping_math)
5046 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5047 else
5048 {
5049 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5050 emit_move_insn (operands[2], operands[1]);
5051 emit_insn (gen_sse2_loadld (operands[4],
5052 CONST0_RTX (V4SImode), operands[2]));
5053 }
5054 if (<ssevecmode>mode == V4SFmode)
5055 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5056 else
5057 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5058 DONE;
5059 })
5060
5061 (define_split
5062 [(set (match_operand:MODEF 0 "register_operand")
5063 (float:MODEF (match_operand:SI 1 "memory_operand")))
5064 (clobber (match_operand:SI 2 "memory_operand"))]
5065 "TARGET_SSE2 && TARGET_SSE_MATH
5066 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5067 && reload_completed
5068 && (SSE_REG_P (operands[0])
5069 || (GET_CODE (operands[0]) == SUBREG
5070 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5071 [(const_int 0)]
5072 {
5073 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5074 <MODE>mode, 0);
5075 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5076
5077 emit_insn (gen_sse2_loadld (operands[4],
5078 CONST0_RTX (V4SImode), operands[1]));
5079 if (<ssevecmode>mode == V4SFmode)
5080 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5081 else
5082 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5083 DONE;
5084 })
5085
5086 (define_split
5087 [(set (match_operand:MODEF 0 "register_operand")
5088 (float:MODEF (match_operand:SI 1 "register_operand")))]
5089 "TARGET_SSE2 && TARGET_SSE_MATH
5090 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5091 && reload_completed
5092 && (SSE_REG_P (operands[0])
5093 || (GET_CODE (operands[0]) == SUBREG
5094 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5095 [(const_int 0)]
5096 {
5097 rtx op1 = operands[1];
5098
5099 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5100 <MODE>mode, 0);
5101 if (GET_CODE (op1) == SUBREG)
5102 op1 = SUBREG_REG (op1);
5103
5104 if (GENERAL_REG_P (op1))
5105 {
5106 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5107 if (TARGET_INTER_UNIT_MOVES)
5108 emit_insn (gen_sse2_loadld (operands[4],
5109 CONST0_RTX (V4SImode), operands[1]));
5110 else
5111 {
5112 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5113 operands[1]);
5114 emit_insn (gen_sse2_loadld (operands[4],
5115 CONST0_RTX (V4SImode), operands[5]));
5116 ix86_free_from_memory (GET_MODE (operands[1]));
5117 }
5118 }
5119 /* We can ignore possible trapping value in the
5120 high part of SSE register for non-trapping math. */
5121 else if (SSE_REG_P (op1) && !flag_trapping_math)
5122 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5123 else
5124 gcc_unreachable ();
5125 if (<ssevecmode>mode == V4SFmode)
5126 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5127 else
5128 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5129 DONE;
5130 })
5131
5132 (define_split
5133 [(set (match_operand:MODEF 0 "register_operand")
5134 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5135 "TARGET_SSE2 && TARGET_SSE_MATH
5136 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5137 && reload_completed
5138 && (SSE_REG_P (operands[0])
5139 || (GET_CODE (operands[0]) == SUBREG
5140 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5141 [(const_int 0)]
5142 {
5143 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5144 <MODE>mode, 0);
5145 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5146
5147 emit_insn (gen_sse2_loadld (operands[4],
5148 CONST0_RTX (V4SImode), operands[1]));
5149 if (<ssevecmode>mode == V4SFmode)
5150 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5151 else
5152 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5153 DONE;
5154 })
5155
5156 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5157 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5158 (float:MODEF
5159 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5160 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5161 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5162 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5163 "#"
5164 [(set_attr "type" "sseicvt")
5165 (set_attr "mode" "<MODEF:MODE>")
5166 (set_attr "athlon_decode" "double,direct")
5167 (set_attr "amdfam10_decode" "vector,double")
5168 (set_attr "bdver1_decode" "double,direct")
5169 (set_attr "fp_int_src" "true")])
5170
5171 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5172 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5173 (float:MODEF
5174 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5175 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5176 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5177 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5178 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5179 [(set_attr "type" "sseicvt")
5180 (set_attr "prefix" "maybe_vex")
5181 (set_attr "mode" "<MODEF:MODE>")
5182 (set (attr "prefix_rex")
5183 (if_then_else
5184 (and (eq_attr "prefix" "maybe_vex")
5185 (match_test "<SWI48x:MODE>mode == DImode"))
5186 (const_string "1")
5187 (const_string "*")))
5188 (set_attr "athlon_decode" "double,direct")
5189 (set_attr "amdfam10_decode" "vector,double")
5190 (set_attr "bdver1_decode" "double,direct")
5191 (set_attr "fp_int_src" "true")])
5192
5193 (define_split
5194 [(set (match_operand:MODEF 0 "register_operand")
5195 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5196 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5197 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5198 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5199 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5200 && reload_completed
5201 && (SSE_REG_P (operands[0])
5202 || (GET_CODE (operands[0]) == SUBREG
5203 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5204 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5205
5206 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5207 [(set (match_operand:MODEF 0 "register_operand" "=x")
5208 (float:MODEF
5209 (match_operand:SWI48x 1 "memory_operand" "m")))]
5210 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5211 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5212 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5213 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5214 [(set_attr "type" "sseicvt")
5215 (set_attr "prefix" "maybe_vex")
5216 (set_attr "mode" "<MODEF:MODE>")
5217 (set (attr "prefix_rex")
5218 (if_then_else
5219 (and (eq_attr "prefix" "maybe_vex")
5220 (match_test "<SWI48x:MODE>mode == DImode"))
5221 (const_string "1")
5222 (const_string "*")))
5223 (set_attr "athlon_decode" "direct")
5224 (set_attr "amdfam10_decode" "double")
5225 (set_attr "bdver1_decode" "direct")
5226 (set_attr "fp_int_src" "true")])
5227
5228 (define_split
5229 [(set (match_operand:MODEF 0 "register_operand")
5230 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5231 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5232 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5233 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5234 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5235 && reload_completed
5236 && (SSE_REG_P (operands[0])
5237 || (GET_CODE (operands[0]) == SUBREG
5238 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5239 [(set (match_dup 2) (match_dup 1))
5240 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5241
5242 (define_split
5243 [(set (match_operand:MODEF 0 "register_operand")
5244 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5245 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5246 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5247 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5248 && reload_completed
5249 && (SSE_REG_P (operands[0])
5250 || (GET_CODE (operands[0]) == SUBREG
5251 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5252 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5253
5254 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5255 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5256 (float:X87MODEF
5257 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5258 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5259 "TARGET_80387
5260 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5261 "@
5262 fild%Z1\t%1
5263 #"
5264 [(set_attr "type" "fmov,multi")
5265 (set_attr "mode" "<X87MODEF:MODE>")
5266 (set_attr "unit" "*,i387")
5267 (set_attr "fp_int_src" "true")])
5268
5269 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5270 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5271 (float:X87MODEF
5272 (match_operand:SWI48x 1 "memory_operand" "m")))]
5273 "TARGET_80387
5274 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5275 "fild%Z1\t%1"
5276 [(set_attr "type" "fmov")
5277 (set_attr "mode" "<X87MODEF:MODE>")
5278 (set_attr "fp_int_src" "true")])
5279
5280 (define_split
5281 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5282 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5283 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5284 "TARGET_80387
5285 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5286 && reload_completed"
5287 [(set (match_dup 2) (match_dup 1))
5288 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5289
5290 (define_split
5291 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5292 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5293 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5294 "TARGET_80387
5295 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5296 && reload_completed"
5297 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5298
5299 ;; Avoid store forwarding (partial memory) stall penalty
5300 ;; by passing DImode value through XMM registers. */
5301
5302 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5303 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5304 (float:X87MODEF
5305 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5306 (clobber (match_scratch:V4SI 3 "=X,x"))
5307 (clobber (match_scratch:V4SI 4 "=X,x"))
5308 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5309 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5310 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5311 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5312 "#"
5313 [(set_attr "type" "multi")
5314 (set_attr "mode" "<X87MODEF:MODE>")
5315 (set_attr "unit" "i387")
5316 (set_attr "fp_int_src" "true")])
5317
5318 (define_split
5319 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5320 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5321 (clobber (match_scratch:V4SI 3))
5322 (clobber (match_scratch:V4SI 4))
5323 (clobber (match_operand:DI 2 "memory_operand"))]
5324 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5325 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5326 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5327 && reload_completed"
5328 [(set (match_dup 2) (match_dup 3))
5329 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5330 {
5331 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5332 Assemble the 64-bit DImode value in an xmm register. */
5333 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5334 gen_rtx_SUBREG (SImode, operands[1], 0)));
5335 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5336 gen_rtx_SUBREG (SImode, operands[1], 4)));
5337 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5338 operands[4]));
5339
5340 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5341 })
5342
5343 (define_split
5344 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5345 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5346 (clobber (match_scratch:V4SI 3))
5347 (clobber (match_scratch:V4SI 4))
5348 (clobber (match_operand:DI 2 "memory_operand"))]
5349 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5350 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5351 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5352 && reload_completed"
5353 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5354
5355 ;; Avoid store forwarding (partial memory) stall penalty by extending
5356 ;; SImode value to DImode through XMM register instead of pushing two
5357 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5358 ;; targets benefit from this optimization. Also note that fild
5359 ;; loads from memory only.
5360
5361 (define_insn "*floatunssi<mode>2_1"
5362 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5363 (unsigned_float:X87MODEF
5364 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5365 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5366 (clobber (match_scratch:SI 3 "=X,x"))]
5367 "!TARGET_64BIT
5368 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5369 && TARGET_SSE"
5370 "#"
5371 [(set_attr "type" "multi")
5372 (set_attr "mode" "<MODE>")])
5373
5374 (define_split
5375 [(set (match_operand:X87MODEF 0 "register_operand")
5376 (unsigned_float:X87MODEF
5377 (match_operand:SI 1 "register_operand")))
5378 (clobber (match_operand:DI 2 "memory_operand"))
5379 (clobber (match_scratch:SI 3))]
5380 "!TARGET_64BIT
5381 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5382 && TARGET_SSE
5383 && reload_completed"
5384 [(set (match_dup 2) (match_dup 1))
5385 (set (match_dup 0)
5386 (float:X87MODEF (match_dup 2)))]
5387 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5388
5389 (define_split
5390 [(set (match_operand:X87MODEF 0 "register_operand")
5391 (unsigned_float:X87MODEF
5392 (match_operand:SI 1 "memory_operand")))
5393 (clobber (match_operand:DI 2 "memory_operand"))
5394 (clobber (match_scratch:SI 3))]
5395 "!TARGET_64BIT
5396 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5397 && TARGET_SSE
5398 && reload_completed"
5399 [(set (match_dup 2) (match_dup 3))
5400 (set (match_dup 0)
5401 (float:X87MODEF (match_dup 2)))]
5402 {
5403 emit_move_insn (operands[3], operands[1]);
5404 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5405 })
5406
5407 (define_expand "floatunssi<mode>2"
5408 [(parallel
5409 [(set (match_operand:X87MODEF 0 "register_operand")
5410 (unsigned_float:X87MODEF
5411 (match_operand:SI 1 "nonimmediate_operand")))
5412 (clobber (match_dup 2))
5413 (clobber (match_scratch:SI 3))])]
5414 "!TARGET_64BIT
5415 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5416 && TARGET_SSE)
5417 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5418 {
5419 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5420 {
5421 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5422 DONE;
5423 }
5424 else
5425 {
5426 enum ix86_stack_slot slot = (virtuals_instantiated
5427 ? SLOT_TEMP
5428 : SLOT_VIRTUAL);
5429 operands[2] = assign_386_stack_local (DImode, slot);
5430 }
5431 })
5432
5433 (define_expand "floatunsdisf2"
5434 [(use (match_operand:SF 0 "register_operand"))
5435 (use (match_operand:DI 1 "nonimmediate_operand"))]
5436 "TARGET_64BIT && TARGET_SSE_MATH"
5437 "x86_emit_floatuns (operands); DONE;")
5438
5439 (define_expand "floatunsdidf2"
5440 [(use (match_operand:DF 0 "register_operand"))
5441 (use (match_operand:DI 1 "nonimmediate_operand"))]
5442 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5443 && TARGET_SSE2 && TARGET_SSE_MATH"
5444 {
5445 if (TARGET_64BIT)
5446 x86_emit_floatuns (operands);
5447 else
5448 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5449 DONE;
5450 })
5451 \f
5452 ;; Add instructions
5453
5454 (define_expand "add<mode>3"
5455 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5456 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5457 (match_operand:SDWIM 2 "<general_operand>")))]
5458 ""
5459 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5460
5461 (define_insn_and_split "*add<dwi>3_doubleword"
5462 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5463 (plus:<DWI>
5464 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5465 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5466 (clobber (reg:CC FLAGS_REG))]
5467 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5468 "#"
5469 "reload_completed"
5470 [(parallel [(set (reg:CC FLAGS_REG)
5471 (unspec:CC [(match_dup 1) (match_dup 2)]
5472 UNSPEC_ADD_CARRY))
5473 (set (match_dup 0)
5474 (plus:DWIH (match_dup 1) (match_dup 2)))])
5475 (parallel [(set (match_dup 3)
5476 (plus:DWIH
5477 (match_dup 4)
5478 (plus:DWIH
5479 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5480 (match_dup 5))))
5481 (clobber (reg:CC FLAGS_REG))])]
5482 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5483
5484 (define_insn "*add<mode>3_cc"
5485 [(set (reg:CC FLAGS_REG)
5486 (unspec:CC
5487 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5488 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5489 UNSPEC_ADD_CARRY))
5490 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5491 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5492 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5493 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5494 [(set_attr "type" "alu")
5495 (set_attr "mode" "<MODE>")])
5496
5497 (define_insn "addqi3_cc"
5498 [(set (reg:CC FLAGS_REG)
5499 (unspec:CC
5500 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5501 (match_operand:QI 2 "general_operand" "qn,qm")]
5502 UNSPEC_ADD_CARRY))
5503 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5504 (plus:QI (match_dup 1) (match_dup 2)))]
5505 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5506 "add{b}\t{%2, %0|%0, %2}"
5507 [(set_attr "type" "alu")
5508 (set_attr "mode" "QI")])
5509
5510 (define_insn_and_split "*lea_1"
5511 [(set (match_operand:SI 0 "register_operand" "=r")
5512 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5513 "TARGET_64BIT"
5514 "lea{l}\t{%E1, %0|%0, %E1}"
5515 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5516 [(const_int 0)]
5517 {
5518 ix86_split_lea_for_addr (operands, SImode);
5519 DONE;
5520 }
5521 [(set_attr "type" "lea")
5522 (set_attr "mode" "SI")])
5523
5524 (define_insn_and_split "*lea<mode>_2"
5525 [(set (match_operand:SWI48 0 "register_operand" "=r")
5526 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5527 ""
5528 "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
5529 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5530 [(const_int 0)]
5531 {
5532 ix86_split_lea_for_addr (operands, <MODE>mode);
5533 DONE;
5534 }
5535 [(set_attr "type" "lea")
5536 (set_attr "mode" "<MODE>")])
5537
5538 (define_insn "*lea_3_zext"
5539 [(set (match_operand:DI 0 "register_operand" "=r")
5540 (zero_extend:DI
5541 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5542 "TARGET_64BIT"
5543 "lea{l}\t{%E1, %k0|%k0, %E1}"
5544 [(set_attr "type" "lea")
5545 (set_attr "mode" "SI")])
5546
5547 (define_insn "*lea_4_zext"
5548 [(set (match_operand:DI 0 "register_operand" "=r")
5549 (zero_extend:DI
5550 (match_operand:SI 1 "lea_address_operand" "j")))]
5551 "TARGET_64BIT"
5552 "lea{l}\t{%E1, %k0|%k0, %E1}"
5553 [(set_attr "type" "lea")
5554 (set_attr "mode" "SI")])
5555
5556 (define_insn "*lea_5_zext"
5557 [(set (match_operand:DI 0 "register_operand" "=r")
5558 (and:DI
5559 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5560 (match_operand:DI 2 "const_32bit_mask" "n")))]
5561 "TARGET_64BIT"
5562 "lea{l}\t{%E1, %k0|%k0, %E1}"
5563 [(set_attr "type" "lea")
5564 (set_attr "mode" "SI")])
5565
5566 (define_insn "*lea_6_zext"
5567 [(set (match_operand:DI 0 "register_operand" "=r")
5568 (and:DI
5569 (match_operand:DI 1 "lea_address_operand" "p")
5570 (match_operand:DI 2 "const_32bit_mask" "n")))]
5571 "TARGET_64BIT"
5572 "lea{l}\t{%E1, %k0|%k0, %E1}"
5573 [(set_attr "type" "lea")
5574 (set_attr "mode" "SI")])
5575
5576 (define_insn "*add<mode>_1"
5577 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5578 (plus:SWI48
5579 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5580 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5581 (clobber (reg:CC FLAGS_REG))]
5582 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5583 {
5584 switch (get_attr_type (insn))
5585 {
5586 case TYPE_LEA:
5587 return "#";
5588
5589 case TYPE_INCDEC:
5590 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5591 if (operands[2] == const1_rtx)
5592 return "inc{<imodesuffix>}\t%0";
5593 else
5594 {
5595 gcc_assert (operands[2] == constm1_rtx);
5596 return "dec{<imodesuffix>}\t%0";
5597 }
5598
5599 default:
5600 /* For most processors, ADD is faster than LEA. This alternative
5601 was added to use ADD as much as possible. */
5602 if (which_alternative == 2)
5603 {
5604 rtx tmp;
5605 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5606 }
5607
5608 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5610 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5611
5612 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5613 }
5614 }
5615 [(set (attr "type")
5616 (cond [(eq_attr "alternative" "3")
5617 (const_string "lea")
5618 (match_operand:SWI48 2 "incdec_operand")
5619 (const_string "incdec")
5620 ]
5621 (const_string "alu")))
5622 (set (attr "length_immediate")
5623 (if_then_else
5624 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5625 (const_string "1")
5626 (const_string "*")))
5627 (set_attr "mode" "<MODE>")])
5628
5629 ;; It may seem that nonimmediate operand is proper one for operand 1.
5630 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5631 ;; we take care in ix86_binary_operator_ok to not allow two memory
5632 ;; operands so proper swapping will be done in reload. This allow
5633 ;; patterns constructed from addsi_1 to match.
5634
5635 (define_insn "addsi_1_zext"
5636 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5637 (zero_extend:DI
5638 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5639 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5640 (clobber (reg:CC FLAGS_REG))]
5641 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5642 {
5643 switch (get_attr_type (insn))
5644 {
5645 case TYPE_LEA:
5646 return "#";
5647
5648 case TYPE_INCDEC:
5649 if (operands[2] == const1_rtx)
5650 return "inc{l}\t%k0";
5651 else
5652 {
5653 gcc_assert (operands[2] == constm1_rtx);
5654 return "dec{l}\t%k0";
5655 }
5656
5657 default:
5658 /* For most processors, ADD is faster than LEA. This alternative
5659 was added to use ADD as much as possible. */
5660 if (which_alternative == 1)
5661 {
5662 rtx tmp;
5663 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5664 }
5665
5666 if (x86_maybe_negate_const_int (&operands[2], SImode))
5667 return "sub{l}\t{%2, %k0|%k0, %2}";
5668
5669 return "add{l}\t{%2, %k0|%k0, %2}";
5670 }
5671 }
5672 [(set (attr "type")
5673 (cond [(eq_attr "alternative" "2")
5674 (const_string "lea")
5675 (match_operand:SI 2 "incdec_operand")
5676 (const_string "incdec")
5677 ]
5678 (const_string "alu")))
5679 (set (attr "length_immediate")
5680 (if_then_else
5681 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5682 (const_string "1")
5683 (const_string "*")))
5684 (set_attr "mode" "SI")])
5685
5686 (define_insn "*addhi_1"
5687 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5688 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5689 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5690 (clobber (reg:CC FLAGS_REG))]
5691 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5692 {
5693 switch (get_attr_type (insn))
5694 {
5695 case TYPE_LEA:
5696 return "#";
5697
5698 case TYPE_INCDEC:
5699 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5700 if (operands[2] == const1_rtx)
5701 return "inc{w}\t%0";
5702 else
5703 {
5704 gcc_assert (operands[2] == constm1_rtx);
5705 return "dec{w}\t%0";
5706 }
5707
5708 default:
5709 /* For most processors, ADD is faster than LEA. This alternative
5710 was added to use ADD as much as possible. */
5711 if (which_alternative == 2)
5712 {
5713 rtx tmp;
5714 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5715 }
5716
5717 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5718 if (x86_maybe_negate_const_int (&operands[2], HImode))
5719 return "sub{w}\t{%2, %0|%0, %2}";
5720
5721 return "add{w}\t{%2, %0|%0, %2}";
5722 }
5723 }
5724 [(set (attr "type")
5725 (cond [(eq_attr "alternative" "3")
5726 (const_string "lea")
5727 (match_operand:HI 2 "incdec_operand")
5728 (const_string "incdec")
5729 ]
5730 (const_string "alu")))
5731 (set (attr "length_immediate")
5732 (if_then_else
5733 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5734 (const_string "1")
5735 (const_string "*")))
5736 (set_attr "mode" "HI,HI,HI,SI")])
5737
5738 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5739 (define_insn "*addqi_1"
5740 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5741 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5742 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5743 (clobber (reg:CC FLAGS_REG))]
5744 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5745 {
5746 bool widen = (which_alternative == 3 || which_alternative == 4);
5747
5748 switch (get_attr_type (insn))
5749 {
5750 case TYPE_LEA:
5751 return "#";
5752
5753 case TYPE_INCDEC:
5754 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5755 if (operands[2] == const1_rtx)
5756 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5757 else
5758 {
5759 gcc_assert (operands[2] == constm1_rtx);
5760 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5761 }
5762
5763 default:
5764 /* For most processors, ADD is faster than LEA. These alternatives
5765 were added to use ADD as much as possible. */
5766 if (which_alternative == 2 || which_alternative == 4)
5767 {
5768 rtx tmp;
5769 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5770 }
5771
5772 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5773 if (x86_maybe_negate_const_int (&operands[2], QImode))
5774 {
5775 if (widen)
5776 return "sub{l}\t{%2, %k0|%k0, %2}";
5777 else
5778 return "sub{b}\t{%2, %0|%0, %2}";
5779 }
5780 if (widen)
5781 return "add{l}\t{%k2, %k0|%k0, %k2}";
5782 else
5783 return "add{b}\t{%2, %0|%0, %2}";
5784 }
5785 }
5786 [(set (attr "type")
5787 (cond [(eq_attr "alternative" "5")
5788 (const_string "lea")
5789 (match_operand:QI 2 "incdec_operand")
5790 (const_string "incdec")
5791 ]
5792 (const_string "alu")))
5793 (set (attr "length_immediate")
5794 (if_then_else
5795 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5796 (const_string "1")
5797 (const_string "*")))
5798 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5799
5800 (define_insn "*addqi_1_slp"
5801 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5802 (plus:QI (match_dup 0)
5803 (match_operand:QI 1 "general_operand" "qn,qm")))
5804 (clobber (reg:CC FLAGS_REG))]
5805 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5806 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5807 {
5808 switch (get_attr_type (insn))
5809 {
5810 case TYPE_INCDEC:
5811 if (operands[1] == const1_rtx)
5812 return "inc{b}\t%0";
5813 else
5814 {
5815 gcc_assert (operands[1] == constm1_rtx);
5816 return "dec{b}\t%0";
5817 }
5818
5819 default:
5820 if (x86_maybe_negate_const_int (&operands[1], QImode))
5821 return "sub{b}\t{%1, %0|%0, %1}";
5822
5823 return "add{b}\t{%1, %0|%0, %1}";
5824 }
5825 }
5826 [(set (attr "type")
5827 (if_then_else (match_operand:QI 1 "incdec_operand")
5828 (const_string "incdec")
5829 (const_string "alu1")))
5830 (set (attr "memory")
5831 (if_then_else (match_operand 1 "memory_operand")
5832 (const_string "load")
5833 (const_string "none")))
5834 (set_attr "mode" "QI")])
5835
5836 ;; Split non destructive adds if we cannot use lea.
5837 (define_split
5838 [(set (match_operand:SWI48 0 "register_operand")
5839 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5840 (match_operand:SWI48 2 "nonmemory_operand")))
5841 (clobber (reg:CC FLAGS_REG))]
5842 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5843 [(set (match_dup 0) (match_dup 1))
5844 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5845 (clobber (reg:CC FLAGS_REG))])])
5846
5847 ;; Convert add to the lea pattern to avoid flags dependency.
5848 (define_split
5849 [(set (match_operand:SWI 0 "register_operand")
5850 (plus:SWI (match_operand:SWI 1 "register_operand")
5851 (match_operand:SWI 2 "<nonmemory_operand>")))
5852 (clobber (reg:CC FLAGS_REG))]
5853 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5854 [(const_int 0)]
5855 {
5856 enum machine_mode mode = <MODE>mode;
5857 rtx pat;
5858
5859 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5860 {
5861 mode = SImode;
5862 operands[0] = gen_lowpart (mode, operands[0]);
5863 operands[1] = gen_lowpart (mode, operands[1]);
5864 operands[2] = gen_lowpart (mode, operands[2]);
5865 }
5866
5867 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5868
5869 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5870 DONE;
5871 })
5872
5873 ;; Convert add to the lea pattern to avoid flags dependency.
5874 (define_split
5875 [(set (match_operand:DI 0 "register_operand")
5876 (zero_extend:DI
5877 (plus:SI (match_operand:SI 1 "register_operand")
5878 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5879 (clobber (reg:CC FLAGS_REG))]
5880 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5881 [(set (match_dup 0)
5882 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5883
5884 (define_insn "*add<mode>_2"
5885 [(set (reg FLAGS_REG)
5886 (compare
5887 (plus:SWI
5888 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5889 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5890 (const_int 0)))
5891 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5892 (plus:SWI (match_dup 1) (match_dup 2)))]
5893 "ix86_match_ccmode (insn, CCGOCmode)
5894 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5895 {
5896 switch (get_attr_type (insn))
5897 {
5898 case TYPE_INCDEC:
5899 if (operands[2] == const1_rtx)
5900 return "inc{<imodesuffix>}\t%0";
5901 else
5902 {
5903 gcc_assert (operands[2] == constm1_rtx);
5904 return "dec{<imodesuffix>}\t%0";
5905 }
5906
5907 default:
5908 if (which_alternative == 2)
5909 {
5910 rtx tmp;
5911 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5912 }
5913
5914 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5915 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5916 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5917
5918 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5919 }
5920 }
5921 [(set (attr "type")
5922 (if_then_else (match_operand:SWI 2 "incdec_operand")
5923 (const_string "incdec")
5924 (const_string "alu")))
5925 (set (attr "length_immediate")
5926 (if_then_else
5927 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5928 (const_string "1")
5929 (const_string "*")))
5930 (set_attr "mode" "<MODE>")])
5931
5932 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5933 (define_insn "*addsi_2_zext"
5934 [(set (reg FLAGS_REG)
5935 (compare
5936 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5937 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5938 (const_int 0)))
5939 (set (match_operand:DI 0 "register_operand" "=r,r")
5940 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5941 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5942 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5943 {
5944 switch (get_attr_type (insn))
5945 {
5946 case TYPE_INCDEC:
5947 if (operands[2] == const1_rtx)
5948 return "inc{l}\t%k0";
5949 else
5950 {
5951 gcc_assert (operands[2] == constm1_rtx);
5952 return "dec{l}\t%k0";
5953 }
5954
5955 default:
5956 if (which_alternative == 1)
5957 {
5958 rtx tmp;
5959 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5960 }
5961
5962 if (x86_maybe_negate_const_int (&operands[2], SImode))
5963 return "sub{l}\t{%2, %k0|%k0, %2}";
5964
5965 return "add{l}\t{%2, %k0|%k0, %2}";
5966 }
5967 }
5968 [(set (attr "type")
5969 (if_then_else (match_operand:SI 2 "incdec_operand")
5970 (const_string "incdec")
5971 (const_string "alu")))
5972 (set (attr "length_immediate")
5973 (if_then_else
5974 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5975 (const_string "1")
5976 (const_string "*")))
5977 (set_attr "mode" "SI")])
5978
5979 (define_insn "*add<mode>_3"
5980 [(set (reg FLAGS_REG)
5981 (compare
5982 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5983 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5984 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5985 "ix86_match_ccmode (insn, CCZmode)
5986 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5987 {
5988 switch (get_attr_type (insn))
5989 {
5990 case TYPE_INCDEC:
5991 if (operands[2] == const1_rtx)
5992 return "inc{<imodesuffix>}\t%0";
5993 else
5994 {
5995 gcc_assert (operands[2] == constm1_rtx);
5996 return "dec{<imodesuffix>}\t%0";
5997 }
5998
5999 default:
6000 if (which_alternative == 1)
6001 {
6002 rtx tmp;
6003 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6004 }
6005
6006 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6007 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6008 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6009
6010 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6011 }
6012 }
6013 [(set (attr "type")
6014 (if_then_else (match_operand:SWI 2 "incdec_operand")
6015 (const_string "incdec")
6016 (const_string "alu")))
6017 (set (attr "length_immediate")
6018 (if_then_else
6019 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6020 (const_string "1")
6021 (const_string "*")))
6022 (set_attr "mode" "<MODE>")])
6023
6024 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6025 (define_insn "*addsi_3_zext"
6026 [(set (reg FLAGS_REG)
6027 (compare
6028 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6029 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6030 (set (match_operand:DI 0 "register_operand" "=r,r")
6031 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6032 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6033 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6034 {
6035 switch (get_attr_type (insn))
6036 {
6037 case TYPE_INCDEC:
6038 if (operands[2] == const1_rtx)
6039 return "inc{l}\t%k0";
6040 else
6041 {
6042 gcc_assert (operands[2] == constm1_rtx);
6043 return "dec{l}\t%k0";
6044 }
6045
6046 default:
6047 if (which_alternative == 1)
6048 {
6049 rtx tmp;
6050 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6051 }
6052
6053 if (x86_maybe_negate_const_int (&operands[2], SImode))
6054 return "sub{l}\t{%2, %k0|%k0, %2}";
6055
6056 return "add{l}\t{%2, %k0|%k0, %2}";
6057 }
6058 }
6059 [(set (attr "type")
6060 (if_then_else (match_operand:SI 2 "incdec_operand")
6061 (const_string "incdec")
6062 (const_string "alu")))
6063 (set (attr "length_immediate")
6064 (if_then_else
6065 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6066 (const_string "1")
6067 (const_string "*")))
6068 (set_attr "mode" "SI")])
6069
6070 ; For comparisons against 1, -1 and 128, we may generate better code
6071 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6072 ; is matched then. We can't accept general immediate, because for
6073 ; case of overflows, the result is messed up.
6074 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6075 ; only for comparisons not depending on it.
6076
6077 (define_insn "*adddi_4"
6078 [(set (reg FLAGS_REG)
6079 (compare
6080 (match_operand:DI 1 "nonimmediate_operand" "0")
6081 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6082 (clobber (match_scratch:DI 0 "=rm"))]
6083 "TARGET_64BIT
6084 && ix86_match_ccmode (insn, CCGCmode)"
6085 {
6086 switch (get_attr_type (insn))
6087 {
6088 case TYPE_INCDEC:
6089 if (operands[2] == constm1_rtx)
6090 return "inc{q}\t%0";
6091 else
6092 {
6093 gcc_assert (operands[2] == const1_rtx);
6094 return "dec{q}\t%0";
6095 }
6096
6097 default:
6098 if (x86_maybe_negate_const_int (&operands[2], DImode))
6099 return "add{q}\t{%2, %0|%0, %2}";
6100
6101 return "sub{q}\t{%2, %0|%0, %2}";
6102 }
6103 }
6104 [(set (attr "type")
6105 (if_then_else (match_operand:DI 2 "incdec_operand")
6106 (const_string "incdec")
6107 (const_string "alu")))
6108 (set (attr "length_immediate")
6109 (if_then_else
6110 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6111 (const_string "1")
6112 (const_string "*")))
6113 (set_attr "mode" "DI")])
6114
6115 ; For comparisons against 1, -1 and 128, we may generate better code
6116 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6117 ; is matched then. We can't accept general immediate, because for
6118 ; case of overflows, the result is messed up.
6119 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6120 ; only for comparisons not depending on it.
6121
6122 (define_insn "*add<mode>_4"
6123 [(set (reg FLAGS_REG)
6124 (compare
6125 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6126 (match_operand:SWI124 2 "const_int_operand" "n")))
6127 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6128 "ix86_match_ccmode (insn, CCGCmode)"
6129 {
6130 switch (get_attr_type (insn))
6131 {
6132 case TYPE_INCDEC:
6133 if (operands[2] == constm1_rtx)
6134 return "inc{<imodesuffix>}\t%0";
6135 else
6136 {
6137 gcc_assert (operands[2] == const1_rtx);
6138 return "dec{<imodesuffix>}\t%0";
6139 }
6140
6141 default:
6142 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6143 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6144
6145 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6146 }
6147 }
6148 [(set (attr "type")
6149 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6150 (const_string "incdec")
6151 (const_string "alu")))
6152 (set (attr "length_immediate")
6153 (if_then_else
6154 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6155 (const_string "1")
6156 (const_string "*")))
6157 (set_attr "mode" "<MODE>")])
6158
6159 (define_insn "*add<mode>_5"
6160 [(set (reg FLAGS_REG)
6161 (compare
6162 (plus:SWI
6163 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6164 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6165 (const_int 0)))
6166 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6167 "ix86_match_ccmode (insn, CCGOCmode)
6168 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6169 {
6170 switch (get_attr_type (insn))
6171 {
6172 case TYPE_INCDEC:
6173 if (operands[2] == const1_rtx)
6174 return "inc{<imodesuffix>}\t%0";
6175 else
6176 {
6177 gcc_assert (operands[2] == constm1_rtx);
6178 return "dec{<imodesuffix>}\t%0";
6179 }
6180
6181 default:
6182 if (which_alternative == 1)
6183 {
6184 rtx tmp;
6185 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6186 }
6187
6188 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6189 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6190 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6191
6192 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6193 }
6194 }
6195 [(set (attr "type")
6196 (if_then_else (match_operand:SWI 2 "incdec_operand")
6197 (const_string "incdec")
6198 (const_string "alu")))
6199 (set (attr "length_immediate")
6200 (if_then_else
6201 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6202 (const_string "1")
6203 (const_string "*")))
6204 (set_attr "mode" "<MODE>")])
6205
6206 (define_insn "*addqi_ext_1_rex64"
6207 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6208 (const_int 8)
6209 (const_int 8))
6210 (plus:SI
6211 (zero_extract:SI
6212 (match_operand 1 "ext_register_operand" "0")
6213 (const_int 8)
6214 (const_int 8))
6215 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6216 (clobber (reg:CC FLAGS_REG))]
6217 "TARGET_64BIT"
6218 {
6219 switch (get_attr_type (insn))
6220 {
6221 case TYPE_INCDEC:
6222 if (operands[2] == const1_rtx)
6223 return "inc{b}\t%h0";
6224 else
6225 {
6226 gcc_assert (operands[2] == constm1_rtx);
6227 return "dec{b}\t%h0";
6228 }
6229
6230 default:
6231 return "add{b}\t{%2, %h0|%h0, %2}";
6232 }
6233 }
6234 [(set (attr "type")
6235 (if_then_else (match_operand:QI 2 "incdec_operand")
6236 (const_string "incdec")
6237 (const_string "alu")))
6238 (set_attr "modrm" "1")
6239 (set_attr "mode" "QI")])
6240
6241 (define_insn "addqi_ext_1"
6242 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6243 (const_int 8)
6244 (const_int 8))
6245 (plus:SI
6246 (zero_extract:SI
6247 (match_operand 1 "ext_register_operand" "0")
6248 (const_int 8)
6249 (const_int 8))
6250 (match_operand:QI 2 "general_operand" "Qmn")))
6251 (clobber (reg:CC FLAGS_REG))]
6252 "!TARGET_64BIT"
6253 {
6254 switch (get_attr_type (insn))
6255 {
6256 case TYPE_INCDEC:
6257 if (operands[2] == const1_rtx)
6258 return "inc{b}\t%h0";
6259 else
6260 {
6261 gcc_assert (operands[2] == constm1_rtx);
6262 return "dec{b}\t%h0";
6263 }
6264
6265 default:
6266 return "add{b}\t{%2, %h0|%h0, %2}";
6267 }
6268 }
6269 [(set (attr "type")
6270 (if_then_else (match_operand:QI 2 "incdec_operand")
6271 (const_string "incdec")
6272 (const_string "alu")))
6273 (set_attr "modrm" "1")
6274 (set_attr "mode" "QI")])
6275
6276 (define_insn "*addqi_ext_2"
6277 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6278 (const_int 8)
6279 (const_int 8))
6280 (plus:SI
6281 (zero_extract:SI
6282 (match_operand 1 "ext_register_operand" "%0")
6283 (const_int 8)
6284 (const_int 8))
6285 (zero_extract:SI
6286 (match_operand 2 "ext_register_operand" "Q")
6287 (const_int 8)
6288 (const_int 8))))
6289 (clobber (reg:CC FLAGS_REG))]
6290 ""
6291 "add{b}\t{%h2, %h0|%h0, %h2}"
6292 [(set_attr "type" "alu")
6293 (set_attr "mode" "QI")])
6294
6295 ;; The lea patterns for modes less than 32 bits need to be matched by
6296 ;; several insns converted to real lea by splitters.
6297
6298 (define_insn_and_split "*lea_general_1"
6299 [(set (match_operand 0 "register_operand" "=r")
6300 (plus (plus (match_operand 1 "index_register_operand" "l")
6301 (match_operand 2 "register_operand" "r"))
6302 (match_operand 3 "immediate_operand" "i")))]
6303 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6304 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6305 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6306 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6307 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6308 || GET_MODE (operands[3]) == VOIDmode)"
6309 "#"
6310 "&& reload_completed"
6311 [(const_int 0)]
6312 {
6313 enum machine_mode mode = SImode;
6314 rtx pat;
6315
6316 operands[0] = gen_lowpart (mode, operands[0]);
6317 operands[1] = gen_lowpart (mode, operands[1]);
6318 operands[2] = gen_lowpart (mode, operands[2]);
6319 operands[3] = gen_lowpart (mode, operands[3]);
6320
6321 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6322 operands[3]);
6323
6324 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6325 DONE;
6326 }
6327 [(set_attr "type" "lea")
6328 (set_attr "mode" "SI")])
6329
6330 (define_insn_and_split "*lea_general_2"
6331 [(set (match_operand 0 "register_operand" "=r")
6332 (plus (mult (match_operand 1 "index_register_operand" "l")
6333 (match_operand 2 "const248_operand" "n"))
6334 (match_operand 3 "nonmemory_operand" "ri")))]
6335 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6336 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6337 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6338 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6339 || GET_MODE (operands[3]) == VOIDmode)"
6340 "#"
6341 "&& reload_completed"
6342 [(const_int 0)]
6343 {
6344 enum machine_mode mode = SImode;
6345 rtx pat;
6346
6347 operands[0] = gen_lowpart (mode, operands[0]);
6348 operands[1] = gen_lowpart (mode, operands[1]);
6349 operands[3] = gen_lowpart (mode, operands[3]);
6350
6351 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6352 operands[3]);
6353
6354 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6355 DONE;
6356 }
6357 [(set_attr "type" "lea")
6358 (set_attr "mode" "SI")])
6359
6360 (define_insn_and_split "*lea_general_3"
6361 [(set (match_operand 0 "register_operand" "=r")
6362 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6363 (match_operand 2 "const248_operand" "n"))
6364 (match_operand 3 "register_operand" "r"))
6365 (match_operand 4 "immediate_operand" "i")))]
6366 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6367 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6368 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6369 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6370 "#"
6371 "&& reload_completed"
6372 [(const_int 0)]
6373 {
6374 enum machine_mode mode = SImode;
6375 rtx pat;
6376
6377 operands[0] = gen_lowpart (mode, operands[0]);
6378 operands[1] = gen_lowpart (mode, operands[1]);
6379 operands[3] = gen_lowpart (mode, operands[3]);
6380 operands[4] = gen_lowpart (mode, operands[4]);
6381
6382 pat = gen_rtx_PLUS (mode,
6383 gen_rtx_PLUS (mode,
6384 gen_rtx_MULT (mode, operands[1],
6385 operands[2]),
6386 operands[3]),
6387 operands[4]);
6388
6389 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6390 DONE;
6391 }
6392 [(set_attr "type" "lea")
6393 (set_attr "mode" "SI")])
6394
6395 (define_insn_and_split "*lea_general_4"
6396 [(set (match_operand 0 "register_operand" "=r")
6397 (any_or (ashift
6398 (match_operand 1 "index_register_operand" "l")
6399 (match_operand 2 "const_int_operand" "n"))
6400 (match_operand 3 "const_int_operand" "n")))]
6401 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6402 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6403 || GET_MODE (operands[0]) == SImode
6404 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6405 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6406 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6407 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6408 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6409 "#"
6410 "&& reload_completed"
6411 [(const_int 0)]
6412 {
6413 enum machine_mode mode = GET_MODE (operands[0]);
6414 rtx pat;
6415
6416 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6417 {
6418 mode = SImode;
6419 operands[0] = gen_lowpart (mode, operands[0]);
6420 operands[1] = gen_lowpart (mode, operands[1]);
6421 }
6422
6423 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6424
6425 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6426 INTVAL (operands[3]));
6427
6428 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6429 DONE;
6430 }
6431 [(set_attr "type" "lea")
6432 (set (attr "mode")
6433 (if_then_else (match_operand:DI 0)
6434 (const_string "DI")
6435 (const_string "SI")))])
6436 \f
6437 ;; Subtract instructions
6438
6439 (define_expand "sub<mode>3"
6440 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6441 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6442 (match_operand:SDWIM 2 "<general_operand>")))]
6443 ""
6444 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6445
6446 (define_insn_and_split "*sub<dwi>3_doubleword"
6447 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6448 (minus:<DWI>
6449 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6450 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6451 (clobber (reg:CC FLAGS_REG))]
6452 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6453 "#"
6454 "reload_completed"
6455 [(parallel [(set (reg:CC FLAGS_REG)
6456 (compare:CC (match_dup 1) (match_dup 2)))
6457 (set (match_dup 0)
6458 (minus:DWIH (match_dup 1) (match_dup 2)))])
6459 (parallel [(set (match_dup 3)
6460 (minus:DWIH
6461 (match_dup 4)
6462 (plus:DWIH
6463 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6464 (match_dup 5))))
6465 (clobber (reg:CC FLAGS_REG))])]
6466 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6467
6468 (define_insn "*sub<mode>_1"
6469 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6470 (minus:SWI
6471 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6472 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6473 (clobber (reg:CC FLAGS_REG))]
6474 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6475 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6476 [(set_attr "type" "alu")
6477 (set_attr "mode" "<MODE>")])
6478
6479 (define_insn "*subsi_1_zext"
6480 [(set (match_operand:DI 0 "register_operand" "=r")
6481 (zero_extend:DI
6482 (minus:SI (match_operand:SI 1 "register_operand" "0")
6483 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6484 (clobber (reg:CC FLAGS_REG))]
6485 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6486 "sub{l}\t{%2, %k0|%k0, %2}"
6487 [(set_attr "type" "alu")
6488 (set_attr "mode" "SI")])
6489
6490 (define_insn "*subqi_1_slp"
6491 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6492 (minus:QI (match_dup 0)
6493 (match_operand:QI 1 "general_operand" "qn,qm")))
6494 (clobber (reg:CC FLAGS_REG))]
6495 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6496 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6497 "sub{b}\t{%1, %0|%0, %1}"
6498 [(set_attr "type" "alu1")
6499 (set_attr "mode" "QI")])
6500
6501 (define_insn "*sub<mode>_2"
6502 [(set (reg FLAGS_REG)
6503 (compare
6504 (minus:SWI
6505 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6506 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6507 (const_int 0)))
6508 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6509 (minus:SWI (match_dup 1) (match_dup 2)))]
6510 "ix86_match_ccmode (insn, CCGOCmode)
6511 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6512 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6513 [(set_attr "type" "alu")
6514 (set_attr "mode" "<MODE>")])
6515
6516 (define_insn "*subsi_2_zext"
6517 [(set (reg FLAGS_REG)
6518 (compare
6519 (minus:SI (match_operand:SI 1 "register_operand" "0")
6520 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6521 (const_int 0)))
6522 (set (match_operand:DI 0 "register_operand" "=r")
6523 (zero_extend:DI
6524 (minus:SI (match_dup 1)
6525 (match_dup 2))))]
6526 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6527 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6528 "sub{l}\t{%2, %k0|%k0, %2}"
6529 [(set_attr "type" "alu")
6530 (set_attr "mode" "SI")])
6531
6532 (define_insn "*sub<mode>_3"
6533 [(set (reg FLAGS_REG)
6534 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6535 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6536 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6537 (minus:SWI (match_dup 1) (match_dup 2)))]
6538 "ix86_match_ccmode (insn, CCmode)
6539 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6540 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6541 [(set_attr "type" "alu")
6542 (set_attr "mode" "<MODE>")])
6543
6544 (define_insn "*subsi_3_zext"
6545 [(set (reg FLAGS_REG)
6546 (compare (match_operand:SI 1 "register_operand" "0")
6547 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6548 (set (match_operand:DI 0 "register_operand" "=r")
6549 (zero_extend:DI
6550 (minus:SI (match_dup 1)
6551 (match_dup 2))))]
6552 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6553 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6554 "sub{l}\t{%2, %1|%1, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "mode" "SI")])
6557 \f
6558 ;; Add with carry and subtract with borrow
6559
6560 (define_expand "<plusminus_insn><mode>3_carry"
6561 [(parallel
6562 [(set (match_operand:SWI 0 "nonimmediate_operand")
6563 (plusminus:SWI
6564 (match_operand:SWI 1 "nonimmediate_operand")
6565 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6566 [(match_operand 3 "flags_reg_operand")
6567 (const_int 0)])
6568 (match_operand:SWI 2 "<general_operand>"))))
6569 (clobber (reg:CC FLAGS_REG))])]
6570 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6571
6572 (define_insn "*<plusminus_insn><mode>3_carry"
6573 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6574 (plusminus:SWI
6575 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6576 (plus:SWI
6577 (match_operator 3 "ix86_carry_flag_operator"
6578 [(reg FLAGS_REG) (const_int 0)])
6579 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6580 (clobber (reg:CC FLAGS_REG))]
6581 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6582 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6583 [(set_attr "type" "alu")
6584 (set_attr "use_carry" "1")
6585 (set_attr "pent_pair" "pu")
6586 (set_attr "mode" "<MODE>")])
6587
6588 (define_insn "*addsi3_carry_zext"
6589 [(set (match_operand:DI 0 "register_operand" "=r")
6590 (zero_extend:DI
6591 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6592 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6593 [(reg FLAGS_REG) (const_int 0)])
6594 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6595 (clobber (reg:CC FLAGS_REG))]
6596 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6597 "adc{l}\t{%2, %k0|%k0, %2}"
6598 [(set_attr "type" "alu")
6599 (set_attr "use_carry" "1")
6600 (set_attr "pent_pair" "pu")
6601 (set_attr "mode" "SI")])
6602
6603 (define_insn "*subsi3_carry_zext"
6604 [(set (match_operand:DI 0 "register_operand" "=r")
6605 (zero_extend:DI
6606 (minus:SI (match_operand:SI 1 "register_operand" "0")
6607 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6608 [(reg FLAGS_REG) (const_int 0)])
6609 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6610 (clobber (reg:CC FLAGS_REG))]
6611 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6612 "sbb{l}\t{%2, %k0|%k0, %2}"
6613 [(set_attr "type" "alu")
6614 (set_attr "pent_pair" "pu")
6615 (set_attr "mode" "SI")])
6616 \f
6617 ;; Overflow setting add and subtract instructions
6618
6619 (define_insn "*add<mode>3_cconly_overflow"
6620 [(set (reg:CCC FLAGS_REG)
6621 (compare:CCC
6622 (plus:SWI
6623 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6624 (match_operand:SWI 2 "<general_operand>" "<g>"))
6625 (match_dup 1)))
6626 (clobber (match_scratch:SWI 0 "=<r>"))]
6627 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6628 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6629 [(set_attr "type" "alu")
6630 (set_attr "mode" "<MODE>")])
6631
6632 (define_insn "*sub<mode>3_cconly_overflow"
6633 [(set (reg:CCC FLAGS_REG)
6634 (compare:CCC
6635 (minus:SWI
6636 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6637 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6638 (match_dup 0)))]
6639 ""
6640 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6641 [(set_attr "type" "icmp")
6642 (set_attr "mode" "<MODE>")])
6643
6644 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6645 [(set (reg:CCC FLAGS_REG)
6646 (compare:CCC
6647 (plusminus:SWI
6648 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6649 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6650 (match_dup 1)))
6651 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6652 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6653 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6654 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6655 [(set_attr "type" "alu")
6656 (set_attr "mode" "<MODE>")])
6657
6658 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6659 [(set (reg:CCC FLAGS_REG)
6660 (compare:CCC
6661 (plusminus:SI
6662 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6663 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6664 (match_dup 1)))
6665 (set (match_operand:DI 0 "register_operand" "=r")
6666 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6667 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6668 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6669 [(set_attr "type" "alu")
6670 (set_attr "mode" "SI")])
6671
6672 ;; The patterns that match these are at the end of this file.
6673
6674 (define_expand "<plusminus_insn>xf3"
6675 [(set (match_operand:XF 0 "register_operand")
6676 (plusminus:XF
6677 (match_operand:XF 1 "register_operand")
6678 (match_operand:XF 2 "register_operand")))]
6679 "TARGET_80387")
6680
6681 (define_expand "<plusminus_insn><mode>3"
6682 [(set (match_operand:MODEF 0 "register_operand")
6683 (plusminus:MODEF
6684 (match_operand:MODEF 1 "register_operand")
6685 (match_operand:MODEF 2 "nonimmediate_operand")))]
6686 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6687 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6688 \f
6689 ;; Multiply instructions
6690
6691 (define_expand "mul<mode>3"
6692 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6693 (mult:SWIM248
6694 (match_operand:SWIM248 1 "register_operand")
6695 (match_operand:SWIM248 2 "<general_operand>")))
6696 (clobber (reg:CC FLAGS_REG))])])
6697
6698 (define_expand "mulqi3"
6699 [(parallel [(set (match_operand:QI 0 "register_operand")
6700 (mult:QI
6701 (match_operand:QI 1 "register_operand")
6702 (match_operand:QI 2 "nonimmediate_operand")))
6703 (clobber (reg:CC FLAGS_REG))])]
6704 "TARGET_QIMODE_MATH")
6705
6706 ;; On AMDFAM10
6707 ;; IMUL reg32/64, reg32/64, imm8 Direct
6708 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6709 ;; IMUL reg32/64, reg32/64, imm32 Direct
6710 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6711 ;; IMUL reg32/64, reg32/64 Direct
6712 ;; IMUL reg32/64, mem32/64 Direct
6713 ;;
6714 ;; On BDVER1, all above IMULs use DirectPath
6715
6716 (define_insn "*mul<mode>3_1"
6717 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6718 (mult:SWI48
6719 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6720 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6721 (clobber (reg:CC FLAGS_REG))]
6722 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6723 "@
6724 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6725 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6726 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6727 [(set_attr "type" "imul")
6728 (set_attr "prefix_0f" "0,0,1")
6729 (set (attr "athlon_decode")
6730 (cond [(eq_attr "cpu" "athlon")
6731 (const_string "vector")
6732 (eq_attr "alternative" "1")
6733 (const_string "vector")
6734 (and (eq_attr "alternative" "2")
6735 (match_operand 1 "memory_operand"))
6736 (const_string "vector")]
6737 (const_string "direct")))
6738 (set (attr "amdfam10_decode")
6739 (cond [(and (eq_attr "alternative" "0,1")
6740 (match_operand 1 "memory_operand"))
6741 (const_string "vector")]
6742 (const_string "direct")))
6743 (set_attr "bdver1_decode" "direct")
6744 (set_attr "mode" "<MODE>")])
6745
6746 (define_insn "*mulsi3_1_zext"
6747 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6748 (zero_extend:DI
6749 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6750 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6751 (clobber (reg:CC FLAGS_REG))]
6752 "TARGET_64BIT
6753 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6754 "@
6755 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6756 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6757 imul{l}\t{%2, %k0|%k0, %2}"
6758 [(set_attr "type" "imul")
6759 (set_attr "prefix_0f" "0,0,1")
6760 (set (attr "athlon_decode")
6761 (cond [(eq_attr "cpu" "athlon")
6762 (const_string "vector")
6763 (eq_attr "alternative" "1")
6764 (const_string "vector")
6765 (and (eq_attr "alternative" "2")
6766 (match_operand 1 "memory_operand"))
6767 (const_string "vector")]
6768 (const_string "direct")))
6769 (set (attr "amdfam10_decode")
6770 (cond [(and (eq_attr "alternative" "0,1")
6771 (match_operand 1 "memory_operand"))
6772 (const_string "vector")]
6773 (const_string "direct")))
6774 (set_attr "bdver1_decode" "direct")
6775 (set_attr "mode" "SI")])
6776
6777 ;; On AMDFAM10
6778 ;; IMUL reg16, reg16, imm8 VectorPath
6779 ;; IMUL reg16, mem16, imm8 VectorPath
6780 ;; IMUL reg16, reg16, imm16 VectorPath
6781 ;; IMUL reg16, mem16, imm16 VectorPath
6782 ;; IMUL reg16, reg16 Direct
6783 ;; IMUL reg16, mem16 Direct
6784 ;;
6785 ;; On BDVER1, all HI MULs use DoublePath
6786
6787 (define_insn "*mulhi3_1"
6788 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6789 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6790 (match_operand:HI 2 "general_operand" "K,n,mr")))
6791 (clobber (reg:CC FLAGS_REG))]
6792 "TARGET_HIMODE_MATH
6793 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6794 "@
6795 imul{w}\t{%2, %1, %0|%0, %1, %2}
6796 imul{w}\t{%2, %1, %0|%0, %1, %2}
6797 imul{w}\t{%2, %0|%0, %2}"
6798 [(set_attr "type" "imul")
6799 (set_attr "prefix_0f" "0,0,1")
6800 (set (attr "athlon_decode")
6801 (cond [(eq_attr "cpu" "athlon")
6802 (const_string "vector")
6803 (eq_attr "alternative" "1,2")
6804 (const_string "vector")]
6805 (const_string "direct")))
6806 (set (attr "amdfam10_decode")
6807 (cond [(eq_attr "alternative" "0,1")
6808 (const_string "vector")]
6809 (const_string "direct")))
6810 (set_attr "bdver1_decode" "double")
6811 (set_attr "mode" "HI")])
6812
6813 ;;On AMDFAM10 and BDVER1
6814 ;; MUL reg8 Direct
6815 ;; MUL mem8 Direct
6816
6817 (define_insn "*mulqi3_1"
6818 [(set (match_operand:QI 0 "register_operand" "=a")
6819 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6820 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6821 (clobber (reg:CC FLAGS_REG))]
6822 "TARGET_QIMODE_MATH
6823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6824 "mul{b}\t%2"
6825 [(set_attr "type" "imul")
6826 (set_attr "length_immediate" "0")
6827 (set (attr "athlon_decode")
6828 (if_then_else (eq_attr "cpu" "athlon")
6829 (const_string "vector")
6830 (const_string "direct")))
6831 (set_attr "amdfam10_decode" "direct")
6832 (set_attr "bdver1_decode" "direct")
6833 (set_attr "mode" "QI")])
6834
6835 (define_expand "<u>mul<mode><dwi>3"
6836 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6837 (mult:<DWI>
6838 (any_extend:<DWI>
6839 (match_operand:DWIH 1 "nonimmediate_operand"))
6840 (any_extend:<DWI>
6841 (match_operand:DWIH 2 "register_operand"))))
6842 (clobber (reg:CC FLAGS_REG))])])
6843
6844 (define_expand "<u>mulqihi3"
6845 [(parallel [(set (match_operand:HI 0 "register_operand")
6846 (mult:HI
6847 (any_extend:HI
6848 (match_operand:QI 1 "nonimmediate_operand"))
6849 (any_extend:HI
6850 (match_operand:QI 2 "register_operand"))))
6851 (clobber (reg:CC FLAGS_REG))])]
6852 "TARGET_QIMODE_MATH")
6853
6854 (define_insn "*bmi2_umulditi3_1"
6855 [(set (match_operand:DI 0 "register_operand" "=r")
6856 (mult:DI
6857 (match_operand:DI 2 "nonimmediate_operand" "%d")
6858 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6859 (set (match_operand:DI 1 "register_operand" "=r")
6860 (truncate:DI
6861 (lshiftrt:TI
6862 (mult:TI (zero_extend:TI (match_dup 2))
6863 (zero_extend:TI (match_dup 3)))
6864 (const_int 64))))]
6865 "TARGET_64BIT && TARGET_BMI2
6866 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6867 "mulx\t{%3, %0, %1|%1, %0, %3}"
6868 [(set_attr "type" "imulx")
6869 (set_attr "prefix" "vex")
6870 (set_attr "mode" "DI")])
6871
6872 (define_insn "*bmi2_umulsidi3_1"
6873 [(set (match_operand:SI 0 "register_operand" "=r")
6874 (mult:SI
6875 (match_operand:SI 2 "nonimmediate_operand" "%d")
6876 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6877 (set (match_operand:SI 1 "register_operand" "=r")
6878 (truncate:SI
6879 (lshiftrt:DI
6880 (mult:DI (zero_extend:DI (match_dup 2))
6881 (zero_extend:DI (match_dup 3)))
6882 (const_int 32))))]
6883 "!TARGET_64BIT && TARGET_BMI2
6884 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6885 "mulx\t{%3, %0, %1|%1, %0, %3}"
6886 [(set_attr "type" "imulx")
6887 (set_attr "prefix" "vex")
6888 (set_attr "mode" "SI")])
6889
6890 (define_insn "*umul<mode><dwi>3_1"
6891 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6892 (mult:<DWI>
6893 (zero_extend:<DWI>
6894 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6895 (zero_extend:<DWI>
6896 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6897 (clobber (reg:CC FLAGS_REG))]
6898 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6899 "@
6900 #
6901 mul{<imodesuffix>}\t%2"
6902 [(set_attr "isa" "bmi2,*")
6903 (set_attr "type" "imulx,imul")
6904 (set_attr "length_immediate" "*,0")
6905 (set (attr "athlon_decode")
6906 (cond [(eq_attr "alternative" "1")
6907 (if_then_else (eq_attr "cpu" "athlon")
6908 (const_string "vector")
6909 (const_string "double"))]
6910 (const_string "*")))
6911 (set_attr "amdfam10_decode" "*,double")
6912 (set_attr "bdver1_decode" "*,direct")
6913 (set_attr "prefix" "vex,orig")
6914 (set_attr "mode" "<MODE>")])
6915
6916 ;; Convert mul to the mulx pattern to avoid flags dependency.
6917 (define_split
6918 [(set (match_operand:<DWI> 0 "register_operand")
6919 (mult:<DWI>
6920 (zero_extend:<DWI>
6921 (match_operand:DWIH 1 "register_operand"))
6922 (zero_extend:<DWI>
6923 (match_operand:DWIH 2 "nonimmediate_operand"))))
6924 (clobber (reg:CC FLAGS_REG))]
6925 "TARGET_BMI2 && reload_completed
6926 && true_regnum (operands[1]) == DX_REG"
6927 [(parallel [(set (match_dup 3)
6928 (mult:DWIH (match_dup 1) (match_dup 2)))
6929 (set (match_dup 4)
6930 (truncate:DWIH
6931 (lshiftrt:<DWI>
6932 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6933 (zero_extend:<DWI> (match_dup 2)))
6934 (match_dup 5))))])]
6935 {
6936 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6937
6938 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6939 })
6940
6941 (define_insn "*mul<mode><dwi>3_1"
6942 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6943 (mult:<DWI>
6944 (sign_extend:<DWI>
6945 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6946 (sign_extend:<DWI>
6947 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6948 (clobber (reg:CC FLAGS_REG))]
6949 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950 "imul{<imodesuffix>}\t%2"
6951 [(set_attr "type" "imul")
6952 (set_attr "length_immediate" "0")
6953 (set (attr "athlon_decode")
6954 (if_then_else (eq_attr "cpu" "athlon")
6955 (const_string "vector")
6956 (const_string "double")))
6957 (set_attr "amdfam10_decode" "double")
6958 (set_attr "bdver1_decode" "direct")
6959 (set_attr "mode" "<MODE>")])
6960
6961 (define_insn "*<u>mulqihi3_1"
6962 [(set (match_operand:HI 0 "register_operand" "=a")
6963 (mult:HI
6964 (any_extend:HI
6965 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6966 (any_extend:HI
6967 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6968 (clobber (reg:CC FLAGS_REG))]
6969 "TARGET_QIMODE_MATH
6970 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6971 "<sgnprefix>mul{b}\t%2"
6972 [(set_attr "type" "imul")
6973 (set_attr "length_immediate" "0")
6974 (set (attr "athlon_decode")
6975 (if_then_else (eq_attr "cpu" "athlon")
6976 (const_string "vector")
6977 (const_string "direct")))
6978 (set_attr "amdfam10_decode" "direct")
6979 (set_attr "bdver1_decode" "direct")
6980 (set_attr "mode" "QI")])
6981
6982 (define_expand "<s>mul<mode>3_highpart"
6983 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6984 (truncate:SWI48
6985 (lshiftrt:<DWI>
6986 (mult:<DWI>
6987 (any_extend:<DWI>
6988 (match_operand:SWI48 1 "nonimmediate_operand"))
6989 (any_extend:<DWI>
6990 (match_operand:SWI48 2 "register_operand")))
6991 (match_dup 4))))
6992 (clobber (match_scratch:SWI48 3))
6993 (clobber (reg:CC FLAGS_REG))])]
6994 ""
6995 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6996
6997 (define_insn "*<s>muldi3_highpart_1"
6998 [(set (match_operand:DI 0 "register_operand" "=d")
6999 (truncate:DI
7000 (lshiftrt:TI
7001 (mult:TI
7002 (any_extend:TI
7003 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7004 (any_extend:TI
7005 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7006 (const_int 64))))
7007 (clobber (match_scratch:DI 3 "=1"))
7008 (clobber (reg:CC FLAGS_REG))]
7009 "TARGET_64BIT
7010 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7011 "<sgnprefix>mul{q}\t%2"
7012 [(set_attr "type" "imul")
7013 (set_attr "length_immediate" "0")
7014 (set (attr "athlon_decode")
7015 (if_then_else (eq_attr "cpu" "athlon")
7016 (const_string "vector")
7017 (const_string "double")))
7018 (set_attr "amdfam10_decode" "double")
7019 (set_attr "bdver1_decode" "direct")
7020 (set_attr "mode" "DI")])
7021
7022 (define_insn "*<s>mulsi3_highpart_1"
7023 [(set (match_operand:SI 0 "register_operand" "=d")
7024 (truncate:SI
7025 (lshiftrt:DI
7026 (mult:DI
7027 (any_extend:DI
7028 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7029 (any_extend:DI
7030 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7031 (const_int 32))))
7032 (clobber (match_scratch:SI 3 "=1"))
7033 (clobber (reg:CC FLAGS_REG))]
7034 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7035 "<sgnprefix>mul{l}\t%2"
7036 [(set_attr "type" "imul")
7037 (set_attr "length_immediate" "0")
7038 (set (attr "athlon_decode")
7039 (if_then_else (eq_attr "cpu" "athlon")
7040 (const_string "vector")
7041 (const_string "double")))
7042 (set_attr "amdfam10_decode" "double")
7043 (set_attr "bdver1_decode" "direct")
7044 (set_attr "mode" "SI")])
7045
7046 (define_insn "*<s>mulsi3_highpart_zext"
7047 [(set (match_operand:DI 0 "register_operand" "=d")
7048 (zero_extend:DI (truncate:SI
7049 (lshiftrt:DI
7050 (mult:DI (any_extend:DI
7051 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7052 (any_extend:DI
7053 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7054 (const_int 32)))))
7055 (clobber (match_scratch:SI 3 "=1"))
7056 (clobber (reg:CC FLAGS_REG))]
7057 "TARGET_64BIT
7058 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7059 "<sgnprefix>mul{l}\t%2"
7060 [(set_attr "type" "imul")
7061 (set_attr "length_immediate" "0")
7062 (set (attr "athlon_decode")
7063 (if_then_else (eq_attr "cpu" "athlon")
7064 (const_string "vector")
7065 (const_string "double")))
7066 (set_attr "amdfam10_decode" "double")
7067 (set_attr "bdver1_decode" "direct")
7068 (set_attr "mode" "SI")])
7069
7070 ;; The patterns that match these are at the end of this file.
7071
7072 (define_expand "mulxf3"
7073 [(set (match_operand:XF 0 "register_operand")
7074 (mult:XF (match_operand:XF 1 "register_operand")
7075 (match_operand:XF 2 "register_operand")))]
7076 "TARGET_80387")
7077
7078 (define_expand "mul<mode>3"
7079 [(set (match_operand:MODEF 0 "register_operand")
7080 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7081 (match_operand:MODEF 2 "nonimmediate_operand")))]
7082 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7083 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7084 \f
7085 ;; Divide instructions
7086
7087 ;; The patterns that match these are at the end of this file.
7088
7089 (define_expand "divxf3"
7090 [(set (match_operand:XF 0 "register_operand")
7091 (div:XF (match_operand:XF 1 "register_operand")
7092 (match_operand:XF 2 "register_operand")))]
7093 "TARGET_80387")
7094
7095 (define_expand "divdf3"
7096 [(set (match_operand:DF 0 "register_operand")
7097 (div:DF (match_operand:DF 1 "register_operand")
7098 (match_operand:DF 2 "nonimmediate_operand")))]
7099 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7100 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7101
7102 (define_expand "divsf3"
7103 [(set (match_operand:SF 0 "register_operand")
7104 (div:SF (match_operand:SF 1 "register_operand")
7105 (match_operand:SF 2 "nonimmediate_operand")))]
7106 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7107 || TARGET_SSE_MATH"
7108 {
7109 if (TARGET_SSE_MATH
7110 && TARGET_RECIP_DIV
7111 && optimize_insn_for_speed_p ()
7112 && flag_finite_math_only && !flag_trapping_math
7113 && flag_unsafe_math_optimizations)
7114 {
7115 ix86_emit_swdivsf (operands[0], operands[1],
7116 operands[2], SFmode);
7117 DONE;
7118 }
7119 })
7120 \f
7121 ;; Divmod instructions.
7122
7123 (define_expand "divmod<mode>4"
7124 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7125 (div:SWIM248
7126 (match_operand:SWIM248 1 "register_operand")
7127 (match_operand:SWIM248 2 "nonimmediate_operand")))
7128 (set (match_operand:SWIM248 3 "register_operand")
7129 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7130 (clobber (reg:CC FLAGS_REG))])])
7131
7132 ;; Split with 8bit unsigned divide:
7133 ;; if (dividend an divisor are in [0-255])
7134 ;; use 8bit unsigned integer divide
7135 ;; else
7136 ;; use original integer divide
7137 (define_split
7138 [(set (match_operand:SWI48 0 "register_operand")
7139 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7140 (match_operand:SWI48 3 "nonimmediate_operand")))
7141 (set (match_operand:SWI48 1 "register_operand")
7142 (mod:SWI48 (match_dup 2) (match_dup 3)))
7143 (clobber (reg:CC FLAGS_REG))]
7144 "TARGET_USE_8BIT_IDIV
7145 && TARGET_QIMODE_MATH
7146 && can_create_pseudo_p ()
7147 && !optimize_insn_for_size_p ()"
7148 [(const_int 0)]
7149 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7150
7151 (define_insn_and_split "divmod<mode>4_1"
7152 [(set (match_operand:SWI48 0 "register_operand" "=a")
7153 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7154 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7155 (set (match_operand:SWI48 1 "register_operand" "=&d")
7156 (mod:SWI48 (match_dup 2) (match_dup 3)))
7157 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7158 (clobber (reg:CC FLAGS_REG))]
7159 ""
7160 "#"
7161 "reload_completed"
7162 [(parallel [(set (match_dup 1)
7163 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7164 (clobber (reg:CC FLAGS_REG))])
7165 (parallel [(set (match_dup 0)
7166 (div:SWI48 (match_dup 2) (match_dup 3)))
7167 (set (match_dup 1)
7168 (mod:SWI48 (match_dup 2) (match_dup 3)))
7169 (use (match_dup 1))
7170 (clobber (reg:CC FLAGS_REG))])]
7171 {
7172 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7173
7174 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7175 operands[4] = operands[2];
7176 else
7177 {
7178 /* Avoid use of cltd in favor of a mov+shift. */
7179 emit_move_insn (operands[1], operands[2]);
7180 operands[4] = operands[1];
7181 }
7182 }
7183 [(set_attr "type" "multi")
7184 (set_attr "mode" "<MODE>")])
7185
7186 (define_insn_and_split "*divmod<mode>4"
7187 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7188 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7189 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7190 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7191 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7192 (clobber (reg:CC FLAGS_REG))]
7193 ""
7194 "#"
7195 "reload_completed"
7196 [(parallel [(set (match_dup 1)
7197 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7198 (clobber (reg:CC FLAGS_REG))])
7199 (parallel [(set (match_dup 0)
7200 (div:SWIM248 (match_dup 2) (match_dup 3)))
7201 (set (match_dup 1)
7202 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7203 (use (match_dup 1))
7204 (clobber (reg:CC FLAGS_REG))])]
7205 {
7206 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7207
7208 if (<MODE>mode != HImode
7209 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7210 operands[4] = operands[2];
7211 else
7212 {
7213 /* Avoid use of cltd in favor of a mov+shift. */
7214 emit_move_insn (operands[1], operands[2]);
7215 operands[4] = operands[1];
7216 }
7217 }
7218 [(set_attr "type" "multi")
7219 (set_attr "mode" "<MODE>")])
7220
7221 (define_insn "*divmod<mode>4_noext"
7222 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7223 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7224 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7225 (set (match_operand:SWIM248 1 "register_operand" "=d")
7226 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7227 (use (match_operand:SWIM248 4 "register_operand" "1"))
7228 (clobber (reg:CC FLAGS_REG))]
7229 ""
7230 "idiv{<imodesuffix>}\t%3"
7231 [(set_attr "type" "idiv")
7232 (set_attr "mode" "<MODE>")])
7233
7234 (define_expand "divmodqi4"
7235 [(parallel [(set (match_operand:QI 0 "register_operand")
7236 (div:QI
7237 (match_operand:QI 1 "register_operand")
7238 (match_operand:QI 2 "nonimmediate_operand")))
7239 (set (match_operand:QI 3 "register_operand")
7240 (mod:QI (match_dup 1) (match_dup 2)))
7241 (clobber (reg:CC FLAGS_REG))])]
7242 "TARGET_QIMODE_MATH"
7243 {
7244 rtx div, mod, insn;
7245 rtx tmp0, tmp1;
7246
7247 tmp0 = gen_reg_rtx (HImode);
7248 tmp1 = gen_reg_rtx (HImode);
7249
7250 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7251 in AX. */
7252 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7253 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7254
7255 /* Extract remainder from AH. */
7256 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7257 insn = emit_move_insn (operands[3], tmp1);
7258
7259 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7260 set_unique_reg_note (insn, REG_EQUAL, mod);
7261
7262 /* Extract quotient from AL. */
7263 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7264
7265 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7266 set_unique_reg_note (insn, REG_EQUAL, div);
7267
7268 DONE;
7269 })
7270
7271 ;; Divide AX by r/m8, with result stored in
7272 ;; AL <- Quotient
7273 ;; AH <- Remainder
7274 ;; Change div/mod to HImode and extend the second argument to HImode
7275 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7276 ;; combine may fail.
7277 (define_insn "divmodhiqi3"
7278 [(set (match_operand:HI 0 "register_operand" "=a")
7279 (ior:HI
7280 (ashift:HI
7281 (zero_extend:HI
7282 (truncate:QI
7283 (mod:HI (match_operand:HI 1 "register_operand" "0")
7284 (sign_extend:HI
7285 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7286 (const_int 8))
7287 (zero_extend:HI
7288 (truncate:QI
7289 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7290 (clobber (reg:CC FLAGS_REG))]
7291 "TARGET_QIMODE_MATH"
7292 "idiv{b}\t%2"
7293 [(set_attr "type" "idiv")
7294 (set_attr "mode" "QI")])
7295
7296 (define_expand "udivmod<mode>4"
7297 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7298 (udiv:SWIM248
7299 (match_operand:SWIM248 1 "register_operand")
7300 (match_operand:SWIM248 2 "nonimmediate_operand")))
7301 (set (match_operand:SWIM248 3 "register_operand")
7302 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7303 (clobber (reg:CC FLAGS_REG))])])
7304
7305 ;; Split with 8bit unsigned divide:
7306 ;; if (dividend an divisor are in [0-255])
7307 ;; use 8bit unsigned integer divide
7308 ;; else
7309 ;; use original integer divide
7310 (define_split
7311 [(set (match_operand:SWI48 0 "register_operand")
7312 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7313 (match_operand:SWI48 3 "nonimmediate_operand")))
7314 (set (match_operand:SWI48 1 "register_operand")
7315 (umod:SWI48 (match_dup 2) (match_dup 3)))
7316 (clobber (reg:CC FLAGS_REG))]
7317 "TARGET_USE_8BIT_IDIV
7318 && TARGET_QIMODE_MATH
7319 && can_create_pseudo_p ()
7320 && !optimize_insn_for_size_p ()"
7321 [(const_int 0)]
7322 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7323
7324 (define_insn_and_split "udivmod<mode>4_1"
7325 [(set (match_operand:SWI48 0 "register_operand" "=a")
7326 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7327 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7328 (set (match_operand:SWI48 1 "register_operand" "=&d")
7329 (umod:SWI48 (match_dup 2) (match_dup 3)))
7330 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7331 (clobber (reg:CC FLAGS_REG))]
7332 ""
7333 "#"
7334 "reload_completed"
7335 [(set (match_dup 1) (const_int 0))
7336 (parallel [(set (match_dup 0)
7337 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7338 (set (match_dup 1)
7339 (umod:SWI48 (match_dup 2) (match_dup 3)))
7340 (use (match_dup 1))
7341 (clobber (reg:CC FLAGS_REG))])]
7342 ""
7343 [(set_attr "type" "multi")
7344 (set_attr "mode" "<MODE>")])
7345
7346 (define_insn_and_split "*udivmod<mode>4"
7347 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7348 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7349 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7350 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7351 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7352 (clobber (reg:CC FLAGS_REG))]
7353 ""
7354 "#"
7355 "reload_completed"
7356 [(set (match_dup 1) (const_int 0))
7357 (parallel [(set (match_dup 0)
7358 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7359 (set (match_dup 1)
7360 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7361 (use (match_dup 1))
7362 (clobber (reg:CC FLAGS_REG))])]
7363 ""
7364 [(set_attr "type" "multi")
7365 (set_attr "mode" "<MODE>")])
7366
7367 (define_insn "*udivmod<mode>4_noext"
7368 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7369 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7370 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7371 (set (match_operand:SWIM248 1 "register_operand" "=d")
7372 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7373 (use (match_operand:SWIM248 4 "register_operand" "1"))
7374 (clobber (reg:CC FLAGS_REG))]
7375 ""
7376 "div{<imodesuffix>}\t%3"
7377 [(set_attr "type" "idiv")
7378 (set_attr "mode" "<MODE>")])
7379
7380 (define_expand "udivmodqi4"
7381 [(parallel [(set (match_operand:QI 0 "register_operand")
7382 (udiv:QI
7383 (match_operand:QI 1 "register_operand")
7384 (match_operand:QI 2 "nonimmediate_operand")))
7385 (set (match_operand:QI 3 "register_operand")
7386 (umod:QI (match_dup 1) (match_dup 2)))
7387 (clobber (reg:CC FLAGS_REG))])]
7388 "TARGET_QIMODE_MATH"
7389 {
7390 rtx div, mod, insn;
7391 rtx tmp0, tmp1;
7392
7393 tmp0 = gen_reg_rtx (HImode);
7394 tmp1 = gen_reg_rtx (HImode);
7395
7396 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7397 in AX. */
7398 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7399 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7400
7401 /* Extract remainder from AH. */
7402 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7403 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7404 insn = emit_move_insn (operands[3], tmp1);
7405
7406 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7407 set_unique_reg_note (insn, REG_EQUAL, mod);
7408
7409 /* Extract quotient from AL. */
7410 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7411
7412 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7413 set_unique_reg_note (insn, REG_EQUAL, div);
7414
7415 DONE;
7416 })
7417
7418 (define_insn "udivmodhiqi3"
7419 [(set (match_operand:HI 0 "register_operand" "=a")
7420 (ior:HI
7421 (ashift:HI
7422 (zero_extend:HI
7423 (truncate:QI
7424 (mod:HI (match_operand:HI 1 "register_operand" "0")
7425 (zero_extend:HI
7426 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7427 (const_int 8))
7428 (zero_extend:HI
7429 (truncate:QI
7430 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7431 (clobber (reg:CC FLAGS_REG))]
7432 "TARGET_QIMODE_MATH"
7433 "div{b}\t%2"
7434 [(set_attr "type" "idiv")
7435 (set_attr "mode" "QI")])
7436
7437 ;; We cannot use div/idiv for double division, because it causes
7438 ;; "division by zero" on the overflow and that's not what we expect
7439 ;; from truncate. Because true (non truncating) double division is
7440 ;; never generated, we can't create this insn anyway.
7441 ;
7442 ;(define_insn ""
7443 ; [(set (match_operand:SI 0 "register_operand" "=a")
7444 ; (truncate:SI
7445 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7446 ; (zero_extend:DI
7447 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7448 ; (set (match_operand:SI 3 "register_operand" "=d")
7449 ; (truncate:SI
7450 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7451 ; (clobber (reg:CC FLAGS_REG))]
7452 ; ""
7453 ; "div{l}\t{%2, %0|%0, %2}"
7454 ; [(set_attr "type" "idiv")])
7455 \f
7456 ;;- Logical AND instructions
7457
7458 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7459 ;; Note that this excludes ah.
7460
7461 (define_expand "testsi_ccno_1"
7462 [(set (reg:CCNO FLAGS_REG)
7463 (compare:CCNO
7464 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7465 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7466 (const_int 0)))])
7467
7468 (define_expand "testqi_ccz_1"
7469 [(set (reg:CCZ FLAGS_REG)
7470 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7471 (match_operand:QI 1 "nonmemory_operand"))
7472 (const_int 0)))])
7473
7474 (define_expand "testdi_ccno_1"
7475 [(set (reg:CCNO FLAGS_REG)
7476 (compare:CCNO
7477 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7478 (match_operand:DI 1 "x86_64_szext_general_operand"))
7479 (const_int 0)))]
7480 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7481
7482 (define_insn "*testdi_1"
7483 [(set (reg FLAGS_REG)
7484 (compare
7485 (and:DI
7486 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7487 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7488 (const_int 0)))]
7489 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7490 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7491 "@
7492 test{l}\t{%k1, %k0|%k0, %k1}
7493 test{l}\t{%k1, %k0|%k0, %k1}
7494 test{q}\t{%1, %0|%0, %1}
7495 test{q}\t{%1, %0|%0, %1}
7496 test{q}\t{%1, %0|%0, %1}"
7497 [(set_attr "type" "test")
7498 (set_attr "modrm" "0,1,0,1,1")
7499 (set_attr "mode" "SI,SI,DI,DI,DI")])
7500
7501 (define_insn "*testqi_1_maybe_si"
7502 [(set (reg FLAGS_REG)
7503 (compare
7504 (and:QI
7505 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7506 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7507 (const_int 0)))]
7508 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7509 && ix86_match_ccmode (insn,
7510 CONST_INT_P (operands[1])
7511 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7512 {
7513 if (which_alternative == 3)
7514 {
7515 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7516 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7517 return "test{l}\t{%1, %k0|%k0, %1}";
7518 }
7519 return "test{b}\t{%1, %0|%0, %1}";
7520 }
7521 [(set_attr "type" "test")
7522 (set_attr "modrm" "0,1,1,1")
7523 (set_attr "mode" "QI,QI,QI,SI")
7524 (set_attr "pent_pair" "uv,np,uv,np")])
7525
7526 (define_insn "*test<mode>_1"
7527 [(set (reg FLAGS_REG)
7528 (compare
7529 (and:SWI124
7530 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7531 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7532 (const_int 0)))]
7533 "ix86_match_ccmode (insn, CCNOmode)
7534 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7535 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7536 [(set_attr "type" "test")
7537 (set_attr "modrm" "0,1,1")
7538 (set_attr "mode" "<MODE>")
7539 (set_attr "pent_pair" "uv,np,uv")])
7540
7541 (define_expand "testqi_ext_ccno_0"
7542 [(set (reg:CCNO FLAGS_REG)
7543 (compare:CCNO
7544 (and:SI
7545 (zero_extract:SI
7546 (match_operand 0 "ext_register_operand")
7547 (const_int 8)
7548 (const_int 8))
7549 (match_operand 1 "const_int_operand"))
7550 (const_int 0)))])
7551
7552 (define_insn "*testqi_ext_0"
7553 [(set (reg FLAGS_REG)
7554 (compare
7555 (and:SI
7556 (zero_extract:SI
7557 (match_operand 0 "ext_register_operand" "Q")
7558 (const_int 8)
7559 (const_int 8))
7560 (match_operand 1 "const_int_operand" "n"))
7561 (const_int 0)))]
7562 "ix86_match_ccmode (insn, CCNOmode)"
7563 "test{b}\t{%1, %h0|%h0, %1}"
7564 [(set_attr "type" "test")
7565 (set_attr "mode" "QI")
7566 (set_attr "length_immediate" "1")
7567 (set_attr "modrm" "1")
7568 (set_attr "pent_pair" "np")])
7569
7570 (define_insn "*testqi_ext_1_rex64"
7571 [(set (reg FLAGS_REG)
7572 (compare
7573 (and:SI
7574 (zero_extract:SI
7575 (match_operand 0 "ext_register_operand" "Q")
7576 (const_int 8)
7577 (const_int 8))
7578 (zero_extend:SI
7579 (match_operand:QI 1 "register_operand" "Q")))
7580 (const_int 0)))]
7581 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7582 "test{b}\t{%1, %h0|%h0, %1}"
7583 [(set_attr "type" "test")
7584 (set_attr "mode" "QI")])
7585
7586 (define_insn "*testqi_ext_1"
7587 [(set (reg FLAGS_REG)
7588 (compare
7589 (and:SI
7590 (zero_extract:SI
7591 (match_operand 0 "ext_register_operand" "Q")
7592 (const_int 8)
7593 (const_int 8))
7594 (zero_extend:SI
7595 (match_operand:QI 1 "general_operand" "Qm")))
7596 (const_int 0)))]
7597 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7598 "test{b}\t{%1, %h0|%h0, %1}"
7599 [(set_attr "type" "test")
7600 (set_attr "mode" "QI")])
7601
7602 (define_insn "*testqi_ext_2"
7603 [(set (reg FLAGS_REG)
7604 (compare
7605 (and:SI
7606 (zero_extract:SI
7607 (match_operand 0 "ext_register_operand" "Q")
7608 (const_int 8)
7609 (const_int 8))
7610 (zero_extract:SI
7611 (match_operand 1 "ext_register_operand" "Q")
7612 (const_int 8)
7613 (const_int 8)))
7614 (const_int 0)))]
7615 "ix86_match_ccmode (insn, CCNOmode)"
7616 "test{b}\t{%h1, %h0|%h0, %h1}"
7617 [(set_attr "type" "test")
7618 (set_attr "mode" "QI")])
7619
7620 (define_insn "*testqi_ext_3_rex64"
7621 [(set (reg FLAGS_REG)
7622 (compare (zero_extract:DI
7623 (match_operand 0 "nonimmediate_operand" "rm")
7624 (match_operand:DI 1 "const_int_operand")
7625 (match_operand:DI 2 "const_int_operand"))
7626 (const_int 0)))]
7627 "TARGET_64BIT
7628 && ix86_match_ccmode (insn, CCNOmode)
7629 && INTVAL (operands[1]) > 0
7630 && INTVAL (operands[2]) >= 0
7631 /* Ensure that resulting mask is zero or sign extended operand. */
7632 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7633 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7634 && INTVAL (operands[1]) > 32))
7635 && (GET_MODE (operands[0]) == SImode
7636 || GET_MODE (operands[0]) == DImode
7637 || GET_MODE (operands[0]) == HImode
7638 || GET_MODE (operands[0]) == QImode)"
7639 "#")
7640
7641 ;; Combine likes to form bit extractions for some tests. Humor it.
7642 (define_insn "*testqi_ext_3"
7643 [(set (reg FLAGS_REG)
7644 (compare (zero_extract:SI
7645 (match_operand 0 "nonimmediate_operand" "rm")
7646 (match_operand:SI 1 "const_int_operand")
7647 (match_operand:SI 2 "const_int_operand"))
7648 (const_int 0)))]
7649 "ix86_match_ccmode (insn, CCNOmode)
7650 && INTVAL (operands[1]) > 0
7651 && INTVAL (operands[2]) >= 0
7652 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7653 && (GET_MODE (operands[0]) == SImode
7654 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7655 || GET_MODE (operands[0]) == HImode
7656 || GET_MODE (operands[0]) == QImode)"
7657 "#")
7658
7659 (define_split
7660 [(set (match_operand 0 "flags_reg_operand")
7661 (match_operator 1 "compare_operator"
7662 [(zero_extract
7663 (match_operand 2 "nonimmediate_operand")
7664 (match_operand 3 "const_int_operand")
7665 (match_operand 4 "const_int_operand"))
7666 (const_int 0)]))]
7667 "ix86_match_ccmode (insn, CCNOmode)"
7668 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7669 {
7670 rtx val = operands[2];
7671 HOST_WIDE_INT len = INTVAL (operands[3]);
7672 HOST_WIDE_INT pos = INTVAL (operands[4]);
7673 HOST_WIDE_INT mask;
7674 enum machine_mode mode, submode;
7675
7676 mode = GET_MODE (val);
7677 if (MEM_P (val))
7678 {
7679 /* ??? Combine likes to put non-volatile mem extractions in QImode
7680 no matter the size of the test. So find a mode that works. */
7681 if (! MEM_VOLATILE_P (val))
7682 {
7683 mode = smallest_mode_for_size (pos + len, MODE_INT);
7684 val = adjust_address (val, mode, 0);
7685 }
7686 }
7687 else if (GET_CODE (val) == SUBREG
7688 && (submode = GET_MODE (SUBREG_REG (val)),
7689 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7690 && pos + len <= GET_MODE_BITSIZE (submode)
7691 && GET_MODE_CLASS (submode) == MODE_INT)
7692 {
7693 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7694 mode = submode;
7695 val = SUBREG_REG (val);
7696 }
7697 else if (mode == HImode && pos + len <= 8)
7698 {
7699 /* Small HImode tests can be converted to QImode. */
7700 mode = QImode;
7701 val = gen_lowpart (QImode, val);
7702 }
7703
7704 if (len == HOST_BITS_PER_WIDE_INT)
7705 mask = -1;
7706 else
7707 mask = ((HOST_WIDE_INT)1 << len) - 1;
7708 mask <<= pos;
7709
7710 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7711 })
7712
7713 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7714 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7715 ;; this is relatively important trick.
7716 ;; Do the conversion only post-reload to avoid limiting of the register class
7717 ;; to QI regs.
7718 (define_split
7719 [(set (match_operand 0 "flags_reg_operand")
7720 (match_operator 1 "compare_operator"
7721 [(and (match_operand 2 "register_operand")
7722 (match_operand 3 "const_int_operand"))
7723 (const_int 0)]))]
7724 "reload_completed
7725 && QI_REG_P (operands[2])
7726 && GET_MODE (operands[2]) != QImode
7727 && ((ix86_match_ccmode (insn, CCZmode)
7728 && !(INTVAL (operands[3]) & ~(255 << 8)))
7729 || (ix86_match_ccmode (insn, CCNOmode)
7730 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7731 [(set (match_dup 0)
7732 (match_op_dup 1
7733 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7734 (match_dup 3))
7735 (const_int 0)]))]
7736 {
7737 operands[2] = gen_lowpart (SImode, operands[2]);
7738 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7739 })
7740
7741 (define_split
7742 [(set (match_operand 0 "flags_reg_operand")
7743 (match_operator 1 "compare_operator"
7744 [(and (match_operand 2 "nonimmediate_operand")
7745 (match_operand 3 "const_int_operand"))
7746 (const_int 0)]))]
7747 "reload_completed
7748 && GET_MODE (operands[2]) != QImode
7749 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7750 && ((ix86_match_ccmode (insn, CCZmode)
7751 && !(INTVAL (operands[3]) & ~255))
7752 || (ix86_match_ccmode (insn, CCNOmode)
7753 && !(INTVAL (operands[3]) & ~127)))"
7754 [(set (match_dup 0)
7755 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7756 (const_int 0)]))]
7757 {
7758 operands[2] = gen_lowpart (QImode, operands[2]);
7759 operands[3] = gen_lowpart (QImode, operands[3]);
7760 })
7761
7762 ;; %%% This used to optimize known byte-wide and operations to memory,
7763 ;; and sometimes to QImode registers. If this is considered useful,
7764 ;; it should be done with splitters.
7765
7766 (define_expand "and<mode>3"
7767 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7768 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7769 (match_operand:SWIM 2 "<general_szext_operand>")))]
7770 ""
7771 {
7772 enum machine_mode mode = <MODE>mode;
7773 rtx (*insn) (rtx, rtx);
7774
7775 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7776 {
7777 HOST_WIDE_INT ival = INTVAL (operands[2]);
7778
7779 if (ival == (HOST_WIDE_INT) 0xffffffff)
7780 mode = SImode;
7781 else if (ival == 0xffff)
7782 mode = HImode;
7783 else if (ival == 0xff)
7784 mode = QImode;
7785 }
7786
7787 if (mode == <MODE>mode)
7788 {
7789 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7790 DONE;
7791 }
7792
7793 if (<MODE>mode == DImode)
7794 insn = (mode == SImode)
7795 ? gen_zero_extendsidi2
7796 : (mode == HImode)
7797 ? gen_zero_extendhidi2
7798 : gen_zero_extendqidi2;
7799 else if (<MODE>mode == SImode)
7800 insn = (mode == HImode)
7801 ? gen_zero_extendhisi2
7802 : gen_zero_extendqisi2;
7803 else if (<MODE>mode == HImode)
7804 insn = gen_zero_extendqihi2;
7805 else
7806 gcc_unreachable ();
7807
7808 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7809 DONE;
7810 })
7811
7812 (define_insn "*anddi_1"
7813 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7814 (and:DI
7815 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7816 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7817 (clobber (reg:CC FLAGS_REG))]
7818 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7819 {
7820 switch (get_attr_type (insn))
7821 {
7822 case TYPE_IMOVX:
7823 return "#";
7824
7825 default:
7826 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7827 if (get_attr_mode (insn) == MODE_SI)
7828 return "and{l}\t{%k2, %k0|%k0, %k2}";
7829 else
7830 return "and{q}\t{%2, %0|%0, %2}";
7831 }
7832 }
7833 [(set_attr "type" "alu,alu,alu,imovx")
7834 (set_attr "length_immediate" "*,*,*,0")
7835 (set (attr "prefix_rex")
7836 (if_then_else
7837 (and (eq_attr "type" "imovx")
7838 (and (match_test "INTVAL (operands[2]) == 0xff")
7839 (match_operand 1 "ext_QIreg_operand")))
7840 (const_string "1")
7841 (const_string "*")))
7842 (set_attr "mode" "SI,DI,DI,SI")])
7843
7844 (define_insn "*andsi_1"
7845 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7846 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7847 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7848 (clobber (reg:CC FLAGS_REG))]
7849 "ix86_binary_operator_ok (AND, SImode, operands)"
7850 {
7851 switch (get_attr_type (insn))
7852 {
7853 case TYPE_IMOVX:
7854 return "#";
7855
7856 default:
7857 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7858 return "and{l}\t{%2, %0|%0, %2}";
7859 }
7860 }
7861 [(set_attr "type" "alu,alu,imovx")
7862 (set (attr "prefix_rex")
7863 (if_then_else
7864 (and (eq_attr "type" "imovx")
7865 (and (match_test "INTVAL (operands[2]) == 0xff")
7866 (match_operand 1 "ext_QIreg_operand")))
7867 (const_string "1")
7868 (const_string "*")))
7869 (set_attr "length_immediate" "*,*,0")
7870 (set_attr "mode" "SI")])
7871
7872 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7873 (define_insn "*andsi_1_zext"
7874 [(set (match_operand:DI 0 "register_operand" "=r")
7875 (zero_extend:DI
7876 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7877 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7878 (clobber (reg:CC FLAGS_REG))]
7879 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7880 "and{l}\t{%2, %k0|%k0, %2}"
7881 [(set_attr "type" "alu")
7882 (set_attr "mode" "SI")])
7883
7884 (define_insn "*andhi_1"
7885 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7886 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7887 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7888 (clobber (reg:CC FLAGS_REG))]
7889 "ix86_binary_operator_ok (AND, HImode, operands)"
7890 {
7891 switch (get_attr_type (insn))
7892 {
7893 case TYPE_IMOVX:
7894 return "#";
7895
7896 default:
7897 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7898 return "and{w}\t{%2, %0|%0, %2}";
7899 }
7900 }
7901 [(set_attr "type" "alu,alu,imovx")
7902 (set_attr "length_immediate" "*,*,0")
7903 (set (attr "prefix_rex")
7904 (if_then_else
7905 (and (eq_attr "type" "imovx")
7906 (match_operand 1 "ext_QIreg_operand"))
7907 (const_string "1")
7908 (const_string "*")))
7909 (set_attr "mode" "HI,HI,SI")])
7910
7911 ;; %%% Potential partial reg stall on alternative 2. What to do?
7912 (define_insn "*andqi_1"
7913 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7914 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7915 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7916 (clobber (reg:CC FLAGS_REG))]
7917 "ix86_binary_operator_ok (AND, QImode, operands)"
7918 "@
7919 and{b}\t{%2, %0|%0, %2}
7920 and{b}\t{%2, %0|%0, %2}
7921 and{l}\t{%k2, %k0|%k0, %k2}"
7922 [(set_attr "type" "alu")
7923 (set_attr "mode" "QI,QI,SI")])
7924
7925 (define_insn "*andqi_1_slp"
7926 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7927 (and:QI (match_dup 0)
7928 (match_operand:QI 1 "general_operand" "qn,qmn")))
7929 (clobber (reg:CC FLAGS_REG))]
7930 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7931 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7932 "and{b}\t{%1, %0|%0, %1}"
7933 [(set_attr "type" "alu1")
7934 (set_attr "mode" "QI")])
7935
7936 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7937 (define_split
7938 [(set (match_operand:DI 0 "register_operand")
7939 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7940 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7941 (clobber (reg:CC FLAGS_REG))]
7942 "TARGET_64BIT"
7943 [(parallel [(set (match_dup 0)
7944 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7945 (clobber (reg:CC FLAGS_REG))])]
7946 "operands[2] = gen_lowpart (SImode, operands[2]);")
7947
7948 (define_split
7949 [(set (match_operand:SWI248 0 "register_operand")
7950 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7951 (match_operand:SWI248 2 "const_int_operand")))
7952 (clobber (reg:CC FLAGS_REG))]
7953 "reload_completed
7954 && true_regnum (operands[0]) != true_regnum (operands[1])"
7955 [(const_int 0)]
7956 {
7957 HOST_WIDE_INT ival = INTVAL (operands[2]);
7958 enum machine_mode mode;
7959 rtx (*insn) (rtx, rtx);
7960
7961 if (ival == (HOST_WIDE_INT) 0xffffffff)
7962 mode = SImode;
7963 else if (ival == 0xffff)
7964 mode = HImode;
7965 else
7966 {
7967 gcc_assert (ival == 0xff);
7968 mode = QImode;
7969 }
7970
7971 if (<MODE>mode == DImode)
7972 insn = (mode == SImode)
7973 ? gen_zero_extendsidi2
7974 : (mode == HImode)
7975 ? gen_zero_extendhidi2
7976 : gen_zero_extendqidi2;
7977 else
7978 {
7979 if (<MODE>mode != SImode)
7980 /* Zero extend to SImode to avoid partial register stalls. */
7981 operands[0] = gen_lowpart (SImode, operands[0]);
7982
7983 insn = (mode == HImode)
7984 ? gen_zero_extendhisi2
7985 : gen_zero_extendqisi2;
7986 }
7987 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7988 DONE;
7989 })
7990
7991 (define_split
7992 [(set (match_operand 0 "register_operand")
7993 (and (match_dup 0)
7994 (const_int -65536)))
7995 (clobber (reg:CC FLAGS_REG))]
7996 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7997 || optimize_function_for_size_p (cfun)"
7998 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7999 "operands[1] = gen_lowpart (HImode, operands[0]);")
8000
8001 (define_split
8002 [(set (match_operand 0 "ext_register_operand")
8003 (and (match_dup 0)
8004 (const_int -256)))
8005 (clobber (reg:CC FLAGS_REG))]
8006 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8007 && reload_completed"
8008 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8009 "operands[1] = gen_lowpart (QImode, operands[0]);")
8010
8011 (define_split
8012 [(set (match_operand 0 "ext_register_operand")
8013 (and (match_dup 0)
8014 (const_int -65281)))
8015 (clobber (reg:CC FLAGS_REG))]
8016 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8017 && reload_completed"
8018 [(parallel [(set (zero_extract:SI (match_dup 0)
8019 (const_int 8)
8020 (const_int 8))
8021 (xor:SI
8022 (zero_extract:SI (match_dup 0)
8023 (const_int 8)
8024 (const_int 8))
8025 (zero_extract:SI (match_dup 0)
8026 (const_int 8)
8027 (const_int 8))))
8028 (clobber (reg:CC FLAGS_REG))])]
8029 "operands[0] = gen_lowpart (SImode, operands[0]);")
8030
8031 (define_insn "*anddi_2"
8032 [(set (reg FLAGS_REG)
8033 (compare
8034 (and:DI
8035 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8036 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8037 (const_int 0)))
8038 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8039 (and:DI (match_dup 1) (match_dup 2)))]
8040 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8041 && ix86_binary_operator_ok (AND, DImode, operands)"
8042 "@
8043 and{l}\t{%k2, %k0|%k0, %k2}
8044 and{q}\t{%2, %0|%0, %2}
8045 and{q}\t{%2, %0|%0, %2}"
8046 [(set_attr "type" "alu")
8047 (set_attr "mode" "SI,DI,DI")])
8048
8049 (define_insn "*andqi_2_maybe_si"
8050 [(set (reg FLAGS_REG)
8051 (compare (and:QI
8052 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8053 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8054 (const_int 0)))
8055 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8056 (and:QI (match_dup 1) (match_dup 2)))]
8057 "ix86_binary_operator_ok (AND, QImode, operands)
8058 && ix86_match_ccmode (insn,
8059 CONST_INT_P (operands[2])
8060 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8061 {
8062 if (which_alternative == 2)
8063 {
8064 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8065 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8066 return "and{l}\t{%2, %k0|%k0, %2}";
8067 }
8068 return "and{b}\t{%2, %0|%0, %2}";
8069 }
8070 [(set_attr "type" "alu")
8071 (set_attr "mode" "QI,QI,SI")])
8072
8073 (define_insn "*and<mode>_2"
8074 [(set (reg FLAGS_REG)
8075 (compare (and:SWI124
8076 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8077 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8078 (const_int 0)))
8079 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8080 (and:SWI124 (match_dup 1) (match_dup 2)))]
8081 "ix86_match_ccmode (insn, CCNOmode)
8082 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8083 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8084 [(set_attr "type" "alu")
8085 (set_attr "mode" "<MODE>")])
8086
8087 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8088 (define_insn "*andsi_2_zext"
8089 [(set (reg FLAGS_REG)
8090 (compare (and:SI
8091 (match_operand:SI 1 "nonimmediate_operand" "%0")
8092 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8093 (const_int 0)))
8094 (set (match_operand:DI 0 "register_operand" "=r")
8095 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8096 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8097 && ix86_binary_operator_ok (AND, SImode, operands)"
8098 "and{l}\t{%2, %k0|%k0, %2}"
8099 [(set_attr "type" "alu")
8100 (set_attr "mode" "SI")])
8101
8102 (define_insn "*andqi_2_slp"
8103 [(set (reg FLAGS_REG)
8104 (compare (and:QI
8105 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8106 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8107 (const_int 0)))
8108 (set (strict_low_part (match_dup 0))
8109 (and:QI (match_dup 0) (match_dup 1)))]
8110 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8111 && ix86_match_ccmode (insn, CCNOmode)
8112 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8113 "and{b}\t{%1, %0|%0, %1}"
8114 [(set_attr "type" "alu1")
8115 (set_attr "mode" "QI")])
8116
8117 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8118 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8119 ;; for a QImode operand, which of course failed.
8120 (define_insn "andqi_ext_0"
8121 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8122 (const_int 8)
8123 (const_int 8))
8124 (and:SI
8125 (zero_extract:SI
8126 (match_operand 1 "ext_register_operand" "0")
8127 (const_int 8)
8128 (const_int 8))
8129 (match_operand 2 "const_int_operand" "n")))
8130 (clobber (reg:CC FLAGS_REG))]
8131 ""
8132 "and{b}\t{%2, %h0|%h0, %2}"
8133 [(set_attr "type" "alu")
8134 (set_attr "length_immediate" "1")
8135 (set_attr "modrm" "1")
8136 (set_attr "mode" "QI")])
8137
8138 ;; Generated by peephole translating test to and. This shows up
8139 ;; often in fp comparisons.
8140 (define_insn "*andqi_ext_0_cc"
8141 [(set (reg FLAGS_REG)
8142 (compare
8143 (and:SI
8144 (zero_extract:SI
8145 (match_operand 1 "ext_register_operand" "0")
8146 (const_int 8)
8147 (const_int 8))
8148 (match_operand 2 "const_int_operand" "n"))
8149 (const_int 0)))
8150 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8151 (const_int 8)
8152 (const_int 8))
8153 (and:SI
8154 (zero_extract:SI
8155 (match_dup 1)
8156 (const_int 8)
8157 (const_int 8))
8158 (match_dup 2)))]
8159 "ix86_match_ccmode (insn, CCNOmode)"
8160 "and{b}\t{%2, %h0|%h0, %2}"
8161 [(set_attr "type" "alu")
8162 (set_attr "length_immediate" "1")
8163 (set_attr "modrm" "1")
8164 (set_attr "mode" "QI")])
8165
8166 (define_insn "*andqi_ext_1_rex64"
8167 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8168 (const_int 8)
8169 (const_int 8))
8170 (and:SI
8171 (zero_extract:SI
8172 (match_operand 1 "ext_register_operand" "0")
8173 (const_int 8)
8174 (const_int 8))
8175 (zero_extend:SI
8176 (match_operand 2 "ext_register_operand" "Q"))))
8177 (clobber (reg:CC FLAGS_REG))]
8178 "TARGET_64BIT"
8179 "and{b}\t{%2, %h0|%h0, %2}"
8180 [(set_attr "type" "alu")
8181 (set_attr "length_immediate" "0")
8182 (set_attr "mode" "QI")])
8183
8184 (define_insn "*andqi_ext_1"
8185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8186 (const_int 8)
8187 (const_int 8))
8188 (and:SI
8189 (zero_extract:SI
8190 (match_operand 1 "ext_register_operand" "0")
8191 (const_int 8)
8192 (const_int 8))
8193 (zero_extend:SI
8194 (match_operand:QI 2 "general_operand" "Qm"))))
8195 (clobber (reg:CC FLAGS_REG))]
8196 "!TARGET_64BIT"
8197 "and{b}\t{%2, %h0|%h0, %2}"
8198 [(set_attr "type" "alu")
8199 (set_attr "length_immediate" "0")
8200 (set_attr "mode" "QI")])
8201
8202 (define_insn "*andqi_ext_2"
8203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8204 (const_int 8)
8205 (const_int 8))
8206 (and:SI
8207 (zero_extract:SI
8208 (match_operand 1 "ext_register_operand" "%0")
8209 (const_int 8)
8210 (const_int 8))
8211 (zero_extract:SI
8212 (match_operand 2 "ext_register_operand" "Q")
8213 (const_int 8)
8214 (const_int 8))))
8215 (clobber (reg:CC FLAGS_REG))]
8216 ""
8217 "and{b}\t{%h2, %h0|%h0, %h2}"
8218 [(set_attr "type" "alu")
8219 (set_attr "length_immediate" "0")
8220 (set_attr "mode" "QI")])
8221
8222 ;; Convert wide AND instructions with immediate operand to shorter QImode
8223 ;; equivalents when possible.
8224 ;; Don't do the splitting with memory operands, since it introduces risk
8225 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8226 ;; for size, but that can (should?) be handled by generic code instead.
8227 (define_split
8228 [(set (match_operand 0 "register_operand")
8229 (and (match_operand 1 "register_operand")
8230 (match_operand 2 "const_int_operand")))
8231 (clobber (reg:CC FLAGS_REG))]
8232 "reload_completed
8233 && QI_REG_P (operands[0])
8234 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8235 && !(~INTVAL (operands[2]) & ~(255 << 8))
8236 && GET_MODE (operands[0]) != QImode"
8237 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8238 (and:SI (zero_extract:SI (match_dup 1)
8239 (const_int 8) (const_int 8))
8240 (match_dup 2)))
8241 (clobber (reg:CC FLAGS_REG))])]
8242 {
8243 operands[0] = gen_lowpart (SImode, operands[0]);
8244 operands[1] = gen_lowpart (SImode, operands[1]);
8245 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8246 })
8247
8248 ;; Since AND can be encoded with sign extended immediate, this is only
8249 ;; profitable when 7th bit is not set.
8250 (define_split
8251 [(set (match_operand 0 "register_operand")
8252 (and (match_operand 1 "general_operand")
8253 (match_operand 2 "const_int_operand")))
8254 (clobber (reg:CC FLAGS_REG))]
8255 "reload_completed
8256 && ANY_QI_REG_P (operands[0])
8257 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8258 && !(~INTVAL (operands[2]) & ~255)
8259 && !(INTVAL (operands[2]) & 128)
8260 && GET_MODE (operands[0]) != QImode"
8261 [(parallel [(set (strict_low_part (match_dup 0))
8262 (and:QI (match_dup 1)
8263 (match_dup 2)))
8264 (clobber (reg:CC FLAGS_REG))])]
8265 {
8266 operands[0] = gen_lowpart (QImode, operands[0]);
8267 operands[1] = gen_lowpart (QImode, operands[1]);
8268 operands[2] = gen_lowpart (QImode, operands[2]);
8269 })
8270 \f
8271 ;; Logical inclusive and exclusive OR instructions
8272
8273 ;; %%% This used to optimize known byte-wide and operations to memory.
8274 ;; If this is considered useful, it should be done with splitters.
8275
8276 (define_expand "<code><mode>3"
8277 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8278 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8279 (match_operand:SWIM 2 "<general_operand>")))]
8280 ""
8281 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8282
8283 (define_insn "*<code><mode>_1"
8284 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8285 (any_or:SWI248
8286 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8287 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8288 (clobber (reg:CC FLAGS_REG))]
8289 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8290 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8291 [(set_attr "type" "alu")
8292 (set_attr "mode" "<MODE>")])
8293
8294 ;; %%% Potential partial reg stall on alternative 2. What to do?
8295 (define_insn "*<code>qi_1"
8296 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8297 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8298 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8299 (clobber (reg:CC FLAGS_REG))]
8300 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8301 "@
8302 <logic>{b}\t{%2, %0|%0, %2}
8303 <logic>{b}\t{%2, %0|%0, %2}
8304 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "QI,QI,SI")])
8307
8308 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8309 (define_insn "*<code>si_1_zext"
8310 [(set (match_operand:DI 0 "register_operand" "=r")
8311 (zero_extend:DI
8312 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8313 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8314 (clobber (reg:CC FLAGS_REG))]
8315 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8316 "<logic>{l}\t{%2, %k0|%k0, %2}"
8317 [(set_attr "type" "alu")
8318 (set_attr "mode" "SI")])
8319
8320 (define_insn "*<code>si_1_zext_imm"
8321 [(set (match_operand:DI 0 "register_operand" "=r")
8322 (any_or:DI
8323 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8324 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8325 (clobber (reg:CC FLAGS_REG))]
8326 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8327 "<logic>{l}\t{%2, %k0|%k0, %2}"
8328 [(set_attr "type" "alu")
8329 (set_attr "mode" "SI")])
8330
8331 (define_insn "*<code>qi_1_slp"
8332 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8333 (any_or:QI (match_dup 0)
8334 (match_operand:QI 1 "general_operand" "qmn,qn")))
8335 (clobber (reg:CC FLAGS_REG))]
8336 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8337 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8338 "<logic>{b}\t{%1, %0|%0, %1}"
8339 [(set_attr "type" "alu1")
8340 (set_attr "mode" "QI")])
8341
8342 (define_insn "*<code><mode>_2"
8343 [(set (reg FLAGS_REG)
8344 (compare (any_or:SWI
8345 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8346 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8347 (const_int 0)))
8348 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8349 (any_or:SWI (match_dup 1) (match_dup 2)))]
8350 "ix86_match_ccmode (insn, CCNOmode)
8351 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8352 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8353 [(set_attr "type" "alu")
8354 (set_attr "mode" "<MODE>")])
8355
8356 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8357 ;; ??? Special case for immediate operand is missing - it is tricky.
8358 (define_insn "*<code>si_2_zext"
8359 [(set (reg FLAGS_REG)
8360 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8361 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8362 (const_int 0)))
8363 (set (match_operand:DI 0 "register_operand" "=r")
8364 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8365 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8366 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8367 "<logic>{l}\t{%2, %k0|%k0, %2}"
8368 [(set_attr "type" "alu")
8369 (set_attr "mode" "SI")])
8370
8371 (define_insn "*<code>si_2_zext_imm"
8372 [(set (reg FLAGS_REG)
8373 (compare (any_or:SI
8374 (match_operand:SI 1 "nonimmediate_operand" "%0")
8375 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8376 (const_int 0)))
8377 (set (match_operand:DI 0 "register_operand" "=r")
8378 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8379 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8380 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8381 "<logic>{l}\t{%2, %k0|%k0, %2}"
8382 [(set_attr "type" "alu")
8383 (set_attr "mode" "SI")])
8384
8385 (define_insn "*<code>qi_2_slp"
8386 [(set (reg FLAGS_REG)
8387 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8388 (match_operand:QI 1 "general_operand" "qmn,qn"))
8389 (const_int 0)))
8390 (set (strict_low_part (match_dup 0))
8391 (any_or:QI (match_dup 0) (match_dup 1)))]
8392 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8393 && ix86_match_ccmode (insn, CCNOmode)
8394 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8395 "<logic>{b}\t{%1, %0|%0, %1}"
8396 [(set_attr "type" "alu1")
8397 (set_attr "mode" "QI")])
8398
8399 (define_insn "*<code><mode>_3"
8400 [(set (reg FLAGS_REG)
8401 (compare (any_or:SWI
8402 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8403 (match_operand:SWI 2 "<general_operand>" "<g>"))
8404 (const_int 0)))
8405 (clobber (match_scratch:SWI 0 "=<r>"))]
8406 "ix86_match_ccmode (insn, CCNOmode)
8407 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8408 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8409 [(set_attr "type" "alu")
8410 (set_attr "mode" "<MODE>")])
8411
8412 (define_insn "*<code>qi_ext_0"
8413 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8414 (const_int 8)
8415 (const_int 8))
8416 (any_or:SI
8417 (zero_extract:SI
8418 (match_operand 1 "ext_register_operand" "0")
8419 (const_int 8)
8420 (const_int 8))
8421 (match_operand 2 "const_int_operand" "n")))
8422 (clobber (reg:CC FLAGS_REG))]
8423 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8424 "<logic>{b}\t{%2, %h0|%h0, %2}"
8425 [(set_attr "type" "alu")
8426 (set_attr "length_immediate" "1")
8427 (set_attr "modrm" "1")
8428 (set_attr "mode" "QI")])
8429
8430 (define_insn "*<code>qi_ext_1_rex64"
8431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8432 (const_int 8)
8433 (const_int 8))
8434 (any_or:SI
8435 (zero_extract:SI
8436 (match_operand 1 "ext_register_operand" "0")
8437 (const_int 8)
8438 (const_int 8))
8439 (zero_extend:SI
8440 (match_operand 2 "ext_register_operand" "Q"))))
8441 (clobber (reg:CC FLAGS_REG))]
8442 "TARGET_64BIT
8443 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8444 "<logic>{b}\t{%2, %h0|%h0, %2}"
8445 [(set_attr "type" "alu")
8446 (set_attr "length_immediate" "0")
8447 (set_attr "mode" "QI")])
8448
8449 (define_insn "*<code>qi_ext_1"
8450 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8451 (const_int 8)
8452 (const_int 8))
8453 (any_or:SI
8454 (zero_extract:SI
8455 (match_operand 1 "ext_register_operand" "0")
8456 (const_int 8)
8457 (const_int 8))
8458 (zero_extend:SI
8459 (match_operand:QI 2 "general_operand" "Qm"))))
8460 (clobber (reg:CC FLAGS_REG))]
8461 "!TARGET_64BIT
8462 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8463 "<logic>{b}\t{%2, %h0|%h0, %2}"
8464 [(set_attr "type" "alu")
8465 (set_attr "length_immediate" "0")
8466 (set_attr "mode" "QI")])
8467
8468 (define_insn "*<code>qi_ext_2"
8469 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8470 (const_int 8)
8471 (const_int 8))
8472 (any_or:SI
8473 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8474 (const_int 8)
8475 (const_int 8))
8476 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8477 (const_int 8)
8478 (const_int 8))))
8479 (clobber (reg:CC FLAGS_REG))]
8480 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8481 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8482 [(set_attr "type" "alu")
8483 (set_attr "length_immediate" "0")
8484 (set_attr "mode" "QI")])
8485
8486 (define_split
8487 [(set (match_operand 0 "register_operand")
8488 (any_or (match_operand 1 "register_operand")
8489 (match_operand 2 "const_int_operand")))
8490 (clobber (reg:CC FLAGS_REG))]
8491 "reload_completed
8492 && QI_REG_P (operands[0])
8493 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8494 && !(INTVAL (operands[2]) & ~(255 << 8))
8495 && GET_MODE (operands[0]) != QImode"
8496 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8497 (any_or:SI (zero_extract:SI (match_dup 1)
8498 (const_int 8) (const_int 8))
8499 (match_dup 2)))
8500 (clobber (reg:CC FLAGS_REG))])]
8501 {
8502 operands[0] = gen_lowpart (SImode, operands[0]);
8503 operands[1] = gen_lowpart (SImode, operands[1]);
8504 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8505 })
8506
8507 ;; Since OR can be encoded with sign extended immediate, this is only
8508 ;; profitable when 7th bit is set.
8509 (define_split
8510 [(set (match_operand 0 "register_operand")
8511 (any_or (match_operand 1 "general_operand")
8512 (match_operand 2 "const_int_operand")))
8513 (clobber (reg:CC FLAGS_REG))]
8514 "reload_completed
8515 && ANY_QI_REG_P (operands[0])
8516 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8517 && !(INTVAL (operands[2]) & ~255)
8518 && (INTVAL (operands[2]) & 128)
8519 && GET_MODE (operands[0]) != QImode"
8520 [(parallel [(set (strict_low_part (match_dup 0))
8521 (any_or:QI (match_dup 1)
8522 (match_dup 2)))
8523 (clobber (reg:CC FLAGS_REG))])]
8524 {
8525 operands[0] = gen_lowpart (QImode, operands[0]);
8526 operands[1] = gen_lowpart (QImode, operands[1]);
8527 operands[2] = gen_lowpart (QImode, operands[2]);
8528 })
8529
8530 (define_expand "xorqi_cc_ext_1"
8531 [(parallel [
8532 (set (reg:CCNO FLAGS_REG)
8533 (compare:CCNO
8534 (xor:SI
8535 (zero_extract:SI
8536 (match_operand 1 "ext_register_operand")
8537 (const_int 8)
8538 (const_int 8))
8539 (match_operand:QI 2 "general_operand"))
8540 (const_int 0)))
8541 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8542 (const_int 8)
8543 (const_int 8))
8544 (xor:SI
8545 (zero_extract:SI
8546 (match_dup 1)
8547 (const_int 8)
8548 (const_int 8))
8549 (match_dup 2)))])])
8550
8551 (define_insn "*xorqi_cc_ext_1_rex64"
8552 [(set (reg FLAGS_REG)
8553 (compare
8554 (xor:SI
8555 (zero_extract:SI
8556 (match_operand 1 "ext_register_operand" "0")
8557 (const_int 8)
8558 (const_int 8))
8559 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8560 (const_int 0)))
8561 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8562 (const_int 8)
8563 (const_int 8))
8564 (xor:SI
8565 (zero_extract:SI
8566 (match_dup 1)
8567 (const_int 8)
8568 (const_int 8))
8569 (match_dup 2)))]
8570 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8571 "xor{b}\t{%2, %h0|%h0, %2}"
8572 [(set_attr "type" "alu")
8573 (set_attr "modrm" "1")
8574 (set_attr "mode" "QI")])
8575
8576 (define_insn "*xorqi_cc_ext_1"
8577 [(set (reg FLAGS_REG)
8578 (compare
8579 (xor:SI
8580 (zero_extract:SI
8581 (match_operand 1 "ext_register_operand" "0")
8582 (const_int 8)
8583 (const_int 8))
8584 (match_operand:QI 2 "general_operand" "qmn"))
8585 (const_int 0)))
8586 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8587 (const_int 8)
8588 (const_int 8))
8589 (xor:SI
8590 (zero_extract:SI
8591 (match_dup 1)
8592 (const_int 8)
8593 (const_int 8))
8594 (match_dup 2)))]
8595 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8596 "xor{b}\t{%2, %h0|%h0, %2}"
8597 [(set_attr "type" "alu")
8598 (set_attr "modrm" "1")
8599 (set_attr "mode" "QI")])
8600 \f
8601 ;; Negation instructions
8602
8603 (define_expand "neg<mode>2"
8604 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8605 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8606 ""
8607 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8608
8609 (define_insn_and_split "*neg<dwi>2_doubleword"
8610 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8611 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8612 (clobber (reg:CC FLAGS_REG))]
8613 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8614 "#"
8615 "reload_completed"
8616 [(parallel
8617 [(set (reg:CCZ FLAGS_REG)
8618 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8619 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8620 (parallel
8621 [(set (match_dup 2)
8622 (plus:DWIH (match_dup 3)
8623 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8624 (const_int 0))))
8625 (clobber (reg:CC FLAGS_REG))])
8626 (parallel
8627 [(set (match_dup 2)
8628 (neg:DWIH (match_dup 2)))
8629 (clobber (reg:CC FLAGS_REG))])]
8630 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8631
8632 (define_insn "*neg<mode>2_1"
8633 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8634 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8635 (clobber (reg:CC FLAGS_REG))]
8636 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8637 "neg{<imodesuffix>}\t%0"
8638 [(set_attr "type" "negnot")
8639 (set_attr "mode" "<MODE>")])
8640
8641 ;; Combine is quite creative about this pattern.
8642 (define_insn "*negsi2_1_zext"
8643 [(set (match_operand:DI 0 "register_operand" "=r")
8644 (lshiftrt:DI
8645 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8646 (const_int 32)))
8647 (const_int 32)))
8648 (clobber (reg:CC FLAGS_REG))]
8649 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8650 "neg{l}\t%k0"
8651 [(set_attr "type" "negnot")
8652 (set_attr "mode" "SI")])
8653
8654 ;; The problem with neg is that it does not perform (compare x 0),
8655 ;; it really performs (compare 0 x), which leaves us with the zero
8656 ;; flag being the only useful item.
8657
8658 (define_insn "*neg<mode>2_cmpz"
8659 [(set (reg:CCZ FLAGS_REG)
8660 (compare:CCZ
8661 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8662 (const_int 0)))
8663 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8664 (neg:SWI (match_dup 1)))]
8665 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8666 "neg{<imodesuffix>}\t%0"
8667 [(set_attr "type" "negnot")
8668 (set_attr "mode" "<MODE>")])
8669
8670 (define_insn "*negsi2_cmpz_zext"
8671 [(set (reg:CCZ FLAGS_REG)
8672 (compare:CCZ
8673 (lshiftrt:DI
8674 (neg:DI (ashift:DI
8675 (match_operand:DI 1 "register_operand" "0")
8676 (const_int 32)))
8677 (const_int 32))
8678 (const_int 0)))
8679 (set (match_operand:DI 0 "register_operand" "=r")
8680 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8681 (const_int 32)))
8682 (const_int 32)))]
8683 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8684 "neg{l}\t%k0"
8685 [(set_attr "type" "negnot")
8686 (set_attr "mode" "SI")])
8687
8688 ;; Changing of sign for FP values is doable using integer unit too.
8689
8690 (define_expand "<code><mode>2"
8691 [(set (match_operand:X87MODEF 0 "register_operand")
8692 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8693 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8694 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8695
8696 (define_insn "*absneg<mode>2_mixed"
8697 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8698 (match_operator:MODEF 3 "absneg_operator"
8699 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8700 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8701 (clobber (reg:CC FLAGS_REG))]
8702 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8703 "#")
8704
8705 (define_insn "*absneg<mode>2_sse"
8706 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8707 (match_operator:MODEF 3 "absneg_operator"
8708 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8709 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8710 (clobber (reg:CC FLAGS_REG))]
8711 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8712 "#")
8713
8714 (define_insn "*absneg<mode>2_i387"
8715 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8716 (match_operator:X87MODEF 3 "absneg_operator"
8717 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8718 (use (match_operand 2))
8719 (clobber (reg:CC FLAGS_REG))]
8720 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8721 "#")
8722
8723 (define_expand "<code>tf2"
8724 [(set (match_operand:TF 0 "register_operand")
8725 (absneg:TF (match_operand:TF 1 "register_operand")))]
8726 "TARGET_SSE"
8727 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8728
8729 (define_insn "*absnegtf2_sse"
8730 [(set (match_operand:TF 0 "register_operand" "=x,x")
8731 (match_operator:TF 3 "absneg_operator"
8732 [(match_operand:TF 1 "register_operand" "0,x")]))
8733 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8734 (clobber (reg:CC FLAGS_REG))]
8735 "TARGET_SSE"
8736 "#")
8737
8738 ;; Splitters for fp abs and neg.
8739
8740 (define_split
8741 [(set (match_operand 0 "fp_register_operand")
8742 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8743 (use (match_operand 2))
8744 (clobber (reg:CC FLAGS_REG))]
8745 "reload_completed"
8746 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8747
8748 (define_split
8749 [(set (match_operand 0 "register_operand")
8750 (match_operator 3 "absneg_operator"
8751 [(match_operand 1 "register_operand")]))
8752 (use (match_operand 2 "nonimmediate_operand"))
8753 (clobber (reg:CC FLAGS_REG))]
8754 "reload_completed && SSE_REG_P (operands[0])"
8755 [(set (match_dup 0) (match_dup 3))]
8756 {
8757 enum machine_mode mode = GET_MODE (operands[0]);
8758 enum machine_mode vmode = GET_MODE (operands[2]);
8759 rtx tmp;
8760
8761 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8762 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8763 if (operands_match_p (operands[0], operands[2]))
8764 {
8765 tmp = operands[1];
8766 operands[1] = operands[2];
8767 operands[2] = tmp;
8768 }
8769 if (GET_CODE (operands[3]) == ABS)
8770 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8771 else
8772 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8773 operands[3] = tmp;
8774 })
8775
8776 (define_split
8777 [(set (match_operand:SF 0 "register_operand")
8778 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8779 (use (match_operand:V4SF 2))
8780 (clobber (reg:CC FLAGS_REG))]
8781 "reload_completed"
8782 [(parallel [(set (match_dup 0) (match_dup 1))
8783 (clobber (reg:CC FLAGS_REG))])]
8784 {
8785 rtx tmp;
8786 operands[0] = gen_lowpart (SImode, operands[0]);
8787 if (GET_CODE (operands[1]) == ABS)
8788 {
8789 tmp = gen_int_mode (0x7fffffff, SImode);
8790 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8791 }
8792 else
8793 {
8794 tmp = gen_int_mode (0x80000000, SImode);
8795 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8796 }
8797 operands[1] = tmp;
8798 })
8799
8800 (define_split
8801 [(set (match_operand:DF 0 "register_operand")
8802 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8803 (use (match_operand 2))
8804 (clobber (reg:CC FLAGS_REG))]
8805 "reload_completed"
8806 [(parallel [(set (match_dup 0) (match_dup 1))
8807 (clobber (reg:CC FLAGS_REG))])]
8808 {
8809 rtx tmp;
8810 if (TARGET_64BIT)
8811 {
8812 tmp = gen_lowpart (DImode, operands[0]);
8813 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8814 operands[0] = tmp;
8815
8816 if (GET_CODE (operands[1]) == ABS)
8817 tmp = const0_rtx;
8818 else
8819 tmp = gen_rtx_NOT (DImode, tmp);
8820 }
8821 else
8822 {
8823 operands[0] = gen_highpart (SImode, operands[0]);
8824 if (GET_CODE (operands[1]) == ABS)
8825 {
8826 tmp = gen_int_mode (0x7fffffff, SImode);
8827 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8828 }
8829 else
8830 {
8831 tmp = gen_int_mode (0x80000000, SImode);
8832 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8833 }
8834 }
8835 operands[1] = tmp;
8836 })
8837
8838 (define_split
8839 [(set (match_operand:XF 0 "register_operand")
8840 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8841 (use (match_operand 2))
8842 (clobber (reg:CC FLAGS_REG))]
8843 "reload_completed"
8844 [(parallel [(set (match_dup 0) (match_dup 1))
8845 (clobber (reg:CC FLAGS_REG))])]
8846 {
8847 rtx tmp;
8848 operands[0] = gen_rtx_REG (SImode,
8849 true_regnum (operands[0])
8850 + (TARGET_64BIT ? 1 : 2));
8851 if (GET_CODE (operands[1]) == ABS)
8852 {
8853 tmp = GEN_INT (0x7fff);
8854 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8855 }
8856 else
8857 {
8858 tmp = GEN_INT (0x8000);
8859 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8860 }
8861 operands[1] = tmp;
8862 })
8863
8864 ;; Conditionalize these after reload. If they match before reload, we
8865 ;; lose the clobber and ability to use integer instructions.
8866
8867 (define_insn "*<code><mode>2_1"
8868 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8869 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8870 "TARGET_80387
8871 && (reload_completed
8872 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8873 "f<absneg_mnemonic>"
8874 [(set_attr "type" "fsgn")
8875 (set_attr "mode" "<MODE>")])
8876
8877 (define_insn "*<code>extendsfdf2"
8878 [(set (match_operand:DF 0 "register_operand" "=f")
8879 (absneg:DF (float_extend:DF
8880 (match_operand:SF 1 "register_operand" "0"))))]
8881 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8882 "f<absneg_mnemonic>"
8883 [(set_attr "type" "fsgn")
8884 (set_attr "mode" "DF")])
8885
8886 (define_insn "*<code>extendsfxf2"
8887 [(set (match_operand:XF 0 "register_operand" "=f")
8888 (absneg:XF (float_extend:XF
8889 (match_operand:SF 1 "register_operand" "0"))))]
8890 "TARGET_80387"
8891 "f<absneg_mnemonic>"
8892 [(set_attr "type" "fsgn")
8893 (set_attr "mode" "XF")])
8894
8895 (define_insn "*<code>extenddfxf2"
8896 [(set (match_operand:XF 0 "register_operand" "=f")
8897 (absneg:XF (float_extend:XF
8898 (match_operand:DF 1 "register_operand" "0"))))]
8899 "TARGET_80387"
8900 "f<absneg_mnemonic>"
8901 [(set_attr "type" "fsgn")
8902 (set_attr "mode" "XF")])
8903
8904 ;; Copysign instructions
8905
8906 (define_mode_iterator CSGNMODE [SF DF TF])
8907 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8908
8909 (define_expand "copysign<mode>3"
8910 [(match_operand:CSGNMODE 0 "register_operand")
8911 (match_operand:CSGNMODE 1 "nonmemory_operand")
8912 (match_operand:CSGNMODE 2 "register_operand")]
8913 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8914 || (TARGET_SSE && (<MODE>mode == TFmode))"
8915 "ix86_expand_copysign (operands); DONE;")
8916
8917 (define_insn_and_split "copysign<mode>3_const"
8918 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8919 (unspec:CSGNMODE
8920 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8921 (match_operand:CSGNMODE 2 "register_operand" "0")
8922 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8923 UNSPEC_COPYSIGN))]
8924 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8925 || (TARGET_SSE && (<MODE>mode == TFmode))"
8926 "#"
8927 "&& reload_completed"
8928 [(const_int 0)]
8929 "ix86_split_copysign_const (operands); DONE;")
8930
8931 (define_insn "copysign<mode>3_var"
8932 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8933 (unspec:CSGNMODE
8934 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8935 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8936 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8937 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8938 UNSPEC_COPYSIGN))
8939 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8940 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8941 || (TARGET_SSE && (<MODE>mode == TFmode))"
8942 "#")
8943
8944 (define_split
8945 [(set (match_operand:CSGNMODE 0 "register_operand")
8946 (unspec:CSGNMODE
8947 [(match_operand:CSGNMODE 2 "register_operand")
8948 (match_operand:CSGNMODE 3 "register_operand")
8949 (match_operand:<CSGNVMODE> 4)
8950 (match_operand:<CSGNVMODE> 5)]
8951 UNSPEC_COPYSIGN))
8952 (clobber (match_scratch:<CSGNVMODE> 1))]
8953 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8954 || (TARGET_SSE && (<MODE>mode == TFmode)))
8955 && reload_completed"
8956 [(const_int 0)]
8957 "ix86_split_copysign_var (operands); DONE;")
8958 \f
8959 ;; One complement instructions
8960
8961 (define_expand "one_cmpl<mode>2"
8962 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8963 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8964 ""
8965 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8966
8967 (define_insn "*one_cmpl<mode>2_1"
8968 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8969 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8970 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8971 "not{<imodesuffix>}\t%0"
8972 [(set_attr "type" "negnot")
8973 (set_attr "mode" "<MODE>")])
8974
8975 ;; %%% Potential partial reg stall on alternative 1. What to do?
8976 (define_insn "*one_cmplqi2_1"
8977 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8978 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8979 "ix86_unary_operator_ok (NOT, QImode, operands)"
8980 "@
8981 not{b}\t%0
8982 not{l}\t%k0"
8983 [(set_attr "type" "negnot")
8984 (set_attr "mode" "QI,SI")])
8985
8986 ;; ??? Currently never generated - xor is used instead.
8987 (define_insn "*one_cmplsi2_1_zext"
8988 [(set (match_operand:DI 0 "register_operand" "=r")
8989 (zero_extend:DI
8990 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8991 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8992 "not{l}\t%k0"
8993 [(set_attr "type" "negnot")
8994 (set_attr "mode" "SI")])
8995
8996 (define_insn "*one_cmpl<mode>2_2"
8997 [(set (reg FLAGS_REG)
8998 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8999 (const_int 0)))
9000 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9001 (not:SWI (match_dup 1)))]
9002 "ix86_match_ccmode (insn, CCNOmode)
9003 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9004 "#"
9005 [(set_attr "type" "alu1")
9006 (set_attr "mode" "<MODE>")])
9007
9008 (define_split
9009 [(set (match_operand 0 "flags_reg_operand")
9010 (match_operator 2 "compare_operator"
9011 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9012 (const_int 0)]))
9013 (set (match_operand:SWI 1 "nonimmediate_operand")
9014 (not:SWI (match_dup 3)))]
9015 "ix86_match_ccmode (insn, CCNOmode)"
9016 [(parallel [(set (match_dup 0)
9017 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9018 (const_int 0)]))
9019 (set (match_dup 1)
9020 (xor:SWI (match_dup 3) (const_int -1)))])])
9021
9022 ;; ??? Currently never generated - xor is used instead.
9023 (define_insn "*one_cmplsi2_2_zext"
9024 [(set (reg FLAGS_REG)
9025 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9026 (const_int 0)))
9027 (set (match_operand:DI 0 "register_operand" "=r")
9028 (zero_extend:DI (not:SI (match_dup 1))))]
9029 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9030 && ix86_unary_operator_ok (NOT, SImode, operands)"
9031 "#"
9032 [(set_attr "type" "alu1")
9033 (set_attr "mode" "SI")])
9034
9035 (define_split
9036 [(set (match_operand 0 "flags_reg_operand")
9037 (match_operator 2 "compare_operator"
9038 [(not:SI (match_operand:SI 3 "register_operand"))
9039 (const_int 0)]))
9040 (set (match_operand:DI 1 "register_operand")
9041 (zero_extend:DI (not:SI (match_dup 3))))]
9042 "ix86_match_ccmode (insn, CCNOmode)"
9043 [(parallel [(set (match_dup 0)
9044 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9045 (const_int 0)]))
9046 (set (match_dup 1)
9047 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9048 \f
9049 ;; Shift instructions
9050
9051 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9052 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9053 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9054 ;; from the assembler input.
9055 ;;
9056 ;; This instruction shifts the target reg/mem as usual, but instead of
9057 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9058 ;; is a left shift double, bits are taken from the high order bits of
9059 ;; reg, else if the insn is a shift right double, bits are taken from the
9060 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9061 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9062 ;;
9063 ;; Since sh[lr]d does not change the `reg' operand, that is done
9064 ;; separately, making all shifts emit pairs of shift double and normal
9065 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9066 ;; support a 63 bit shift, each shift where the count is in a reg expands
9067 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9068 ;;
9069 ;; If the shift count is a constant, we need never emit more than one
9070 ;; shift pair, instead using moves and sign extension for counts greater
9071 ;; than 31.
9072
9073 (define_expand "ashl<mode>3"
9074 [(set (match_operand:SDWIM 0 "<shift_operand>")
9075 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9076 (match_operand:QI 2 "nonmemory_operand")))]
9077 ""
9078 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9079
9080 (define_insn "*ashl<mode>3_doubleword"
9081 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9082 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9083 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9084 (clobber (reg:CC FLAGS_REG))]
9085 ""
9086 "#"
9087 [(set_attr "type" "multi")])
9088
9089 (define_split
9090 [(set (match_operand:DWI 0 "register_operand")
9091 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9092 (match_operand:QI 2 "nonmemory_operand")))
9093 (clobber (reg:CC FLAGS_REG))]
9094 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9095 [(const_int 0)]
9096 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9097
9098 ;; By default we don't ask for a scratch register, because when DWImode
9099 ;; values are manipulated, registers are already at a premium. But if
9100 ;; we have one handy, we won't turn it away.
9101
9102 (define_peephole2
9103 [(match_scratch:DWIH 3 "r")
9104 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9105 (ashift:<DWI>
9106 (match_operand:<DWI> 1 "nonmemory_operand")
9107 (match_operand:QI 2 "nonmemory_operand")))
9108 (clobber (reg:CC FLAGS_REG))])
9109 (match_dup 3)]
9110 "TARGET_CMOVE"
9111 [(const_int 0)]
9112 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9113
9114 (define_insn "x86_64_shld"
9115 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9116 (ior:DI (ashift:DI (match_dup 0)
9117 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9118 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9119 (minus:QI (const_int 64) (match_dup 2)))))
9120 (clobber (reg:CC FLAGS_REG))]
9121 "TARGET_64BIT"
9122 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9123 [(set_attr "type" "ishift")
9124 (set_attr "prefix_0f" "1")
9125 (set_attr "mode" "DI")
9126 (set_attr "athlon_decode" "vector")
9127 (set_attr "amdfam10_decode" "vector")
9128 (set_attr "bdver1_decode" "vector")])
9129
9130 (define_insn "x86_shld"
9131 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9132 (ior:SI (ashift:SI (match_dup 0)
9133 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9134 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9135 (minus:QI (const_int 32) (match_dup 2)))))
9136 (clobber (reg:CC FLAGS_REG))]
9137 ""
9138 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9139 [(set_attr "type" "ishift")
9140 (set_attr "prefix_0f" "1")
9141 (set_attr "mode" "SI")
9142 (set_attr "pent_pair" "np")
9143 (set_attr "athlon_decode" "vector")
9144 (set_attr "amdfam10_decode" "vector")
9145 (set_attr "bdver1_decode" "vector")])
9146
9147 (define_expand "x86_shift<mode>_adj_1"
9148 [(set (reg:CCZ FLAGS_REG)
9149 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9150 (match_dup 4))
9151 (const_int 0)))
9152 (set (match_operand:SWI48 0 "register_operand")
9153 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9154 (match_operand:SWI48 1 "register_operand")
9155 (match_dup 0)))
9156 (set (match_dup 1)
9157 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9158 (match_operand:SWI48 3 "register_operand")
9159 (match_dup 1)))]
9160 "TARGET_CMOVE"
9161 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9162
9163 (define_expand "x86_shift<mode>_adj_2"
9164 [(use (match_operand:SWI48 0 "register_operand"))
9165 (use (match_operand:SWI48 1 "register_operand"))
9166 (use (match_operand:QI 2 "register_operand"))]
9167 ""
9168 {
9169 rtx label = gen_label_rtx ();
9170 rtx tmp;
9171
9172 emit_insn (gen_testqi_ccz_1 (operands[2],
9173 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9174
9175 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9176 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9177 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9178 gen_rtx_LABEL_REF (VOIDmode, label),
9179 pc_rtx);
9180 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9181 JUMP_LABEL (tmp) = label;
9182
9183 emit_move_insn (operands[0], operands[1]);
9184 ix86_expand_clear (operands[1]);
9185
9186 emit_label (label);
9187 LABEL_NUSES (label) = 1;
9188
9189 DONE;
9190 })
9191
9192 ;; Avoid useless masking of count operand.
9193 (define_insn_and_split "*ashl<mode>3_mask"
9194 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9195 (ashift:SWI48
9196 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9197 (subreg:QI
9198 (and:SI
9199 (match_operand:SI 2 "nonimmediate_operand" "c")
9200 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9201 (clobber (reg:CC FLAGS_REG))]
9202 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9203 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9204 == GET_MODE_BITSIZE (<MODE>mode)-1"
9205 "#"
9206 "&& 1"
9207 [(parallel [(set (match_dup 0)
9208 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9209 (clobber (reg:CC FLAGS_REG))])]
9210 {
9211 if (can_create_pseudo_p ())
9212 operands [2] = force_reg (SImode, operands[2]);
9213
9214 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9215 }
9216 [(set_attr "type" "ishift")
9217 (set_attr "mode" "<MODE>")])
9218
9219 (define_insn "*bmi2_ashl<mode>3_1"
9220 [(set (match_operand:SWI48 0 "register_operand" "=r")
9221 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9222 (match_operand:SWI48 2 "register_operand" "r")))]
9223 "TARGET_BMI2"
9224 "shlx\t{%2, %1, %0|%0, %1, %2}"
9225 [(set_attr "type" "ishiftx")
9226 (set_attr "mode" "<MODE>")])
9227
9228 (define_insn "*ashl<mode>3_1"
9229 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9230 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9231 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9232 (clobber (reg:CC FLAGS_REG))]
9233 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9234 {
9235 switch (get_attr_type (insn))
9236 {
9237 case TYPE_LEA:
9238 case TYPE_ISHIFTX:
9239 return "#";
9240
9241 case TYPE_ALU:
9242 gcc_assert (operands[2] == const1_rtx);
9243 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9244 return "add{<imodesuffix>}\t%0, %0";
9245
9246 default:
9247 if (operands[2] == const1_rtx
9248 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9249 return "sal{<imodesuffix>}\t%0";
9250 else
9251 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9252 }
9253 }
9254 [(set_attr "isa" "*,*,bmi2")
9255 (set (attr "type")
9256 (cond [(eq_attr "alternative" "1")
9257 (const_string "lea")
9258 (eq_attr "alternative" "2")
9259 (const_string "ishiftx")
9260 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9261 (match_operand 0 "register_operand"))
9262 (match_operand 2 "const1_operand"))
9263 (const_string "alu")
9264 ]
9265 (const_string "ishift")))
9266 (set (attr "length_immediate")
9267 (if_then_else
9268 (ior (eq_attr "type" "alu")
9269 (and (eq_attr "type" "ishift")
9270 (and (match_operand 2 "const1_operand")
9271 (ior (match_test "TARGET_SHIFT1")
9272 (match_test "optimize_function_for_size_p (cfun)")))))
9273 (const_string "0")
9274 (const_string "*")))
9275 (set_attr "mode" "<MODE>")])
9276
9277 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9278 (define_split
9279 [(set (match_operand:SWI48 0 "register_operand")
9280 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9281 (match_operand:QI 2 "register_operand")))
9282 (clobber (reg:CC FLAGS_REG))]
9283 "TARGET_BMI2 && reload_completed"
9284 [(set (match_dup 0)
9285 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9286 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9287
9288 (define_insn "*bmi2_ashlsi3_1_zext"
9289 [(set (match_operand:DI 0 "register_operand" "=r")
9290 (zero_extend:DI
9291 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9292 (match_operand:SI 2 "register_operand" "r"))))]
9293 "TARGET_64BIT && TARGET_BMI2"
9294 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9295 [(set_attr "type" "ishiftx")
9296 (set_attr "mode" "SI")])
9297
9298 (define_insn "*ashlsi3_1_zext"
9299 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9300 (zero_extend:DI
9301 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9302 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9303 (clobber (reg:CC FLAGS_REG))]
9304 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9305 {
9306 switch (get_attr_type (insn))
9307 {
9308 case TYPE_LEA:
9309 case TYPE_ISHIFTX:
9310 return "#";
9311
9312 case TYPE_ALU:
9313 gcc_assert (operands[2] == const1_rtx);
9314 return "add{l}\t%k0, %k0";
9315
9316 default:
9317 if (operands[2] == const1_rtx
9318 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9319 return "sal{l}\t%k0";
9320 else
9321 return "sal{l}\t{%2, %k0|%k0, %2}";
9322 }
9323 }
9324 [(set_attr "isa" "*,*,bmi2")
9325 (set (attr "type")
9326 (cond [(eq_attr "alternative" "1")
9327 (const_string "lea")
9328 (eq_attr "alternative" "2")
9329 (const_string "ishiftx")
9330 (and (match_test "TARGET_DOUBLE_WITH_ADD")
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" "SI")])
9345
9346 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9347 (define_split
9348 [(set (match_operand:DI 0 "register_operand")
9349 (zero_extend:DI
9350 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9351 (match_operand:QI 2 "register_operand"))))
9352 (clobber (reg:CC FLAGS_REG))]
9353 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9354 [(set (match_dup 0)
9355 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9356 "operands[2] = gen_lowpart (SImode, operands[2]);")
9357
9358 (define_insn "*ashlhi3_1"
9359 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9360 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9361 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9362 (clobber (reg:CC FLAGS_REG))]
9363 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9364 {
9365 switch (get_attr_type (insn))
9366 {
9367 case TYPE_LEA:
9368 return "#";
9369
9370 case TYPE_ALU:
9371 gcc_assert (operands[2] == const1_rtx);
9372 return "add{w}\t%0, %0";
9373
9374 default:
9375 if (operands[2] == const1_rtx
9376 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9377 return "sal{w}\t%0";
9378 else
9379 return "sal{w}\t{%2, %0|%0, %2}";
9380 }
9381 }
9382 [(set (attr "type")
9383 (cond [(eq_attr "alternative" "1")
9384 (const_string "lea")
9385 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9386 (match_operand 0 "register_operand"))
9387 (match_operand 2 "const1_operand"))
9388 (const_string "alu")
9389 ]
9390 (const_string "ishift")))
9391 (set (attr "length_immediate")
9392 (if_then_else
9393 (ior (eq_attr "type" "alu")
9394 (and (eq_attr "type" "ishift")
9395 (and (match_operand 2 "const1_operand")
9396 (ior (match_test "TARGET_SHIFT1")
9397 (match_test "optimize_function_for_size_p (cfun)")))))
9398 (const_string "0")
9399 (const_string "*")))
9400 (set_attr "mode" "HI,SI")])
9401
9402 ;; %%% Potential partial reg stall on alternative 1. What to do?
9403 (define_insn "*ashlqi3_1"
9404 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9405 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9406 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9407 (clobber (reg:CC FLAGS_REG))]
9408 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9409 {
9410 switch (get_attr_type (insn))
9411 {
9412 case TYPE_LEA:
9413 return "#";
9414
9415 case TYPE_ALU:
9416 gcc_assert (operands[2] == const1_rtx);
9417 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9418 return "add{l}\t%k0, %k0";
9419 else
9420 return "add{b}\t%0, %0";
9421
9422 default:
9423 if (operands[2] == const1_rtx
9424 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9425 {
9426 if (get_attr_mode (insn) == MODE_SI)
9427 return "sal{l}\t%k0";
9428 else
9429 return "sal{b}\t%0";
9430 }
9431 else
9432 {
9433 if (get_attr_mode (insn) == MODE_SI)
9434 return "sal{l}\t{%2, %k0|%k0, %2}";
9435 else
9436 return "sal{b}\t{%2, %0|%0, %2}";
9437 }
9438 }
9439 }
9440 [(set (attr "type")
9441 (cond [(eq_attr "alternative" "2")
9442 (const_string "lea")
9443 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9444 (match_operand 0 "register_operand"))
9445 (match_operand 2 "const1_operand"))
9446 (const_string "alu")
9447 ]
9448 (const_string "ishift")))
9449 (set (attr "length_immediate")
9450 (if_then_else
9451 (ior (eq_attr "type" "alu")
9452 (and (eq_attr "type" "ishift")
9453 (and (match_operand 2 "const1_operand")
9454 (ior (match_test "TARGET_SHIFT1")
9455 (match_test "optimize_function_for_size_p (cfun)")))))
9456 (const_string "0")
9457 (const_string "*")))
9458 (set_attr "mode" "QI,SI,SI")])
9459
9460 (define_insn "*ashlqi3_1_slp"
9461 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9462 (ashift:QI (match_dup 0)
9463 (match_operand:QI 1 "nonmemory_operand" "cI")))
9464 (clobber (reg:CC FLAGS_REG))]
9465 "(optimize_function_for_size_p (cfun)
9466 || !TARGET_PARTIAL_FLAG_REG_STALL
9467 || (operands[1] == const1_rtx
9468 && (TARGET_SHIFT1
9469 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9470 {
9471 switch (get_attr_type (insn))
9472 {
9473 case TYPE_ALU:
9474 gcc_assert (operands[1] == const1_rtx);
9475 return "add{b}\t%0, %0";
9476
9477 default:
9478 if (operands[1] == const1_rtx
9479 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9480 return "sal{b}\t%0";
9481 else
9482 return "sal{b}\t{%1, %0|%0, %1}";
9483 }
9484 }
9485 [(set (attr "type")
9486 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9487 (match_operand 0 "register_operand"))
9488 (match_operand 1 "const1_operand"))
9489 (const_string "alu")
9490 ]
9491 (const_string "ishift1")))
9492 (set (attr "length_immediate")
9493 (if_then_else
9494 (ior (eq_attr "type" "alu")
9495 (and (eq_attr "type" "ishift1")
9496 (and (match_operand 1 "const1_operand")
9497 (ior (match_test "TARGET_SHIFT1")
9498 (match_test "optimize_function_for_size_p (cfun)")))))
9499 (const_string "0")
9500 (const_string "*")))
9501 (set_attr "mode" "QI")])
9502
9503 ;; Convert ashift to the lea pattern to avoid flags dependency.
9504 (define_split
9505 [(set (match_operand 0 "register_operand")
9506 (ashift (match_operand 1 "index_register_operand")
9507 (match_operand:QI 2 "const_int_operand")))
9508 (clobber (reg:CC FLAGS_REG))]
9509 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9510 && reload_completed
9511 && true_regnum (operands[0]) != true_regnum (operands[1])"
9512 [(const_int 0)]
9513 {
9514 enum machine_mode mode = GET_MODE (operands[0]);
9515 rtx pat;
9516
9517 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9518 {
9519 mode = SImode;
9520 operands[0] = gen_lowpart (mode, operands[0]);
9521 operands[1] = gen_lowpart (mode, operands[1]);
9522 }
9523
9524 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9525
9526 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9527
9528 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9529 DONE;
9530 })
9531
9532 ;; Convert ashift to the lea pattern to avoid flags dependency.
9533 (define_split
9534 [(set (match_operand:DI 0 "register_operand")
9535 (zero_extend:DI
9536 (ashift:SI (match_operand:SI 1 "index_register_operand")
9537 (match_operand:QI 2 "const_int_operand"))))
9538 (clobber (reg:CC FLAGS_REG))]
9539 "TARGET_64BIT && reload_completed
9540 && true_regnum (operands[0]) != true_regnum (operands[1])"
9541 [(set (match_dup 0)
9542 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9543 {
9544 operands[1] = gen_lowpart (DImode, operands[1]);
9545 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9546 })
9547
9548 ;; This pattern can't accept a variable shift count, since shifts by
9549 ;; zero don't affect the flags. We assume that shifts by constant
9550 ;; zero are optimized away.
9551 (define_insn "*ashl<mode>3_cmp"
9552 [(set (reg FLAGS_REG)
9553 (compare
9554 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9555 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9556 (const_int 0)))
9557 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9558 (ashift:SWI (match_dup 1) (match_dup 2)))]
9559 "(optimize_function_for_size_p (cfun)
9560 || !TARGET_PARTIAL_FLAG_REG_STALL
9561 || (operands[2] == const1_rtx
9562 && (TARGET_SHIFT1
9563 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9564 && ix86_match_ccmode (insn, CCGOCmode)
9565 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9566 {
9567 switch (get_attr_type (insn))
9568 {
9569 case TYPE_ALU:
9570 gcc_assert (operands[2] == const1_rtx);
9571 return "add{<imodesuffix>}\t%0, %0";
9572
9573 default:
9574 if (operands[2] == const1_rtx
9575 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9576 return "sal{<imodesuffix>}\t%0";
9577 else
9578 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9579 }
9580 }
9581 [(set (attr "type")
9582 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9583 (match_operand 0 "register_operand"))
9584 (match_operand 2 "const1_operand"))
9585 (const_string "alu")
9586 ]
9587 (const_string "ishift")))
9588 (set (attr "length_immediate")
9589 (if_then_else
9590 (ior (eq_attr "type" "alu")
9591 (and (eq_attr "type" "ishift")
9592 (and (match_operand 2 "const1_operand")
9593 (ior (match_test "TARGET_SHIFT1")
9594 (match_test "optimize_function_for_size_p (cfun)")))))
9595 (const_string "0")
9596 (const_string "*")))
9597 (set_attr "mode" "<MODE>")])
9598
9599 (define_insn "*ashlsi3_cmp_zext"
9600 [(set (reg FLAGS_REG)
9601 (compare
9602 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9603 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9604 (const_int 0)))
9605 (set (match_operand:DI 0 "register_operand" "=r")
9606 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9607 "TARGET_64BIT
9608 && (optimize_function_for_size_p (cfun)
9609 || !TARGET_PARTIAL_FLAG_REG_STALL
9610 || (operands[2] == const1_rtx
9611 && (TARGET_SHIFT1
9612 || TARGET_DOUBLE_WITH_ADD)))
9613 && ix86_match_ccmode (insn, CCGOCmode)
9614 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9615 {
9616 switch (get_attr_type (insn))
9617 {
9618 case TYPE_ALU:
9619 gcc_assert (operands[2] == const1_rtx);
9620 return "add{l}\t%k0, %k0";
9621
9622 default:
9623 if (operands[2] == const1_rtx
9624 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9625 return "sal{l}\t%k0";
9626 else
9627 return "sal{l}\t{%2, %k0|%k0, %2}";
9628 }
9629 }
9630 [(set (attr "type")
9631 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9632 (match_operand 2 "const1_operand"))
9633 (const_string "alu")
9634 ]
9635 (const_string "ishift")))
9636 (set (attr "length_immediate")
9637 (if_then_else
9638 (ior (eq_attr "type" "alu")
9639 (and (eq_attr "type" "ishift")
9640 (and (match_operand 2 "const1_operand")
9641 (ior (match_test "TARGET_SHIFT1")
9642 (match_test "optimize_function_for_size_p (cfun)")))))
9643 (const_string "0")
9644 (const_string "*")))
9645 (set_attr "mode" "SI")])
9646
9647 (define_insn "*ashl<mode>3_cconly"
9648 [(set (reg FLAGS_REG)
9649 (compare
9650 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9651 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9652 (const_int 0)))
9653 (clobber (match_scratch:SWI 0 "=<r>"))]
9654 "(optimize_function_for_size_p (cfun)
9655 || !TARGET_PARTIAL_FLAG_REG_STALL
9656 || (operands[2] == const1_rtx
9657 && (TARGET_SHIFT1
9658 || TARGET_DOUBLE_WITH_ADD)))
9659 && ix86_match_ccmode (insn, CCGOCmode)"
9660 {
9661 switch (get_attr_type (insn))
9662 {
9663 case TYPE_ALU:
9664 gcc_assert (operands[2] == const1_rtx);
9665 return "add{<imodesuffix>}\t%0, %0";
9666
9667 default:
9668 if (operands[2] == const1_rtx
9669 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9670 return "sal{<imodesuffix>}\t%0";
9671 else
9672 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9673 }
9674 }
9675 [(set (attr "type")
9676 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9677 (match_operand 0 "register_operand"))
9678 (match_operand 2 "const1_operand"))
9679 (const_string "alu")
9680 ]
9681 (const_string "ishift")))
9682 (set (attr "length_immediate")
9683 (if_then_else
9684 (ior (eq_attr "type" "alu")
9685 (and (eq_attr "type" "ishift")
9686 (and (match_operand 2 "const1_operand")
9687 (ior (match_test "TARGET_SHIFT1")
9688 (match_test "optimize_function_for_size_p (cfun)")))))
9689 (const_string "0")
9690 (const_string "*")))
9691 (set_attr "mode" "<MODE>")])
9692
9693 ;; See comment above `ashl<mode>3' about how this works.
9694
9695 (define_expand "<shift_insn><mode>3"
9696 [(set (match_operand:SDWIM 0 "<shift_operand>")
9697 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9698 (match_operand:QI 2 "nonmemory_operand")))]
9699 ""
9700 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9701
9702 ;; Avoid useless masking of count operand.
9703 (define_insn_and_split "*<shift_insn><mode>3_mask"
9704 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9705 (any_shiftrt:SWI48
9706 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9707 (subreg:QI
9708 (and:SI
9709 (match_operand:SI 2 "nonimmediate_operand" "c")
9710 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9711 (clobber (reg:CC FLAGS_REG))]
9712 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9713 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9714 == GET_MODE_BITSIZE (<MODE>mode)-1"
9715 "#"
9716 "&& 1"
9717 [(parallel [(set (match_dup 0)
9718 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9719 (clobber (reg:CC FLAGS_REG))])]
9720 {
9721 if (can_create_pseudo_p ())
9722 operands [2] = force_reg (SImode, operands[2]);
9723
9724 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9725 }
9726 [(set_attr "type" "ishift")
9727 (set_attr "mode" "<MODE>")])
9728
9729 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9730 [(set (match_operand:DWI 0 "register_operand" "=r")
9731 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9732 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9733 (clobber (reg:CC FLAGS_REG))]
9734 ""
9735 "#"
9736 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9737 [(const_int 0)]
9738 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9739 [(set_attr "type" "multi")])
9740
9741 ;; By default we don't ask for a scratch register, because when DWImode
9742 ;; values are manipulated, registers are already at a premium. But if
9743 ;; we have one handy, we won't turn it away.
9744
9745 (define_peephole2
9746 [(match_scratch:DWIH 3 "r")
9747 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9748 (any_shiftrt:<DWI>
9749 (match_operand:<DWI> 1 "register_operand")
9750 (match_operand:QI 2 "nonmemory_operand")))
9751 (clobber (reg:CC FLAGS_REG))])
9752 (match_dup 3)]
9753 "TARGET_CMOVE"
9754 [(const_int 0)]
9755 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9756
9757 (define_insn "x86_64_shrd"
9758 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9759 (ior:DI (ashiftrt:DI (match_dup 0)
9760 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9761 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9762 (minus:QI (const_int 64) (match_dup 2)))))
9763 (clobber (reg:CC FLAGS_REG))]
9764 "TARGET_64BIT"
9765 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9766 [(set_attr "type" "ishift")
9767 (set_attr "prefix_0f" "1")
9768 (set_attr "mode" "DI")
9769 (set_attr "athlon_decode" "vector")
9770 (set_attr "amdfam10_decode" "vector")
9771 (set_attr "bdver1_decode" "vector")])
9772
9773 (define_insn "x86_shrd"
9774 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9775 (ior:SI (ashiftrt:SI (match_dup 0)
9776 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9777 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9778 (minus:QI (const_int 32) (match_dup 2)))))
9779 (clobber (reg:CC FLAGS_REG))]
9780 ""
9781 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9782 [(set_attr "type" "ishift")
9783 (set_attr "prefix_0f" "1")
9784 (set_attr "mode" "SI")
9785 (set_attr "pent_pair" "np")
9786 (set_attr "athlon_decode" "vector")
9787 (set_attr "amdfam10_decode" "vector")
9788 (set_attr "bdver1_decode" "vector")])
9789
9790 (define_insn "ashrdi3_cvt"
9791 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9792 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9793 (match_operand:QI 2 "const_int_operand")))
9794 (clobber (reg:CC FLAGS_REG))]
9795 "TARGET_64BIT && INTVAL (operands[2]) == 63
9796 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9797 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9798 "@
9799 {cqto|cqo}
9800 sar{q}\t{%2, %0|%0, %2}"
9801 [(set_attr "type" "imovx,ishift")
9802 (set_attr "prefix_0f" "0,*")
9803 (set_attr "length_immediate" "0,*")
9804 (set_attr "modrm" "0,1")
9805 (set_attr "mode" "DI")])
9806
9807 (define_insn "ashrsi3_cvt"
9808 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9809 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9810 (match_operand:QI 2 "const_int_operand")))
9811 (clobber (reg:CC FLAGS_REG))]
9812 "INTVAL (operands[2]) == 31
9813 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9814 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9815 "@
9816 {cltd|cdq}
9817 sar{l}\t{%2, %0|%0, %2}"
9818 [(set_attr "type" "imovx,ishift")
9819 (set_attr "prefix_0f" "0,*")
9820 (set_attr "length_immediate" "0,*")
9821 (set_attr "modrm" "0,1")
9822 (set_attr "mode" "SI")])
9823
9824 (define_insn "*ashrsi3_cvt_zext"
9825 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9826 (zero_extend:DI
9827 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9828 (match_operand:QI 2 "const_int_operand"))))
9829 (clobber (reg:CC FLAGS_REG))]
9830 "TARGET_64BIT && INTVAL (operands[2]) == 31
9831 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9832 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9833 "@
9834 {cltd|cdq}
9835 sar{l}\t{%2, %k0|%k0, %2}"
9836 [(set_attr "type" "imovx,ishift")
9837 (set_attr "prefix_0f" "0,*")
9838 (set_attr "length_immediate" "0,*")
9839 (set_attr "modrm" "0,1")
9840 (set_attr "mode" "SI")])
9841
9842 (define_expand "x86_shift<mode>_adj_3"
9843 [(use (match_operand:SWI48 0 "register_operand"))
9844 (use (match_operand:SWI48 1 "register_operand"))
9845 (use (match_operand:QI 2 "register_operand"))]
9846 ""
9847 {
9848 rtx label = gen_label_rtx ();
9849 rtx tmp;
9850
9851 emit_insn (gen_testqi_ccz_1 (operands[2],
9852 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9853
9854 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9855 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9856 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9857 gen_rtx_LABEL_REF (VOIDmode, label),
9858 pc_rtx);
9859 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9860 JUMP_LABEL (tmp) = label;
9861
9862 emit_move_insn (operands[0], operands[1]);
9863 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9864 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9865 emit_label (label);
9866 LABEL_NUSES (label) = 1;
9867
9868 DONE;
9869 })
9870
9871 (define_insn "*bmi2_<shift_insn><mode>3_1"
9872 [(set (match_operand:SWI48 0 "register_operand" "=r")
9873 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9874 (match_operand:SWI48 2 "register_operand" "r")))]
9875 "TARGET_BMI2"
9876 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9877 [(set_attr "type" "ishiftx")
9878 (set_attr "mode" "<MODE>")])
9879
9880 (define_insn "*<shift_insn><mode>3_1"
9881 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9882 (any_shiftrt:SWI48
9883 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9884 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9885 (clobber (reg:CC FLAGS_REG))]
9886 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9887 {
9888 switch (get_attr_type (insn))
9889 {
9890 case TYPE_ISHIFTX:
9891 return "#";
9892
9893 default:
9894 if (operands[2] == const1_rtx
9895 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9896 return "<shift>{<imodesuffix>}\t%0";
9897 else
9898 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9899 }
9900 }
9901 [(set_attr "isa" "*,bmi2")
9902 (set_attr "type" "ishift,ishiftx")
9903 (set (attr "length_immediate")
9904 (if_then_else
9905 (and (match_operand 2 "const1_operand")
9906 (ior (match_test "TARGET_SHIFT1")
9907 (match_test "optimize_function_for_size_p (cfun)")))
9908 (const_string "0")
9909 (const_string "*")))
9910 (set_attr "mode" "<MODE>")])
9911
9912 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9913 (define_split
9914 [(set (match_operand:SWI48 0 "register_operand")
9915 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9916 (match_operand:QI 2 "register_operand")))
9917 (clobber (reg:CC FLAGS_REG))]
9918 "TARGET_BMI2 && reload_completed"
9919 [(set (match_dup 0)
9920 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9921 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9922
9923 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9924 [(set (match_operand:DI 0 "register_operand" "=r")
9925 (zero_extend:DI
9926 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9927 (match_operand:SI 2 "register_operand" "r"))))]
9928 "TARGET_64BIT && TARGET_BMI2"
9929 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9930 [(set_attr "type" "ishiftx")
9931 (set_attr "mode" "SI")])
9932
9933 (define_insn "*<shift_insn>si3_1_zext"
9934 [(set (match_operand:DI 0 "register_operand" "=r,r")
9935 (zero_extend:DI
9936 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9937 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9938 (clobber (reg:CC FLAGS_REG))]
9939 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9940 {
9941 switch (get_attr_type (insn))
9942 {
9943 case TYPE_ISHIFTX:
9944 return "#";
9945
9946 default:
9947 if (operands[2] == const1_rtx
9948 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9949 return "<shift>{l}\t%k0";
9950 else
9951 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9952 }
9953 }
9954 [(set_attr "isa" "*,bmi2")
9955 (set_attr "type" "ishift,ishiftx")
9956 (set (attr "length_immediate")
9957 (if_then_else
9958 (and (match_operand 2 "const1_operand")
9959 (ior (match_test "TARGET_SHIFT1")
9960 (match_test "optimize_function_for_size_p (cfun)")))
9961 (const_string "0")
9962 (const_string "*")))
9963 (set_attr "mode" "SI")])
9964
9965 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9966 (define_split
9967 [(set (match_operand:DI 0 "register_operand")
9968 (zero_extend:DI
9969 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9970 (match_operand:QI 2 "register_operand"))))
9971 (clobber (reg:CC FLAGS_REG))]
9972 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9973 [(set (match_dup 0)
9974 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9975 "operands[2] = gen_lowpart (SImode, operands[2]);")
9976
9977 (define_insn "*<shift_insn><mode>3_1"
9978 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9979 (any_shiftrt:SWI12
9980 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9981 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9982 (clobber (reg:CC FLAGS_REG))]
9983 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9984 {
9985 if (operands[2] == const1_rtx
9986 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9987 return "<shift>{<imodesuffix>}\t%0";
9988 else
9989 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9990 }
9991 [(set_attr "type" "ishift")
9992 (set (attr "length_immediate")
9993 (if_then_else
9994 (and (match_operand 2 "const1_operand")
9995 (ior (match_test "TARGET_SHIFT1")
9996 (match_test "optimize_function_for_size_p (cfun)")))
9997 (const_string "0")
9998 (const_string "*")))
9999 (set_attr "mode" "<MODE>")])
10000
10001 (define_insn "*<shift_insn>qi3_1_slp"
10002 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10003 (any_shiftrt:QI (match_dup 0)
10004 (match_operand:QI 1 "nonmemory_operand" "cI")))
10005 (clobber (reg:CC FLAGS_REG))]
10006 "(optimize_function_for_size_p (cfun)
10007 || !TARGET_PARTIAL_REG_STALL
10008 || (operands[1] == const1_rtx
10009 && TARGET_SHIFT1))"
10010 {
10011 if (operands[1] == const1_rtx
10012 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10013 return "<shift>{b}\t%0";
10014 else
10015 return "<shift>{b}\t{%1, %0|%0, %1}";
10016 }
10017 [(set_attr "type" "ishift1")
10018 (set (attr "length_immediate")
10019 (if_then_else
10020 (and (match_operand 1 "const1_operand")
10021 (ior (match_test "TARGET_SHIFT1")
10022 (match_test "optimize_function_for_size_p (cfun)")))
10023 (const_string "0")
10024 (const_string "*")))
10025 (set_attr "mode" "QI")])
10026
10027 ;; This pattern can't accept a variable shift count, since shifts by
10028 ;; zero don't affect the flags. We assume that shifts by constant
10029 ;; zero are optimized away.
10030 (define_insn "*<shift_insn><mode>3_cmp"
10031 [(set (reg FLAGS_REG)
10032 (compare
10033 (any_shiftrt:SWI
10034 (match_operand:SWI 1 "nonimmediate_operand" "0")
10035 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10036 (const_int 0)))
10037 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10038 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10039 "(optimize_function_for_size_p (cfun)
10040 || !TARGET_PARTIAL_FLAG_REG_STALL
10041 || (operands[2] == const1_rtx
10042 && TARGET_SHIFT1))
10043 && ix86_match_ccmode (insn, CCGOCmode)
10044 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10045 {
10046 if (operands[2] == const1_rtx
10047 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10048 return "<shift>{<imodesuffix>}\t%0";
10049 else
10050 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10051 }
10052 [(set_attr "type" "ishift")
10053 (set (attr "length_immediate")
10054 (if_then_else
10055 (and (match_operand 2 "const1_operand")
10056 (ior (match_test "TARGET_SHIFT1")
10057 (match_test "optimize_function_for_size_p (cfun)")))
10058 (const_string "0")
10059 (const_string "*")))
10060 (set_attr "mode" "<MODE>")])
10061
10062 (define_insn "*<shift_insn>si3_cmp_zext"
10063 [(set (reg FLAGS_REG)
10064 (compare
10065 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10066 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10067 (const_int 0)))
10068 (set (match_operand:DI 0 "register_operand" "=r")
10069 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10070 "TARGET_64BIT
10071 && (optimize_function_for_size_p (cfun)
10072 || !TARGET_PARTIAL_FLAG_REG_STALL
10073 || (operands[2] == const1_rtx
10074 && TARGET_SHIFT1))
10075 && ix86_match_ccmode (insn, CCGOCmode)
10076 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10077 {
10078 if (operands[2] == const1_rtx
10079 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10080 return "<shift>{l}\t%k0";
10081 else
10082 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10083 }
10084 [(set_attr "type" "ishift")
10085 (set (attr "length_immediate")
10086 (if_then_else
10087 (and (match_operand 2 "const1_operand")
10088 (ior (match_test "TARGET_SHIFT1")
10089 (match_test "optimize_function_for_size_p (cfun)")))
10090 (const_string "0")
10091 (const_string "*")))
10092 (set_attr "mode" "SI")])
10093
10094 (define_insn "*<shift_insn><mode>3_cconly"
10095 [(set (reg FLAGS_REG)
10096 (compare
10097 (any_shiftrt:SWI
10098 (match_operand:SWI 1 "register_operand" "0")
10099 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10100 (const_int 0)))
10101 (clobber (match_scratch:SWI 0 "=<r>"))]
10102 "(optimize_function_for_size_p (cfun)
10103 || !TARGET_PARTIAL_FLAG_REG_STALL
10104 || (operands[2] == const1_rtx
10105 && TARGET_SHIFT1))
10106 && ix86_match_ccmode (insn, CCGOCmode)"
10107 {
10108 if (operands[2] == const1_rtx
10109 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10110 return "<shift>{<imodesuffix>}\t%0";
10111 else
10112 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10113 }
10114 [(set_attr "type" "ishift")
10115 (set (attr "length_immediate")
10116 (if_then_else
10117 (and (match_operand 2 "const1_operand")
10118 (ior (match_test "TARGET_SHIFT1")
10119 (match_test "optimize_function_for_size_p (cfun)")))
10120 (const_string "0")
10121 (const_string "*")))
10122 (set_attr "mode" "<MODE>")])
10123 \f
10124 ;; Rotate instructions
10125
10126 (define_expand "<rotate_insn>ti3"
10127 [(set (match_operand:TI 0 "register_operand")
10128 (any_rotate:TI (match_operand:TI 1 "register_operand")
10129 (match_operand:QI 2 "nonmemory_operand")))]
10130 "TARGET_64BIT"
10131 {
10132 if (const_1_to_63_operand (operands[2], VOIDmode))
10133 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10134 (operands[0], operands[1], operands[2]));
10135 else
10136 FAIL;
10137
10138 DONE;
10139 })
10140
10141 (define_expand "<rotate_insn>di3"
10142 [(set (match_operand:DI 0 "shiftdi_operand")
10143 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10144 (match_operand:QI 2 "nonmemory_operand")))]
10145 ""
10146 {
10147 if (TARGET_64BIT)
10148 ix86_expand_binary_operator (<CODE>, DImode, operands);
10149 else if (const_1_to_31_operand (operands[2], VOIDmode))
10150 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10151 (operands[0], operands[1], operands[2]));
10152 else
10153 FAIL;
10154
10155 DONE;
10156 })
10157
10158 (define_expand "<rotate_insn><mode>3"
10159 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10160 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10161 (match_operand:QI 2 "nonmemory_operand")))]
10162 ""
10163 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10164
10165 ;; Avoid useless masking of count operand.
10166 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10167 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10168 (any_rotate:SWI48
10169 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10170 (subreg:QI
10171 (and:SI
10172 (match_operand:SI 2 "nonimmediate_operand" "c")
10173 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10174 (clobber (reg:CC FLAGS_REG))]
10175 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10176 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10177 == GET_MODE_BITSIZE (<MODE>mode)-1"
10178 "#"
10179 "&& 1"
10180 [(parallel [(set (match_dup 0)
10181 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10182 (clobber (reg:CC FLAGS_REG))])]
10183 {
10184 if (can_create_pseudo_p ())
10185 operands [2] = force_reg (SImode, operands[2]);
10186
10187 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10188 }
10189 [(set_attr "type" "rotate")
10190 (set_attr "mode" "<MODE>")])
10191
10192 ;; Implement rotation using two double-precision
10193 ;; shift instructions and a scratch register.
10194
10195 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10196 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10197 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10198 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10199 (clobber (reg:CC FLAGS_REG))
10200 (clobber (match_scratch:DWIH 3 "=&r"))]
10201 ""
10202 "#"
10203 "reload_completed"
10204 [(set (match_dup 3) (match_dup 4))
10205 (parallel
10206 [(set (match_dup 4)
10207 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10208 (lshiftrt:DWIH (match_dup 5)
10209 (minus:QI (match_dup 6) (match_dup 2)))))
10210 (clobber (reg:CC FLAGS_REG))])
10211 (parallel
10212 [(set (match_dup 5)
10213 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10214 (lshiftrt:DWIH (match_dup 3)
10215 (minus:QI (match_dup 6) (match_dup 2)))))
10216 (clobber (reg:CC FLAGS_REG))])]
10217 {
10218 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10219
10220 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10221 })
10222
10223 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10224 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10225 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10226 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10227 (clobber (reg:CC FLAGS_REG))
10228 (clobber (match_scratch:DWIH 3 "=&r"))]
10229 ""
10230 "#"
10231 "reload_completed"
10232 [(set (match_dup 3) (match_dup 4))
10233 (parallel
10234 [(set (match_dup 4)
10235 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10236 (ashift:DWIH (match_dup 5)
10237 (minus:QI (match_dup 6) (match_dup 2)))))
10238 (clobber (reg:CC FLAGS_REG))])
10239 (parallel
10240 [(set (match_dup 5)
10241 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10242 (ashift:DWIH (match_dup 3)
10243 (minus:QI (match_dup 6) (match_dup 2)))))
10244 (clobber (reg:CC FLAGS_REG))])]
10245 {
10246 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10247
10248 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10249 })
10250
10251 (define_insn "*bmi2_rorx<mode>3_1"
10252 [(set (match_operand:SWI48 0 "register_operand" "=r")
10253 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10254 (match_operand:QI 2 "immediate_operand" "<S>")))]
10255 "TARGET_BMI2"
10256 "rorx\t{%2, %1, %0|%0, %1, %2}"
10257 [(set_attr "type" "rotatex")
10258 (set_attr "mode" "<MODE>")])
10259
10260 (define_insn "*<rotate_insn><mode>3_1"
10261 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10262 (any_rotate:SWI48
10263 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10264 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10265 (clobber (reg:CC FLAGS_REG))]
10266 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10267 {
10268 switch (get_attr_type (insn))
10269 {
10270 case TYPE_ROTATEX:
10271 return "#";
10272
10273 default:
10274 if (operands[2] == const1_rtx
10275 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10276 return "<rotate>{<imodesuffix>}\t%0";
10277 else
10278 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10279 }
10280 }
10281 [(set_attr "isa" "*,bmi2")
10282 (set_attr "type" "rotate,rotatex")
10283 (set (attr "length_immediate")
10284 (if_then_else
10285 (and (eq_attr "type" "rotate")
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 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10294 (define_split
10295 [(set (match_operand:SWI48 0 "register_operand")
10296 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10297 (match_operand:QI 2 "immediate_operand")))
10298 (clobber (reg:CC FLAGS_REG))]
10299 "TARGET_BMI2 && reload_completed"
10300 [(set (match_dup 0)
10301 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10302 {
10303 operands[2]
10304 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10305 })
10306
10307 (define_split
10308 [(set (match_operand:SWI48 0 "register_operand")
10309 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10310 (match_operand:QI 2 "immediate_operand")))
10311 (clobber (reg:CC FLAGS_REG))]
10312 "TARGET_BMI2 && reload_completed"
10313 [(set (match_dup 0)
10314 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10315
10316 (define_insn "*bmi2_rorxsi3_1_zext"
10317 [(set (match_operand:DI 0 "register_operand" "=r")
10318 (zero_extend:DI
10319 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10320 (match_operand:QI 2 "immediate_operand" "I"))))]
10321 "TARGET_64BIT && TARGET_BMI2"
10322 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10323 [(set_attr "type" "rotatex")
10324 (set_attr "mode" "SI")])
10325
10326 (define_insn "*<rotate_insn>si3_1_zext"
10327 [(set (match_operand:DI 0 "register_operand" "=r,r")
10328 (zero_extend:DI
10329 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10330 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10331 (clobber (reg:CC FLAGS_REG))]
10332 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10333 {
10334 switch (get_attr_type (insn))
10335 {
10336 case TYPE_ROTATEX:
10337 return "#";
10338
10339 default:
10340 if (operands[2] == const1_rtx
10341 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10342 return "<rotate>{l}\t%k0";
10343 else
10344 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10345 }
10346 }
10347 [(set_attr "isa" "*,bmi2")
10348 (set_attr "type" "rotate,rotatex")
10349 (set (attr "length_immediate")
10350 (if_then_else
10351 (and (eq_attr "type" "rotate")
10352 (and (match_operand 2 "const1_operand")
10353 (ior (match_test "TARGET_SHIFT1")
10354 (match_test "optimize_function_for_size_p (cfun)"))))
10355 (const_string "0")
10356 (const_string "*")))
10357 (set_attr "mode" "SI")])
10358
10359 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10360 (define_split
10361 [(set (match_operand:DI 0 "register_operand")
10362 (zero_extend:DI
10363 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10364 (match_operand:QI 2 "immediate_operand"))))
10365 (clobber (reg:CC FLAGS_REG))]
10366 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10367 [(set (match_dup 0)
10368 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10369 {
10370 operands[2]
10371 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10372 })
10373
10374 (define_split
10375 [(set (match_operand:DI 0 "register_operand")
10376 (zero_extend:DI
10377 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10378 (match_operand:QI 2 "immediate_operand"))))
10379 (clobber (reg:CC FLAGS_REG))]
10380 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10381 [(set (match_dup 0)
10382 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10383
10384 (define_insn "*<rotate_insn><mode>3_1"
10385 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10386 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10387 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10388 (clobber (reg:CC FLAGS_REG))]
10389 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10390 {
10391 if (operands[2] == const1_rtx
10392 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10393 return "<rotate>{<imodesuffix>}\t%0";
10394 else
10395 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10396 }
10397 [(set_attr "type" "rotate")
10398 (set (attr "length_immediate")
10399 (if_then_else
10400 (and (match_operand 2 "const1_operand")
10401 (ior (match_test "TARGET_SHIFT1")
10402 (match_test "optimize_function_for_size_p (cfun)")))
10403 (const_string "0")
10404 (const_string "*")))
10405 (set_attr "mode" "<MODE>")])
10406
10407 (define_insn "*<rotate_insn>qi3_1_slp"
10408 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10409 (any_rotate:QI (match_dup 0)
10410 (match_operand:QI 1 "nonmemory_operand" "cI")))
10411 (clobber (reg:CC FLAGS_REG))]
10412 "(optimize_function_for_size_p (cfun)
10413 || !TARGET_PARTIAL_REG_STALL
10414 || (operands[1] == const1_rtx
10415 && TARGET_SHIFT1))"
10416 {
10417 if (operands[1] == const1_rtx
10418 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10419 return "<rotate>{b}\t%0";
10420 else
10421 return "<rotate>{b}\t{%1, %0|%0, %1}";
10422 }
10423 [(set_attr "type" "rotate1")
10424 (set (attr "length_immediate")
10425 (if_then_else
10426 (and (match_operand 1 "const1_operand")
10427 (ior (match_test "TARGET_SHIFT1")
10428 (match_test "optimize_function_for_size_p (cfun)")))
10429 (const_string "0")
10430 (const_string "*")))
10431 (set_attr "mode" "QI")])
10432
10433 (define_split
10434 [(set (match_operand:HI 0 "register_operand")
10435 (any_rotate:HI (match_dup 0) (const_int 8)))
10436 (clobber (reg:CC FLAGS_REG))]
10437 "reload_completed
10438 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10439 [(parallel [(set (strict_low_part (match_dup 0))
10440 (bswap:HI (match_dup 0)))
10441 (clobber (reg:CC FLAGS_REG))])])
10442 \f
10443 ;; Bit set / bit test instructions
10444
10445 (define_expand "extv"
10446 [(set (match_operand:SI 0 "register_operand")
10447 (sign_extract:SI (match_operand:SI 1 "register_operand")
10448 (match_operand:SI 2 "const8_operand")
10449 (match_operand:SI 3 "const8_operand")))]
10450 ""
10451 {
10452 /* Handle extractions from %ah et al. */
10453 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10454 FAIL;
10455
10456 /* From mips.md: extract_bit_field doesn't verify that our source
10457 matches the predicate, so check it again here. */
10458 if (! ext_register_operand (operands[1], VOIDmode))
10459 FAIL;
10460 })
10461
10462 (define_expand "extzv"
10463 [(set (match_operand:SI 0 "register_operand")
10464 (zero_extract:SI (match_operand 1 "ext_register_operand")
10465 (match_operand:SI 2 "const8_operand")
10466 (match_operand:SI 3 "const8_operand")))]
10467 ""
10468 {
10469 /* Handle extractions from %ah et al. */
10470 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10471 FAIL;
10472
10473 /* From mips.md: extract_bit_field doesn't verify that our source
10474 matches the predicate, so check it again here. */
10475 if (! ext_register_operand (operands[1], VOIDmode))
10476 FAIL;
10477 })
10478
10479 (define_expand "insv"
10480 [(set (zero_extract (match_operand 0 "register_operand")
10481 (match_operand 1 "const_int_operand")
10482 (match_operand 2 "const_int_operand"))
10483 (match_operand 3 "register_operand"))]
10484 ""
10485 {
10486 rtx (*gen_mov_insv_1) (rtx, rtx);
10487
10488 if (ix86_expand_pinsr (operands))
10489 DONE;
10490
10491 /* Handle insertions to %ah et al. */
10492 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10493 FAIL;
10494
10495 /* From mips.md: insert_bit_field doesn't verify that our source
10496 matches the predicate, so check it again here. */
10497 if (! ext_register_operand (operands[0], VOIDmode))
10498 FAIL;
10499
10500 gen_mov_insv_1 = (TARGET_64BIT
10501 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10502
10503 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10504 DONE;
10505 })
10506
10507 ;; %%% bts, btr, btc, bt.
10508 ;; In general these instructions are *slow* when applied to memory,
10509 ;; since they enforce atomic operation. When applied to registers,
10510 ;; it depends on the cpu implementation. They're never faster than
10511 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10512 ;; no point. But in 64-bit, we can't hold the relevant immediates
10513 ;; within the instruction itself, so operating on bits in the high
10514 ;; 32-bits of a register becomes easier.
10515 ;;
10516 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10517 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10518 ;; negdf respectively, so they can never be disabled entirely.
10519
10520 (define_insn "*btsq"
10521 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10522 (const_int 1)
10523 (match_operand:DI 1 "const_0_to_63_operand"))
10524 (const_int 1))
10525 (clobber (reg:CC FLAGS_REG))]
10526 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10527 "bts{q}\t{%1, %0|%0, %1}"
10528 [(set_attr "type" "alu1")
10529 (set_attr "prefix_0f" "1")
10530 (set_attr "mode" "DI")])
10531
10532 (define_insn "*btrq"
10533 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10534 (const_int 1)
10535 (match_operand:DI 1 "const_0_to_63_operand"))
10536 (const_int 0))
10537 (clobber (reg:CC FLAGS_REG))]
10538 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10539 "btr{q}\t{%1, %0|%0, %1}"
10540 [(set_attr "type" "alu1")
10541 (set_attr "prefix_0f" "1")
10542 (set_attr "mode" "DI")])
10543
10544 (define_insn "*btcq"
10545 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10546 (const_int 1)
10547 (match_operand:DI 1 "const_0_to_63_operand"))
10548 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10549 (clobber (reg:CC FLAGS_REG))]
10550 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10551 "btc{q}\t{%1, %0|%0, %1}"
10552 [(set_attr "type" "alu1")
10553 (set_attr "prefix_0f" "1")
10554 (set_attr "mode" "DI")])
10555
10556 ;; Allow Nocona to avoid these instructions if a register is available.
10557
10558 (define_peephole2
10559 [(match_scratch:DI 2 "r")
10560 (parallel [(set (zero_extract:DI
10561 (match_operand:DI 0 "register_operand")
10562 (const_int 1)
10563 (match_operand:DI 1 "const_0_to_63_operand"))
10564 (const_int 1))
10565 (clobber (reg:CC FLAGS_REG))])]
10566 "TARGET_64BIT && !TARGET_USE_BT"
10567 [(const_int 0)]
10568 {
10569 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10570 rtx op1;
10571
10572 if (HOST_BITS_PER_WIDE_INT >= 64)
10573 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10574 else if (i < HOST_BITS_PER_WIDE_INT)
10575 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10576 else
10577 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10578
10579 op1 = immed_double_const (lo, hi, DImode);
10580 if (i >= 31)
10581 {
10582 emit_move_insn (operands[2], op1);
10583 op1 = operands[2];
10584 }
10585
10586 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10587 DONE;
10588 })
10589
10590 (define_peephole2
10591 [(match_scratch:DI 2 "r")
10592 (parallel [(set (zero_extract:DI
10593 (match_operand:DI 0 "register_operand")
10594 (const_int 1)
10595 (match_operand:DI 1 "const_0_to_63_operand"))
10596 (const_int 0))
10597 (clobber (reg:CC FLAGS_REG))])]
10598 "TARGET_64BIT && !TARGET_USE_BT"
10599 [(const_int 0)]
10600 {
10601 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10602 rtx op1;
10603
10604 if (HOST_BITS_PER_WIDE_INT >= 64)
10605 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10606 else if (i < HOST_BITS_PER_WIDE_INT)
10607 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10608 else
10609 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10610
10611 op1 = immed_double_const (~lo, ~hi, DImode);
10612 if (i >= 32)
10613 {
10614 emit_move_insn (operands[2], op1);
10615 op1 = operands[2];
10616 }
10617
10618 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10619 DONE;
10620 })
10621
10622 (define_peephole2
10623 [(match_scratch:DI 2 "r")
10624 (parallel [(set (zero_extract:DI
10625 (match_operand:DI 0 "register_operand")
10626 (const_int 1)
10627 (match_operand:DI 1 "const_0_to_63_operand"))
10628 (not:DI (zero_extract:DI
10629 (match_dup 0) (const_int 1) (match_dup 1))))
10630 (clobber (reg:CC FLAGS_REG))])]
10631 "TARGET_64BIT && !TARGET_USE_BT"
10632 [(const_int 0)]
10633 {
10634 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10635 rtx op1;
10636
10637 if (HOST_BITS_PER_WIDE_INT >= 64)
10638 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10639 else if (i < HOST_BITS_PER_WIDE_INT)
10640 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10641 else
10642 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10643
10644 op1 = immed_double_const (lo, hi, DImode);
10645 if (i >= 31)
10646 {
10647 emit_move_insn (operands[2], op1);
10648 op1 = operands[2];
10649 }
10650
10651 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10652 DONE;
10653 })
10654
10655 (define_insn "*bt<mode>"
10656 [(set (reg:CCC FLAGS_REG)
10657 (compare:CCC
10658 (zero_extract:SWI48
10659 (match_operand:SWI48 0 "register_operand" "r")
10660 (const_int 1)
10661 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10662 (const_int 0)))]
10663 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10664 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10665 [(set_attr "type" "alu1")
10666 (set_attr "prefix_0f" "1")
10667 (set_attr "mode" "<MODE>")])
10668 \f
10669 ;; Store-flag instructions.
10670
10671 ;; For all sCOND expanders, also expand the compare or test insn that
10672 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10673
10674 (define_insn_and_split "*setcc_di_1"
10675 [(set (match_operand:DI 0 "register_operand" "=q")
10676 (match_operator:DI 1 "ix86_comparison_operator"
10677 [(reg FLAGS_REG) (const_int 0)]))]
10678 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10679 "#"
10680 "&& reload_completed"
10681 [(set (match_dup 2) (match_dup 1))
10682 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10683 {
10684 PUT_MODE (operands[1], QImode);
10685 operands[2] = gen_lowpart (QImode, operands[0]);
10686 })
10687
10688 (define_insn_and_split "*setcc_si_1_and"
10689 [(set (match_operand:SI 0 "register_operand" "=q")
10690 (match_operator:SI 1 "ix86_comparison_operator"
10691 [(reg FLAGS_REG) (const_int 0)]))
10692 (clobber (reg:CC FLAGS_REG))]
10693 "!TARGET_PARTIAL_REG_STALL
10694 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10695 "#"
10696 "&& reload_completed"
10697 [(set (match_dup 2) (match_dup 1))
10698 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10699 (clobber (reg:CC FLAGS_REG))])]
10700 {
10701 PUT_MODE (operands[1], QImode);
10702 operands[2] = gen_lowpart (QImode, operands[0]);
10703 })
10704
10705 (define_insn_and_split "*setcc_si_1_movzbl"
10706 [(set (match_operand:SI 0 "register_operand" "=q")
10707 (match_operator:SI 1 "ix86_comparison_operator"
10708 [(reg FLAGS_REG) (const_int 0)]))]
10709 "!TARGET_PARTIAL_REG_STALL
10710 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10711 "#"
10712 "&& reload_completed"
10713 [(set (match_dup 2) (match_dup 1))
10714 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10715 {
10716 PUT_MODE (operands[1], QImode);
10717 operands[2] = gen_lowpart (QImode, operands[0]);
10718 })
10719
10720 (define_insn "*setcc_qi"
10721 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10722 (match_operator:QI 1 "ix86_comparison_operator"
10723 [(reg FLAGS_REG) (const_int 0)]))]
10724 ""
10725 "set%C1\t%0"
10726 [(set_attr "type" "setcc")
10727 (set_attr "mode" "QI")])
10728
10729 (define_insn "*setcc_qi_slp"
10730 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10731 (match_operator:QI 1 "ix86_comparison_operator"
10732 [(reg FLAGS_REG) (const_int 0)]))]
10733 ""
10734 "set%C1\t%0"
10735 [(set_attr "type" "setcc")
10736 (set_attr "mode" "QI")])
10737
10738 ;; In general it is not safe to assume too much about CCmode registers,
10739 ;; so simplify-rtx stops when it sees a second one. Under certain
10740 ;; conditions this is safe on x86, so help combine not create
10741 ;;
10742 ;; seta %al
10743 ;; testb %al, %al
10744 ;; sete %al
10745
10746 (define_split
10747 [(set (match_operand:QI 0 "nonimmediate_operand")
10748 (ne:QI (match_operator 1 "ix86_comparison_operator"
10749 [(reg FLAGS_REG) (const_int 0)])
10750 (const_int 0)))]
10751 ""
10752 [(set (match_dup 0) (match_dup 1))]
10753 "PUT_MODE (operands[1], QImode);")
10754
10755 (define_split
10756 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10757 (ne:QI (match_operator 1 "ix86_comparison_operator"
10758 [(reg FLAGS_REG) (const_int 0)])
10759 (const_int 0)))]
10760 ""
10761 [(set (match_dup 0) (match_dup 1))]
10762 "PUT_MODE (operands[1], QImode);")
10763
10764 (define_split
10765 [(set (match_operand:QI 0 "nonimmediate_operand")
10766 (eq:QI (match_operator 1 "ix86_comparison_operator"
10767 [(reg FLAGS_REG) (const_int 0)])
10768 (const_int 0)))]
10769 ""
10770 [(set (match_dup 0) (match_dup 1))]
10771 {
10772 rtx new_op1 = copy_rtx (operands[1]);
10773 operands[1] = new_op1;
10774 PUT_MODE (new_op1, QImode);
10775 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10776 GET_MODE (XEXP (new_op1, 0))));
10777
10778 /* Make sure that (a) the CCmode we have for the flags is strong
10779 enough for the reversed compare or (b) we have a valid FP compare. */
10780 if (! ix86_comparison_operator (new_op1, VOIDmode))
10781 FAIL;
10782 })
10783
10784 (define_split
10785 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10786 (eq:QI (match_operator 1 "ix86_comparison_operator"
10787 [(reg FLAGS_REG) (const_int 0)])
10788 (const_int 0)))]
10789 ""
10790 [(set (match_dup 0) (match_dup 1))]
10791 {
10792 rtx new_op1 = copy_rtx (operands[1]);
10793 operands[1] = new_op1;
10794 PUT_MODE (new_op1, QImode);
10795 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10796 GET_MODE (XEXP (new_op1, 0))));
10797
10798 /* Make sure that (a) the CCmode we have for the flags is strong
10799 enough for the reversed compare or (b) we have a valid FP compare. */
10800 if (! ix86_comparison_operator (new_op1, VOIDmode))
10801 FAIL;
10802 })
10803
10804 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10805 ;; subsequent logical operations are used to imitate conditional moves.
10806 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10807 ;; it directly.
10808
10809 (define_insn "setcc_<mode>_sse"
10810 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10811 (match_operator:MODEF 3 "sse_comparison_operator"
10812 [(match_operand:MODEF 1 "register_operand" "0,x")
10813 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10814 "SSE_FLOAT_MODE_P (<MODE>mode)"
10815 "@
10816 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10817 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10818 [(set_attr "isa" "noavx,avx")
10819 (set_attr "type" "ssecmp")
10820 (set_attr "length_immediate" "1")
10821 (set_attr "prefix" "orig,vex")
10822 (set_attr "mode" "<MODE>")])
10823 \f
10824 ;; Basic conditional jump instructions.
10825 ;; We ignore the overflow flag for signed branch instructions.
10826
10827 (define_insn "*jcc_1"
10828 [(set (pc)
10829 (if_then_else (match_operator 1 "ix86_comparison_operator"
10830 [(reg FLAGS_REG) (const_int 0)])
10831 (label_ref (match_operand 0))
10832 (pc)))]
10833 ""
10834 "%+j%C1\t%l0"
10835 [(set_attr "type" "ibr")
10836 (set_attr "modrm" "0")
10837 (set (attr "length")
10838 (if_then_else (and (ge (minus (match_dup 0) (pc))
10839 (const_int -126))
10840 (lt (minus (match_dup 0) (pc))
10841 (const_int 128)))
10842 (const_int 2)
10843 (const_int 6)))])
10844
10845 (define_insn "*jcc_2"
10846 [(set (pc)
10847 (if_then_else (match_operator 1 "ix86_comparison_operator"
10848 [(reg FLAGS_REG) (const_int 0)])
10849 (pc)
10850 (label_ref (match_operand 0))))]
10851 ""
10852 "%+j%c1\t%l0"
10853 [(set_attr "type" "ibr")
10854 (set_attr "modrm" "0")
10855 (set (attr "length")
10856 (if_then_else (and (ge (minus (match_dup 0) (pc))
10857 (const_int -126))
10858 (lt (minus (match_dup 0) (pc))
10859 (const_int 128)))
10860 (const_int 2)
10861 (const_int 6)))])
10862
10863 ;; In general it is not safe to assume too much about CCmode registers,
10864 ;; so simplify-rtx stops when it sees a second one. Under certain
10865 ;; conditions this is safe on x86, so help combine not create
10866 ;;
10867 ;; seta %al
10868 ;; testb %al, %al
10869 ;; je Lfoo
10870
10871 (define_split
10872 [(set (pc)
10873 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10874 [(reg FLAGS_REG) (const_int 0)])
10875 (const_int 0))
10876 (label_ref (match_operand 1))
10877 (pc)))]
10878 ""
10879 [(set (pc)
10880 (if_then_else (match_dup 0)
10881 (label_ref (match_dup 1))
10882 (pc)))]
10883 "PUT_MODE (operands[0], VOIDmode);")
10884
10885 (define_split
10886 [(set (pc)
10887 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10888 [(reg FLAGS_REG) (const_int 0)])
10889 (const_int 0))
10890 (label_ref (match_operand 1))
10891 (pc)))]
10892 ""
10893 [(set (pc)
10894 (if_then_else (match_dup 0)
10895 (label_ref (match_dup 1))
10896 (pc)))]
10897 {
10898 rtx new_op0 = copy_rtx (operands[0]);
10899 operands[0] = new_op0;
10900 PUT_MODE (new_op0, VOIDmode);
10901 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10902 GET_MODE (XEXP (new_op0, 0))));
10903
10904 /* Make sure that (a) the CCmode we have for the flags is strong
10905 enough for the reversed compare or (b) we have a valid FP compare. */
10906 if (! ix86_comparison_operator (new_op0, VOIDmode))
10907 FAIL;
10908 })
10909
10910 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10911 ;; pass generates from shift insn with QImode operand. Actually, the mode
10912 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10913 ;; appropriate modulo of the bit offset value.
10914
10915 (define_insn_and_split "*jcc_bt<mode>"
10916 [(set (pc)
10917 (if_then_else (match_operator 0 "bt_comparison_operator"
10918 [(zero_extract:SWI48
10919 (match_operand:SWI48 1 "register_operand" "r")
10920 (const_int 1)
10921 (zero_extend:SI
10922 (match_operand:QI 2 "register_operand" "r")))
10923 (const_int 0)])
10924 (label_ref (match_operand 3))
10925 (pc)))
10926 (clobber (reg:CC FLAGS_REG))]
10927 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10928 "#"
10929 "&& 1"
10930 [(set (reg:CCC FLAGS_REG)
10931 (compare:CCC
10932 (zero_extract:SWI48
10933 (match_dup 1)
10934 (const_int 1)
10935 (match_dup 2))
10936 (const_int 0)))
10937 (set (pc)
10938 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10939 (label_ref (match_dup 3))
10940 (pc)))]
10941 {
10942 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10943
10944 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10945 })
10946
10947 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10948 ;; also for DImode, this is what combine produces.
10949 (define_insn_and_split "*jcc_bt<mode>_mask"
10950 [(set (pc)
10951 (if_then_else (match_operator 0 "bt_comparison_operator"
10952 [(zero_extract:SWI48
10953 (match_operand:SWI48 1 "register_operand" "r")
10954 (const_int 1)
10955 (and:SI
10956 (match_operand:SI 2 "register_operand" "r")
10957 (match_operand:SI 3 "const_int_operand" "n")))])
10958 (label_ref (match_operand 4))
10959 (pc)))
10960 (clobber (reg:CC FLAGS_REG))]
10961 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10962 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10963 == GET_MODE_BITSIZE (<MODE>mode)-1"
10964 "#"
10965 "&& 1"
10966 [(set (reg:CCC FLAGS_REG)
10967 (compare:CCC
10968 (zero_extract:SWI48
10969 (match_dup 1)
10970 (const_int 1)
10971 (match_dup 2))
10972 (const_int 0)))
10973 (set (pc)
10974 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10975 (label_ref (match_dup 4))
10976 (pc)))]
10977 {
10978 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10979
10980 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10981 })
10982
10983 (define_insn_and_split "*jcc_btsi_1"
10984 [(set (pc)
10985 (if_then_else (match_operator 0 "bt_comparison_operator"
10986 [(and:SI
10987 (lshiftrt:SI
10988 (match_operand:SI 1 "register_operand" "r")
10989 (match_operand:QI 2 "register_operand" "r"))
10990 (const_int 1))
10991 (const_int 0)])
10992 (label_ref (match_operand 3))
10993 (pc)))
10994 (clobber (reg:CC FLAGS_REG))]
10995 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10996 "#"
10997 "&& 1"
10998 [(set (reg:CCC FLAGS_REG)
10999 (compare:CCC
11000 (zero_extract:SI
11001 (match_dup 1)
11002 (const_int 1)
11003 (match_dup 2))
11004 (const_int 0)))
11005 (set (pc)
11006 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11007 (label_ref (match_dup 3))
11008 (pc)))]
11009 {
11010 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11011
11012 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11013 })
11014
11015 ;; avoid useless masking of bit offset operand
11016 (define_insn_and_split "*jcc_btsi_mask_1"
11017 [(set (pc)
11018 (if_then_else
11019 (match_operator 0 "bt_comparison_operator"
11020 [(and:SI
11021 (lshiftrt:SI
11022 (match_operand:SI 1 "register_operand" "r")
11023 (subreg:QI
11024 (and:SI
11025 (match_operand:SI 2 "register_operand" "r")
11026 (match_operand:SI 3 "const_int_operand" "n")) 0))
11027 (const_int 1))
11028 (const_int 0)])
11029 (label_ref (match_operand 4))
11030 (pc)))
11031 (clobber (reg:CC FLAGS_REG))]
11032 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11033 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11034 "#"
11035 "&& 1"
11036 [(set (reg:CCC FLAGS_REG)
11037 (compare:CCC
11038 (zero_extract:SI
11039 (match_dup 1)
11040 (const_int 1)
11041 (match_dup 2))
11042 (const_int 0)))
11043 (set (pc)
11044 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11045 (label_ref (match_dup 4))
11046 (pc)))]
11047 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11048
11049 ;; Define combination compare-and-branch fp compare instructions to help
11050 ;; combine.
11051
11052 (define_insn "*fp_jcc_1_387"
11053 [(set (pc)
11054 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11055 [(match_operand 1 "register_operand" "f")
11056 (match_operand 2 "nonimmediate_operand" "fm")])
11057 (label_ref (match_operand 3))
11058 (pc)))
11059 (clobber (reg:CCFP FPSR_REG))
11060 (clobber (reg:CCFP FLAGS_REG))
11061 (clobber (match_scratch:HI 4 "=a"))]
11062 "TARGET_80387
11063 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11064 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11065 && SELECT_CC_MODE (GET_CODE (operands[0]),
11066 operands[1], operands[2]) == CCFPmode
11067 && !TARGET_CMOVE"
11068 "#")
11069
11070 (define_insn "*fp_jcc_1r_387"
11071 [(set (pc)
11072 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11073 [(match_operand 1 "register_operand" "f")
11074 (match_operand 2 "nonimmediate_operand" "fm")])
11075 (pc)
11076 (label_ref (match_operand 3))))
11077 (clobber (reg:CCFP FPSR_REG))
11078 (clobber (reg:CCFP FLAGS_REG))
11079 (clobber (match_scratch:HI 4 "=a"))]
11080 "TARGET_80387
11081 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11082 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11083 && SELECT_CC_MODE (GET_CODE (operands[0]),
11084 operands[1], operands[2]) == CCFPmode
11085 && !TARGET_CMOVE"
11086 "#")
11087
11088 (define_insn "*fp_jcc_2_387"
11089 [(set (pc)
11090 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11091 [(match_operand 1 "register_operand" "f")
11092 (match_operand 2 "register_operand" "f")])
11093 (label_ref (match_operand 3))
11094 (pc)))
11095 (clobber (reg:CCFP FPSR_REG))
11096 (clobber (reg:CCFP FLAGS_REG))
11097 (clobber (match_scratch:HI 4 "=a"))]
11098 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11099 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11100 && !TARGET_CMOVE"
11101 "#")
11102
11103 (define_insn "*fp_jcc_2r_387"
11104 [(set (pc)
11105 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11106 [(match_operand 1 "register_operand" "f")
11107 (match_operand 2 "register_operand" "f")])
11108 (pc)
11109 (label_ref (match_operand 3))))
11110 (clobber (reg:CCFP FPSR_REG))
11111 (clobber (reg:CCFP FLAGS_REG))
11112 (clobber (match_scratch:HI 4 "=a"))]
11113 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11114 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11115 && !TARGET_CMOVE"
11116 "#")
11117
11118 (define_insn "*fp_jcc_3_387"
11119 [(set (pc)
11120 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11121 [(match_operand 1 "register_operand" "f")
11122 (match_operand 2 "const0_operand")])
11123 (label_ref (match_operand 3))
11124 (pc)))
11125 (clobber (reg:CCFP FPSR_REG))
11126 (clobber (reg:CCFP FLAGS_REG))
11127 (clobber (match_scratch:HI 4 "=a"))]
11128 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11129 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11130 && SELECT_CC_MODE (GET_CODE (operands[0]),
11131 operands[1], operands[2]) == CCFPmode
11132 && !TARGET_CMOVE"
11133 "#")
11134
11135 (define_split
11136 [(set (pc)
11137 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11138 [(match_operand 1 "register_operand")
11139 (match_operand 2 "nonimmediate_operand")])
11140 (match_operand 3)
11141 (match_operand 4)))
11142 (clobber (reg:CCFP FPSR_REG))
11143 (clobber (reg:CCFP FLAGS_REG))]
11144 "reload_completed"
11145 [(const_int 0)]
11146 {
11147 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11148 operands[3], operands[4], NULL_RTX, NULL_RTX);
11149 DONE;
11150 })
11151
11152 (define_split
11153 [(set (pc)
11154 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11155 [(match_operand 1 "register_operand")
11156 (match_operand 2 "general_operand")])
11157 (match_operand 3)
11158 (match_operand 4)))
11159 (clobber (reg:CCFP FPSR_REG))
11160 (clobber (reg:CCFP FLAGS_REG))
11161 (clobber (match_scratch:HI 5 "=a"))]
11162 "reload_completed"
11163 [(const_int 0)]
11164 {
11165 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11166 operands[3], operands[4], operands[5], NULL_RTX);
11167 DONE;
11168 })
11169
11170 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11171 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11172 ;; with a precedence over other operators and is always put in the first
11173 ;; place. Swap condition and operands to match ficom instruction.
11174
11175 (define_insn "*fp_jcc_4_<mode>_387"
11176 [(set (pc)
11177 (if_then_else
11178 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11179 [(match_operator 1 "float_operator"
11180 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11181 (match_operand 3 "register_operand" "f,f")])
11182 (label_ref (match_operand 4))
11183 (pc)))
11184 (clobber (reg:CCFP FPSR_REG))
11185 (clobber (reg:CCFP FLAGS_REG))
11186 (clobber (match_scratch:HI 5 "=a,a"))]
11187 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11188 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11189 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11190 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11191 && !TARGET_CMOVE"
11192 "#")
11193
11194 (define_split
11195 [(set (pc)
11196 (if_then_else
11197 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11198 [(match_operator 1 "float_operator"
11199 [(match_operand:SWI24 2 "memory_operand")])
11200 (match_operand 3 "register_operand")])
11201 (match_operand 4)
11202 (match_operand 5)))
11203 (clobber (reg:CCFP FPSR_REG))
11204 (clobber (reg:CCFP FLAGS_REG))
11205 (clobber (match_scratch:HI 6 "=a"))]
11206 "reload_completed"
11207 [(const_int 0)]
11208 {
11209 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11210
11211 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11212 operands[3], operands[7],
11213 operands[4], operands[5], operands[6], NULL_RTX);
11214 DONE;
11215 })
11216
11217 ;; %%% Kill this when reload knows how to do it.
11218 (define_split
11219 [(set (pc)
11220 (if_then_else
11221 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11222 [(match_operator 1 "float_operator"
11223 [(match_operand:SWI24 2 "register_operand")])
11224 (match_operand 3 "register_operand")])
11225 (match_operand 4)
11226 (match_operand 5)))
11227 (clobber (reg:CCFP FPSR_REG))
11228 (clobber (reg:CCFP FLAGS_REG))
11229 (clobber (match_scratch:HI 6 "=a"))]
11230 "reload_completed"
11231 [(const_int 0)]
11232 {
11233 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11234 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11235
11236 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11237 operands[3], operands[7],
11238 operands[4], operands[5], operands[6], operands[2]);
11239 DONE;
11240 })
11241 \f
11242 ;; Unconditional and other jump instructions
11243
11244 (define_insn "jump"
11245 [(set (pc)
11246 (label_ref (match_operand 0)))]
11247 ""
11248 "jmp\t%l0"
11249 [(set_attr "type" "ibr")
11250 (set (attr "length")
11251 (if_then_else (and (ge (minus (match_dup 0) (pc))
11252 (const_int -126))
11253 (lt (minus (match_dup 0) (pc))
11254 (const_int 128)))
11255 (const_int 2)
11256 (const_int 5)))
11257 (set_attr "modrm" "0")])
11258
11259 (define_expand "indirect_jump"
11260 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11261 ""
11262 {
11263 if (TARGET_X32)
11264 operands[0] = convert_memory_address (word_mode, operands[0]);
11265 })
11266
11267 (define_insn "*indirect_jump"
11268 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11269 ""
11270 "jmp\t%A0"
11271 [(set_attr "type" "ibr")
11272 (set_attr "length_immediate" "0")])
11273
11274 (define_expand "tablejump"
11275 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11276 (use (label_ref (match_operand 1)))])]
11277 ""
11278 {
11279 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11280 relative. Convert the relative address to an absolute address. */
11281 if (flag_pic)
11282 {
11283 rtx op0, op1;
11284 enum rtx_code code;
11285
11286 /* We can't use @GOTOFF for text labels on VxWorks;
11287 see gotoff_operand. */
11288 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11289 {
11290 code = PLUS;
11291 op0 = operands[0];
11292 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11293 }
11294 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11295 {
11296 code = PLUS;
11297 op0 = operands[0];
11298 op1 = pic_offset_table_rtx;
11299 }
11300 else
11301 {
11302 code = MINUS;
11303 op0 = pic_offset_table_rtx;
11304 op1 = operands[0];
11305 }
11306
11307 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11308 OPTAB_DIRECT);
11309 }
11310
11311 if (TARGET_X32)
11312 operands[0] = convert_memory_address (word_mode, operands[0]);
11313 })
11314
11315 (define_insn "*tablejump_1"
11316 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11317 (use (label_ref (match_operand 1)))]
11318 ""
11319 "jmp\t%A0"
11320 [(set_attr "type" "ibr")
11321 (set_attr "length_immediate" "0")])
11322 \f
11323 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11324
11325 (define_peephole2
11326 [(set (reg FLAGS_REG) (match_operand 0))
11327 (set (match_operand:QI 1 "register_operand")
11328 (match_operator:QI 2 "ix86_comparison_operator"
11329 [(reg FLAGS_REG) (const_int 0)]))
11330 (set (match_operand 3 "q_regs_operand")
11331 (zero_extend (match_dup 1)))]
11332 "(peep2_reg_dead_p (3, operands[1])
11333 || operands_match_p (operands[1], operands[3]))
11334 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11335 [(set (match_dup 4) (match_dup 0))
11336 (set (strict_low_part (match_dup 5))
11337 (match_dup 2))]
11338 {
11339 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11340 operands[5] = gen_lowpart (QImode, operands[3]);
11341 ix86_expand_clear (operands[3]);
11342 })
11343
11344 (define_peephole2
11345 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11346 (match_operand 4)])
11347 (set (match_operand:QI 1 "register_operand")
11348 (match_operator:QI 2 "ix86_comparison_operator"
11349 [(reg FLAGS_REG) (const_int 0)]))
11350 (set (match_operand 3 "q_regs_operand")
11351 (zero_extend (match_dup 1)))]
11352 "(peep2_reg_dead_p (3, operands[1])
11353 || operands_match_p (operands[1], operands[3]))
11354 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11355 [(parallel [(set (match_dup 5) (match_dup 0))
11356 (match_dup 4)])
11357 (set (strict_low_part (match_dup 6))
11358 (match_dup 2))]
11359 {
11360 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11361 operands[6] = gen_lowpart (QImode, operands[3]);
11362 ix86_expand_clear (operands[3]);
11363 })
11364
11365 ;; Similar, but match zero extend with andsi3.
11366
11367 (define_peephole2
11368 [(set (reg FLAGS_REG) (match_operand 0))
11369 (set (match_operand:QI 1 "register_operand")
11370 (match_operator:QI 2 "ix86_comparison_operator"
11371 [(reg FLAGS_REG) (const_int 0)]))
11372 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11373 (and:SI (match_dup 3) (const_int 255)))
11374 (clobber (reg:CC FLAGS_REG))])]
11375 "REGNO (operands[1]) == REGNO (operands[3])
11376 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11377 [(set (match_dup 4) (match_dup 0))
11378 (set (strict_low_part (match_dup 5))
11379 (match_dup 2))]
11380 {
11381 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11382 operands[5] = gen_lowpart (QImode, operands[3]);
11383 ix86_expand_clear (operands[3]);
11384 })
11385
11386 (define_peephole2
11387 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11388 (match_operand 4)])
11389 (set (match_operand:QI 1 "register_operand")
11390 (match_operator:QI 2 "ix86_comparison_operator"
11391 [(reg FLAGS_REG) (const_int 0)]))
11392 (parallel [(set (match_operand 3 "q_regs_operand")
11393 (zero_extend (match_dup 1)))
11394 (clobber (reg:CC FLAGS_REG))])]
11395 "(peep2_reg_dead_p (3, operands[1])
11396 || operands_match_p (operands[1], operands[3]))
11397 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11398 [(parallel [(set (match_dup 5) (match_dup 0))
11399 (match_dup 4)])
11400 (set (strict_low_part (match_dup 6))
11401 (match_dup 2))]
11402 {
11403 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11404 operands[6] = gen_lowpart (QImode, operands[3]);
11405 ix86_expand_clear (operands[3]);
11406 })
11407 \f
11408 ;; Call instructions.
11409
11410 ;; The predicates normally associated with named expanders are not properly
11411 ;; checked for calls. This is a bug in the generic code, but it isn't that
11412 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11413
11414 ;; P6 processors will jump to the address after the decrement when %esp
11415 ;; is used as a call operand, so they will execute return address as a code.
11416 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11417
11418 ;; Register constraint for call instruction.
11419 (define_mode_attr c [(SI "l") (DI "r")])
11420
11421 ;; Call subroutine returning no value.
11422
11423 (define_expand "call"
11424 [(call (match_operand:QI 0)
11425 (match_operand 1))
11426 (use (match_operand 2))]
11427 ""
11428 {
11429 ix86_expand_call (NULL, operands[0], operands[1],
11430 operands[2], NULL, false);
11431 DONE;
11432 })
11433
11434 (define_expand "sibcall"
11435 [(call (match_operand:QI 0)
11436 (match_operand 1))
11437 (use (match_operand 2))]
11438 ""
11439 {
11440 ix86_expand_call (NULL, operands[0], operands[1],
11441 operands[2], NULL, true);
11442 DONE;
11443 })
11444
11445 (define_insn_and_split "*call_vzeroupper"
11446 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11447 (match_operand 1))
11448 (unspec [(match_operand 2 "const_int_operand")]
11449 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11450 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11451 "#"
11452 "&& reload_completed"
11453 [(const_int 0)]
11454 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11455 [(set_attr "type" "call")])
11456
11457 (define_insn "*call"
11458 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11459 (match_operand 1))]
11460 "!SIBLING_CALL_P (insn)"
11461 "* return ix86_output_call_insn (insn, operands[0]);"
11462 [(set_attr "type" "call")])
11463
11464 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11465 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11466 (match_operand 1))
11467 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11468 (clobber (reg:TI XMM6_REG))
11469 (clobber (reg:TI XMM7_REG))
11470 (clobber (reg:TI XMM8_REG))
11471 (clobber (reg:TI XMM9_REG))
11472 (clobber (reg:TI XMM10_REG))
11473 (clobber (reg:TI XMM11_REG))
11474 (clobber (reg:TI XMM12_REG))
11475 (clobber (reg:TI XMM13_REG))
11476 (clobber (reg:TI XMM14_REG))
11477 (clobber (reg:TI XMM15_REG))
11478 (clobber (reg:DI SI_REG))
11479 (clobber (reg:DI DI_REG))
11480 (unspec [(match_operand 2 "const_int_operand")]
11481 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11482 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11483 "#"
11484 "&& reload_completed"
11485 [(const_int 0)]
11486 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11487 [(set_attr "type" "call")])
11488
11489 (define_insn "*call_rex64_ms_sysv"
11490 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11491 (match_operand 1))
11492 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11493 (clobber (reg:TI XMM6_REG))
11494 (clobber (reg:TI XMM7_REG))
11495 (clobber (reg:TI XMM8_REG))
11496 (clobber (reg:TI XMM9_REG))
11497 (clobber (reg:TI XMM10_REG))
11498 (clobber (reg:TI XMM11_REG))
11499 (clobber (reg:TI XMM12_REG))
11500 (clobber (reg:TI XMM13_REG))
11501 (clobber (reg:TI XMM14_REG))
11502 (clobber (reg:TI XMM15_REG))
11503 (clobber (reg:DI SI_REG))
11504 (clobber (reg:DI DI_REG))]
11505 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11506 "* return ix86_output_call_insn (insn, operands[0]);"
11507 [(set_attr "type" "call")])
11508
11509 (define_insn_and_split "*sibcall_vzeroupper"
11510 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11511 (match_operand 1))
11512 (unspec [(match_operand 2 "const_int_operand")]
11513 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11514 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11515 "#"
11516 "&& reload_completed"
11517 [(const_int 0)]
11518 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11519 [(set_attr "type" "call")])
11520
11521 (define_insn "*sibcall"
11522 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11523 (match_operand 1))]
11524 "SIBLING_CALL_P (insn)"
11525 "* return ix86_output_call_insn (insn, operands[0]);"
11526 [(set_attr "type" "call")])
11527
11528 (define_expand "call_pop"
11529 [(parallel [(call (match_operand:QI 0)
11530 (match_operand:SI 1))
11531 (set (reg:SI SP_REG)
11532 (plus:SI (reg:SI SP_REG)
11533 (match_operand:SI 3)))])]
11534 "!TARGET_64BIT"
11535 {
11536 ix86_expand_call (NULL, operands[0], operands[1],
11537 operands[2], operands[3], false);
11538 DONE;
11539 })
11540
11541 (define_insn_and_split "*call_pop_vzeroupper"
11542 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11543 (match_operand 1))
11544 (set (reg:SI SP_REG)
11545 (plus:SI (reg:SI SP_REG)
11546 (match_operand:SI 2 "immediate_operand" "i")))
11547 (unspec [(match_operand 3 "const_int_operand")]
11548 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11549 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11550 "#"
11551 "&& reload_completed"
11552 [(const_int 0)]
11553 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11554 [(set_attr "type" "call")])
11555
11556 (define_insn "*call_pop"
11557 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11558 (match_operand 1))
11559 (set (reg:SI SP_REG)
11560 (plus:SI (reg:SI SP_REG)
11561 (match_operand:SI 2 "immediate_operand" "i")))]
11562 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11563 "* return ix86_output_call_insn (insn, operands[0]);"
11564 [(set_attr "type" "call")])
11565
11566 (define_insn_and_split "*sibcall_pop_vzeroupper"
11567 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11568 (match_operand 1))
11569 (set (reg:SI SP_REG)
11570 (plus:SI (reg:SI SP_REG)
11571 (match_operand:SI 2 "immediate_operand" "i")))
11572 (unspec [(match_operand 3 "const_int_operand")]
11573 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11574 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11575 "#"
11576 "&& reload_completed"
11577 [(const_int 0)]
11578 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11579 [(set_attr "type" "call")])
11580
11581 (define_insn "*sibcall_pop"
11582 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11583 (match_operand 1))
11584 (set (reg:SI SP_REG)
11585 (plus:SI (reg:SI SP_REG)
11586 (match_operand:SI 2 "immediate_operand" "i")))]
11587 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11588 "* return ix86_output_call_insn (insn, operands[0]);"
11589 [(set_attr "type" "call")])
11590
11591 ;; Call subroutine, returning value in operand 0
11592
11593 (define_expand "call_value"
11594 [(set (match_operand 0)
11595 (call (match_operand:QI 1)
11596 (match_operand 2)))
11597 (use (match_operand 3))]
11598 ""
11599 {
11600 ix86_expand_call (operands[0], operands[1], operands[2],
11601 operands[3], NULL, false);
11602 DONE;
11603 })
11604
11605 (define_expand "sibcall_value"
11606 [(set (match_operand 0)
11607 (call (match_operand:QI 1)
11608 (match_operand 2)))
11609 (use (match_operand 3))]
11610 ""
11611 {
11612 ix86_expand_call (operands[0], operands[1], operands[2],
11613 operands[3], NULL, true);
11614 DONE;
11615 })
11616
11617 (define_insn_and_split "*call_value_vzeroupper"
11618 [(set (match_operand 0)
11619 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11620 (match_operand 2)))
11621 (unspec [(match_operand 3 "const_int_operand")]
11622 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11623 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11624 "#"
11625 "&& reload_completed"
11626 [(const_int 0)]
11627 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11628 [(set_attr "type" "callv")])
11629
11630 (define_insn "*call_value"
11631 [(set (match_operand 0)
11632 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11633 (match_operand 2)))]
11634 "!SIBLING_CALL_P (insn)"
11635 "* return ix86_output_call_insn (insn, operands[1]);"
11636 [(set_attr "type" "callv")])
11637
11638 (define_insn_and_split "*sibcall_value_vzeroupper"
11639 [(set (match_operand 0)
11640 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11641 (match_operand 2)))
11642 (unspec [(match_operand 3 "const_int_operand")]
11643 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11644 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11645 "#"
11646 "&& reload_completed"
11647 [(const_int 0)]
11648 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11649 [(set_attr "type" "callv")])
11650
11651 (define_insn "*sibcall_value"
11652 [(set (match_operand 0)
11653 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11654 (match_operand 2)))]
11655 "SIBLING_CALL_P (insn)"
11656 "* return ix86_output_call_insn (insn, operands[1]);"
11657 [(set_attr "type" "callv")])
11658
11659 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11660 [(set (match_operand 0)
11661 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11662 (match_operand 2)))
11663 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11664 (clobber (reg:TI XMM6_REG))
11665 (clobber (reg:TI XMM7_REG))
11666 (clobber (reg:TI XMM8_REG))
11667 (clobber (reg:TI XMM9_REG))
11668 (clobber (reg:TI XMM10_REG))
11669 (clobber (reg:TI XMM11_REG))
11670 (clobber (reg:TI XMM12_REG))
11671 (clobber (reg:TI XMM13_REG))
11672 (clobber (reg:TI XMM14_REG))
11673 (clobber (reg:TI XMM15_REG))
11674 (clobber (reg:DI SI_REG))
11675 (clobber (reg:DI DI_REG))
11676 (unspec [(match_operand 3 "const_int_operand")]
11677 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11678 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11679 "#"
11680 "&& reload_completed"
11681 [(const_int 0)]
11682 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11683 [(set_attr "type" "callv")])
11684
11685 (define_insn "*call_value_rex64_ms_sysv"
11686 [(set (match_operand 0)
11687 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11688 (match_operand 2)))
11689 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11690 (clobber (reg:TI XMM6_REG))
11691 (clobber (reg:TI XMM7_REG))
11692 (clobber (reg:TI XMM8_REG))
11693 (clobber (reg:TI XMM9_REG))
11694 (clobber (reg:TI XMM10_REG))
11695 (clobber (reg:TI XMM11_REG))
11696 (clobber (reg:TI XMM12_REG))
11697 (clobber (reg:TI XMM13_REG))
11698 (clobber (reg:TI XMM14_REG))
11699 (clobber (reg:TI XMM15_REG))
11700 (clobber (reg:DI SI_REG))
11701 (clobber (reg:DI DI_REG))]
11702 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11703 "* return ix86_output_call_insn (insn, operands[1]);"
11704 [(set_attr "type" "callv")])
11705
11706 (define_expand "call_value_pop"
11707 [(parallel [(set (match_operand 0)
11708 (call (match_operand:QI 1)
11709 (match_operand:SI 2)))
11710 (set (reg:SI SP_REG)
11711 (plus:SI (reg:SI SP_REG)
11712 (match_operand:SI 4)))])]
11713 "!TARGET_64BIT"
11714 {
11715 ix86_expand_call (operands[0], operands[1], operands[2],
11716 operands[3], operands[4], false);
11717 DONE;
11718 })
11719
11720 (define_insn_and_split "*call_value_pop_vzeroupper"
11721 [(set (match_operand 0)
11722 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11723 (match_operand 2)))
11724 (set (reg:SI SP_REG)
11725 (plus:SI (reg:SI SP_REG)
11726 (match_operand:SI 3 "immediate_operand" "i")))
11727 (unspec [(match_operand 4 "const_int_operand")]
11728 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11729 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11730 "#"
11731 "&& reload_completed"
11732 [(const_int 0)]
11733 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11734 [(set_attr "type" "callv")])
11735
11736 (define_insn "*call_value_pop"
11737 [(set (match_operand 0)
11738 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11739 (match_operand 2)))
11740 (set (reg:SI SP_REG)
11741 (plus:SI (reg:SI SP_REG)
11742 (match_operand:SI 3 "immediate_operand" "i")))]
11743 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11744 "* return ix86_output_call_insn (insn, operands[1]);"
11745 [(set_attr "type" "callv")])
11746
11747 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11748 [(set (match_operand 0)
11749 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11750 (match_operand 2)))
11751 (set (reg:SI SP_REG)
11752 (plus:SI (reg:SI SP_REG)
11753 (match_operand:SI 3 "immediate_operand" "i")))
11754 (unspec [(match_operand 4 "const_int_operand")]
11755 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11756 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11757 "#"
11758 "&& reload_completed"
11759 [(const_int 0)]
11760 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11761 [(set_attr "type" "callv")])
11762
11763 (define_insn "*sibcall_value_pop"
11764 [(set (match_operand 0)
11765 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11766 (match_operand 2)))
11767 (set (reg:SI SP_REG)
11768 (plus:SI (reg:SI SP_REG)
11769 (match_operand:SI 3 "immediate_operand" "i")))]
11770 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11771 "* return ix86_output_call_insn (insn, operands[1]);"
11772 [(set_attr "type" "callv")])
11773
11774 ;; Call subroutine returning any type.
11775
11776 (define_expand "untyped_call"
11777 [(parallel [(call (match_operand 0)
11778 (const_int 0))
11779 (match_operand 1)
11780 (match_operand 2)])]
11781 ""
11782 {
11783 int i;
11784
11785 /* In order to give reg-stack an easier job in validating two
11786 coprocessor registers as containing a possible return value,
11787 simply pretend the untyped call returns a complex long double
11788 value.
11789
11790 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11791 and should have the default ABI. */
11792
11793 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11794 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11795 operands[0], const0_rtx,
11796 GEN_INT ((TARGET_64BIT
11797 ? (ix86_abi == SYSV_ABI
11798 ? X86_64_SSE_REGPARM_MAX
11799 : X86_64_MS_SSE_REGPARM_MAX)
11800 : X86_32_SSE_REGPARM_MAX)
11801 - 1),
11802 NULL, false);
11803
11804 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11805 {
11806 rtx set = XVECEXP (operands[2], 0, i);
11807 emit_move_insn (SET_DEST (set), SET_SRC (set));
11808 }
11809
11810 /* The optimizer does not know that the call sets the function value
11811 registers we stored in the result block. We avoid problems by
11812 claiming that all hard registers are used and clobbered at this
11813 point. */
11814 emit_insn (gen_blockage ());
11815
11816 DONE;
11817 })
11818 \f
11819 ;; Prologue and epilogue instructions
11820
11821 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11822 ;; all of memory. This blocks insns from being moved across this point.
11823
11824 (define_insn "blockage"
11825 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11826 ""
11827 ""
11828 [(set_attr "length" "0")])
11829
11830 ;; Do not schedule instructions accessing memory across this point.
11831
11832 (define_expand "memory_blockage"
11833 [(set (match_dup 0)
11834 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11835 ""
11836 {
11837 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11838 MEM_VOLATILE_P (operands[0]) = 1;
11839 })
11840
11841 (define_insn "*memory_blockage"
11842 [(set (match_operand:BLK 0)
11843 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11844 ""
11845 ""
11846 [(set_attr "length" "0")])
11847
11848 ;; As USE insns aren't meaningful after reload, this is used instead
11849 ;; to prevent deleting instructions setting registers for PIC code
11850 (define_insn "prologue_use"
11851 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11852 ""
11853 ""
11854 [(set_attr "length" "0")])
11855
11856 ;; Insn emitted into the body of a function to return from a function.
11857 ;; This is only done if the function's epilogue is known to be simple.
11858 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11859
11860 (define_expand "return"
11861 [(simple_return)]
11862 "ix86_can_use_return_insn_p ()"
11863 {
11864 ix86_maybe_emit_epilogue_vzeroupper ();
11865 if (crtl->args.pops_args)
11866 {
11867 rtx popc = GEN_INT (crtl->args.pops_args);
11868 emit_jump_insn (gen_simple_return_pop_internal (popc));
11869 DONE;
11870 }
11871 })
11872
11873 ;; We need to disable this for TARGET_SEH, as otherwise
11874 ;; shrink-wrapped prologue gets enabled too. This might exceed
11875 ;; the maximum size of prologue in unwind information.
11876
11877 (define_expand "simple_return"
11878 [(simple_return)]
11879 "!TARGET_SEH"
11880 {
11881 ix86_maybe_emit_epilogue_vzeroupper ();
11882 if (crtl->args.pops_args)
11883 {
11884 rtx popc = GEN_INT (crtl->args.pops_args);
11885 emit_jump_insn (gen_simple_return_pop_internal (popc));
11886 DONE;
11887 }
11888 })
11889
11890 (define_insn "simple_return_internal"
11891 [(simple_return)]
11892 "reload_completed"
11893 "ret"
11894 [(set_attr "length" "1")
11895 (set_attr "atom_unit" "jeu")
11896 (set_attr "length_immediate" "0")
11897 (set_attr "modrm" "0")])
11898
11899 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11900 ;; instruction Athlon and K8 have.
11901
11902 (define_insn "simple_return_internal_long"
11903 [(simple_return)
11904 (unspec [(const_int 0)] UNSPEC_REP)]
11905 "reload_completed"
11906 "rep\;ret"
11907 [(set_attr "length" "2")
11908 (set_attr "atom_unit" "jeu")
11909 (set_attr "length_immediate" "0")
11910 (set_attr "prefix_rep" "1")
11911 (set_attr "modrm" "0")])
11912
11913 (define_insn "simple_return_pop_internal"
11914 [(simple_return)
11915 (use (match_operand:SI 0 "const_int_operand"))]
11916 "reload_completed"
11917 "ret\t%0"
11918 [(set_attr "length" "3")
11919 (set_attr "atom_unit" "jeu")
11920 (set_attr "length_immediate" "2")
11921 (set_attr "modrm" "0")])
11922
11923 (define_insn "simple_return_indirect_internal"
11924 [(simple_return)
11925 (use (match_operand:SI 0 "register_operand" "r"))]
11926 "reload_completed"
11927 "jmp\t%A0"
11928 [(set_attr "type" "ibr")
11929 (set_attr "length_immediate" "0")])
11930
11931 (define_insn "nop"
11932 [(const_int 0)]
11933 ""
11934 "nop"
11935 [(set_attr "length" "1")
11936 (set_attr "length_immediate" "0")
11937 (set_attr "modrm" "0")])
11938
11939 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11940 (define_insn "nops"
11941 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11942 UNSPECV_NOPS)]
11943 "reload_completed"
11944 {
11945 int num = INTVAL (operands[0]);
11946
11947 gcc_assert (num >= 1 && num <= 8);
11948
11949 while (num--)
11950 fputs ("\tnop\n", asm_out_file);
11951
11952 return "";
11953 }
11954 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11955 (set_attr "length_immediate" "0")
11956 (set_attr "modrm" "0")])
11957
11958 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11959 ;; branch prediction penalty for the third jump in a 16-byte
11960 ;; block on K8.
11961
11962 (define_insn "pad"
11963 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11964 ""
11965 {
11966 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11967 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11968 #else
11969 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11970 The align insn is used to avoid 3 jump instructions in the row to improve
11971 branch prediction and the benefits hardly outweigh the cost of extra 8
11972 nops on the average inserted by full alignment pseudo operation. */
11973 #endif
11974 return "";
11975 }
11976 [(set_attr "length" "16")])
11977
11978 (define_expand "prologue"
11979 [(const_int 0)]
11980 ""
11981 "ix86_expand_prologue (); DONE;")
11982
11983 (define_insn "set_got"
11984 [(set (match_operand:SI 0 "register_operand" "=r")
11985 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11986 (clobber (reg:CC FLAGS_REG))]
11987 "!TARGET_64BIT"
11988 "* return output_set_got (operands[0], NULL_RTX);"
11989 [(set_attr "type" "multi")
11990 (set_attr "length" "12")])
11991
11992 (define_insn "set_got_labelled"
11993 [(set (match_operand:SI 0 "register_operand" "=r")
11994 (unspec:SI [(label_ref (match_operand 1))]
11995 UNSPEC_SET_GOT))
11996 (clobber (reg:CC FLAGS_REG))]
11997 "!TARGET_64BIT"
11998 "* return output_set_got (operands[0], operands[1]);"
11999 [(set_attr "type" "multi")
12000 (set_attr "length" "12")])
12001
12002 (define_insn "set_got_rex64"
12003 [(set (match_operand:DI 0 "register_operand" "=r")
12004 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12005 "TARGET_64BIT"
12006 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12007 [(set_attr "type" "lea")
12008 (set_attr "length_address" "4")
12009 (set_attr "mode" "DI")])
12010
12011 (define_insn "set_rip_rex64"
12012 [(set (match_operand:DI 0 "register_operand" "=r")
12013 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12014 "TARGET_64BIT"
12015 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12016 [(set_attr "type" "lea")
12017 (set_attr "length_address" "4")
12018 (set_attr "mode" "DI")])
12019
12020 (define_insn "set_got_offset_rex64"
12021 [(set (match_operand:DI 0 "register_operand" "=r")
12022 (unspec:DI
12023 [(label_ref (match_operand 1))]
12024 UNSPEC_SET_GOT_OFFSET))]
12025 "TARGET_LP64"
12026 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12027 [(set_attr "type" "imov")
12028 (set_attr "length_immediate" "0")
12029 (set_attr "length_address" "8")
12030 (set_attr "mode" "DI")])
12031
12032 (define_expand "epilogue"
12033 [(const_int 0)]
12034 ""
12035 "ix86_expand_epilogue (1); DONE;")
12036
12037 (define_expand "sibcall_epilogue"
12038 [(const_int 0)]
12039 ""
12040 "ix86_expand_epilogue (0); DONE;")
12041
12042 (define_expand "eh_return"
12043 [(use (match_operand 0 "register_operand"))]
12044 ""
12045 {
12046 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12047
12048 /* Tricky bit: we write the address of the handler to which we will
12049 be returning into someone else's stack frame, one word below the
12050 stack address we wish to restore. */
12051 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12052 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12053 tmp = gen_rtx_MEM (Pmode, tmp);
12054 emit_move_insn (tmp, ra);
12055
12056 emit_jump_insn (gen_eh_return_internal ());
12057 emit_barrier ();
12058 DONE;
12059 })
12060
12061 (define_insn_and_split "eh_return_internal"
12062 [(eh_return)]
12063 ""
12064 "#"
12065 "epilogue_completed"
12066 [(const_int 0)]
12067 "ix86_expand_epilogue (2); DONE;")
12068
12069 (define_insn "leave"
12070 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12071 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12072 (clobber (mem:BLK (scratch)))]
12073 "!TARGET_64BIT"
12074 "leave"
12075 [(set_attr "type" "leave")])
12076
12077 (define_insn "leave_rex64"
12078 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12079 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12080 (clobber (mem:BLK (scratch)))]
12081 "TARGET_64BIT"
12082 "leave"
12083 [(set_attr "type" "leave")])
12084 \f
12085 ;; Handle -fsplit-stack.
12086
12087 (define_expand "split_stack_prologue"
12088 [(const_int 0)]
12089 ""
12090 {
12091 ix86_expand_split_stack_prologue ();
12092 DONE;
12093 })
12094
12095 ;; In order to support the call/return predictor, we use a return
12096 ;; instruction which the middle-end doesn't see.
12097 (define_insn "split_stack_return"
12098 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12099 UNSPECV_SPLIT_STACK_RETURN)]
12100 ""
12101 {
12102 if (operands[0] == const0_rtx)
12103 return "ret";
12104 else
12105 return "ret\t%0";
12106 }
12107 [(set_attr "atom_unit" "jeu")
12108 (set_attr "modrm" "0")
12109 (set (attr "length")
12110 (if_then_else (match_operand:SI 0 "const0_operand")
12111 (const_int 1)
12112 (const_int 3)))
12113 (set (attr "length_immediate")
12114 (if_then_else (match_operand:SI 0 "const0_operand")
12115 (const_int 0)
12116 (const_int 2)))])
12117
12118 ;; If there are operand 0 bytes available on the stack, jump to
12119 ;; operand 1.
12120
12121 (define_expand "split_stack_space_check"
12122 [(set (pc) (if_then_else
12123 (ltu (minus (reg SP_REG)
12124 (match_operand 0 "register_operand"))
12125 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12126 (label_ref (match_operand 1))
12127 (pc)))]
12128 ""
12129 {
12130 rtx reg, size, limit;
12131
12132 reg = gen_reg_rtx (Pmode);
12133 size = force_reg (Pmode, operands[0]);
12134 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12135 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12136 UNSPEC_STACK_CHECK);
12137 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12138 ix86_expand_branch (GEU, reg, limit, operands[1]);
12139
12140 DONE;
12141 })
12142 \f
12143 ;; Bit manipulation instructions.
12144
12145 (define_expand "ffs<mode>2"
12146 [(set (match_dup 2) (const_int -1))
12147 (parallel [(set (match_dup 3) (match_dup 4))
12148 (set (match_operand:SWI48 0 "register_operand")
12149 (ctz:SWI48
12150 (match_operand:SWI48 1 "nonimmediate_operand")))])
12151 (set (match_dup 0) (if_then_else:SWI48
12152 (eq (match_dup 3) (const_int 0))
12153 (match_dup 2)
12154 (match_dup 0)))
12155 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12156 (clobber (reg:CC FLAGS_REG))])]
12157 ""
12158 {
12159 enum machine_mode flags_mode;
12160
12161 if (<MODE>mode == SImode && !TARGET_CMOVE)
12162 {
12163 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12164 DONE;
12165 }
12166
12167 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12168
12169 operands[2] = gen_reg_rtx (<MODE>mode);
12170 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12171 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12172 })
12173
12174 (define_insn_and_split "ffssi2_no_cmove"
12175 [(set (match_operand:SI 0 "register_operand" "=r")
12176 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12177 (clobber (match_scratch:SI 2 "=&q"))
12178 (clobber (reg:CC FLAGS_REG))]
12179 "!TARGET_CMOVE"
12180 "#"
12181 "&& reload_completed"
12182 [(parallel [(set (match_dup 4) (match_dup 5))
12183 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12184 (set (strict_low_part (match_dup 3))
12185 (eq:QI (match_dup 4) (const_int 0)))
12186 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12187 (clobber (reg:CC FLAGS_REG))])
12188 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12189 (clobber (reg:CC FLAGS_REG))])
12190 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12191 (clobber (reg:CC FLAGS_REG))])]
12192 {
12193 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12194
12195 operands[3] = gen_lowpart (QImode, operands[2]);
12196 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12197 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12198
12199 ix86_expand_clear (operands[2]);
12200 })
12201
12202 (define_insn "*tzcnt<mode>_1"
12203 [(set (reg:CCC FLAGS_REG)
12204 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12205 (const_int 0)))
12206 (set (match_operand:SWI48 0 "register_operand" "=r")
12207 (ctz:SWI48 (match_dup 1)))]
12208 "TARGET_BMI"
12209 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12210 [(set_attr "type" "alu1")
12211 (set_attr "prefix_0f" "1")
12212 (set_attr "prefix_rep" "1")
12213 (set_attr "mode" "<MODE>")])
12214
12215 (define_insn "*bsf<mode>_1"
12216 [(set (reg:CCZ FLAGS_REG)
12217 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12218 (const_int 0)))
12219 (set (match_operand:SWI48 0 "register_operand" "=r")
12220 (ctz:SWI48 (match_dup 1)))]
12221 ""
12222 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12223 [(set_attr "type" "alu1")
12224 (set_attr "prefix_0f" "1")
12225 (set_attr "mode" "<MODE>")])
12226
12227 (define_insn "ctz<mode>2"
12228 [(set (match_operand:SWI248 0 "register_operand" "=r")
12229 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12230 (clobber (reg:CC FLAGS_REG))]
12231 ""
12232 {
12233 if (TARGET_BMI)
12234 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12235 else if (optimize_function_for_size_p (cfun))
12236 ;
12237 else if (TARGET_GENERIC)
12238 /* tzcnt expands to rep;bsf and we can use it even if !TARGET_BMI. */
12239 return "rep; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12240
12241 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12242 }
12243 [(set_attr "type" "alu1")
12244 (set_attr "prefix_0f" "1")
12245 (set (attr "prefix_rep")
12246 (if_then_else
12247 (ior (match_test "TARGET_BMI")
12248 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12249 (match_test "TARGET_GENERIC")))
12250 (const_string "1")
12251 (const_string "0")))
12252 (set_attr "mode" "<MODE>")])
12253
12254 (define_expand "clz<mode>2"
12255 [(parallel
12256 [(set (match_operand:SWI248 0 "register_operand")
12257 (minus:SWI248
12258 (match_dup 2)
12259 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12260 (clobber (reg:CC FLAGS_REG))])
12261 (parallel
12262 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12263 (clobber (reg:CC FLAGS_REG))])]
12264 ""
12265 {
12266 if (TARGET_LZCNT)
12267 {
12268 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12269 DONE;
12270 }
12271 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12272 })
12273
12274 (define_insn "clz<mode>2_lzcnt"
12275 [(set (match_operand:SWI248 0 "register_operand" "=r")
12276 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12277 (clobber (reg:CC FLAGS_REG))]
12278 "TARGET_LZCNT"
12279 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12280 [(set_attr "prefix_rep" "1")
12281 (set_attr "type" "bitmanip")
12282 (set_attr "mode" "<MODE>")])
12283
12284 ;; BMI instructions.
12285 (define_insn "*bmi_andn_<mode>"
12286 [(set (match_operand:SWI48 0 "register_operand" "=r")
12287 (and:SWI48
12288 (not:SWI48
12289 (match_operand:SWI48 1 "register_operand" "r"))
12290 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12291 (clobber (reg:CC FLAGS_REG))]
12292 "TARGET_BMI"
12293 "andn\t{%2, %1, %0|%0, %1, %2}"
12294 [(set_attr "type" "bitmanip")
12295 (set_attr "mode" "<MODE>")])
12296
12297 (define_insn "bmi_bextr_<mode>"
12298 [(set (match_operand:SWI48 0 "register_operand" "=r")
12299 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12300 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12301 UNSPEC_BEXTR))
12302 (clobber (reg:CC FLAGS_REG))]
12303 "TARGET_BMI"
12304 "bextr\t{%2, %1, %0|%0, %1, %2}"
12305 [(set_attr "type" "bitmanip")
12306 (set_attr "mode" "<MODE>")])
12307
12308 (define_insn "*bmi_blsi_<mode>"
12309 [(set (match_operand:SWI48 0 "register_operand" "=r")
12310 (and:SWI48
12311 (neg:SWI48
12312 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12313 (match_dup 1)))
12314 (clobber (reg:CC FLAGS_REG))]
12315 "TARGET_BMI"
12316 "blsi\t{%1, %0|%0, %1}"
12317 [(set_attr "type" "bitmanip")
12318 (set_attr "mode" "<MODE>")])
12319
12320 (define_insn "*bmi_blsmsk_<mode>"
12321 [(set (match_operand:SWI48 0 "register_operand" "=r")
12322 (xor:SWI48
12323 (plus:SWI48
12324 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12325 (const_int -1))
12326 (match_dup 1)))
12327 (clobber (reg:CC FLAGS_REG))]
12328 "TARGET_BMI"
12329 "blsmsk\t{%1, %0|%0, %1}"
12330 [(set_attr "type" "bitmanip")
12331 (set_attr "mode" "<MODE>")])
12332
12333 (define_insn "*bmi_blsr_<mode>"
12334 [(set (match_operand:SWI48 0 "register_operand" "=r")
12335 (and:SWI48
12336 (plus:SWI48
12337 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12338 (const_int -1))
12339 (match_dup 1)))
12340 (clobber (reg:CC FLAGS_REG))]
12341 "TARGET_BMI"
12342 "blsr\t{%1, %0|%0, %1}"
12343 [(set_attr "type" "bitmanip")
12344 (set_attr "mode" "<MODE>")])
12345
12346 ;; BMI2 instructions.
12347 (define_insn "bmi2_bzhi_<mode>3"
12348 [(set (match_operand:SWI48 0 "register_operand" "=r")
12349 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12350 (lshiftrt:SWI48 (const_int -1)
12351 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12352 (clobber (reg:CC FLAGS_REG))]
12353 "TARGET_BMI2"
12354 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12355 [(set_attr "type" "bitmanip")
12356 (set_attr "prefix" "vex")
12357 (set_attr "mode" "<MODE>")])
12358
12359 (define_insn "bmi2_pdep_<mode>3"
12360 [(set (match_operand:SWI48 0 "register_operand" "=r")
12361 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12362 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12363 UNSPEC_PDEP))]
12364 "TARGET_BMI2"
12365 "pdep\t{%2, %1, %0|%0, %1, %2}"
12366 [(set_attr "type" "bitmanip")
12367 (set_attr "prefix" "vex")
12368 (set_attr "mode" "<MODE>")])
12369
12370 (define_insn "bmi2_pext_<mode>3"
12371 [(set (match_operand:SWI48 0 "register_operand" "=r")
12372 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12373 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12374 UNSPEC_PEXT))]
12375 "TARGET_BMI2"
12376 "pext\t{%2, %1, %0|%0, %1, %2}"
12377 [(set_attr "type" "bitmanip")
12378 (set_attr "prefix" "vex")
12379 (set_attr "mode" "<MODE>")])
12380
12381 ;; TBM instructions.
12382 (define_insn "tbm_bextri_<mode>"
12383 [(set (match_operand:SWI48 0 "register_operand" "=r")
12384 (zero_extract:SWI48
12385 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12386 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12387 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12388 (clobber (reg:CC FLAGS_REG))]
12389 "TARGET_TBM"
12390 {
12391 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12392 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12393 }
12394 [(set_attr "type" "bitmanip")
12395 (set_attr "mode" "<MODE>")])
12396
12397 (define_insn "*tbm_blcfill_<mode>"
12398 [(set (match_operand:SWI48 0 "register_operand" "=r")
12399 (and:SWI48
12400 (plus:SWI48
12401 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12402 (const_int 1))
12403 (match_dup 1)))
12404 (clobber (reg:CC FLAGS_REG))]
12405 "TARGET_TBM"
12406 "blcfill\t{%1, %0|%0, %1}"
12407 [(set_attr "type" "bitmanip")
12408 (set_attr "mode" "<MODE>")])
12409
12410 (define_insn "*tbm_blci_<mode>"
12411 [(set (match_operand:SWI48 0 "register_operand" "=r")
12412 (ior:SWI48
12413 (not:SWI48
12414 (plus:SWI48
12415 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12416 (const_int 1)))
12417 (match_dup 1)))
12418 (clobber (reg:CC FLAGS_REG))]
12419 "TARGET_TBM"
12420 "blci\t{%1, %0|%0, %1}"
12421 [(set_attr "type" "bitmanip")
12422 (set_attr "mode" "<MODE>")])
12423
12424 (define_insn "*tbm_blcic_<mode>"
12425 [(set (match_operand:SWI48 0 "register_operand" "=r")
12426 (and:SWI48
12427 (plus:SWI48
12428 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12429 (const_int 1))
12430 (not:SWI48
12431 (match_dup 1))))
12432 (clobber (reg:CC FLAGS_REG))]
12433 "TARGET_TBM"
12434 "blcic\t{%1, %0|%0, %1}"
12435 [(set_attr "type" "bitmanip")
12436 (set_attr "mode" "<MODE>")])
12437
12438 (define_insn "*tbm_blcmsk_<mode>"
12439 [(set (match_operand:SWI48 0 "register_operand" "=r")
12440 (xor:SWI48
12441 (plus:SWI48
12442 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12443 (const_int 1))
12444 (match_dup 1)))
12445 (clobber (reg:CC FLAGS_REG))]
12446 "TARGET_TBM"
12447 "blcmsk\t{%1, %0|%0, %1}"
12448 [(set_attr "type" "bitmanip")
12449 (set_attr "mode" "<MODE>")])
12450
12451 (define_insn "*tbm_blcs_<mode>"
12452 [(set (match_operand:SWI48 0 "register_operand" "=r")
12453 (ior:SWI48
12454 (plus:SWI48
12455 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12456 (const_int 1))
12457 (match_dup 1)))
12458 (clobber (reg:CC FLAGS_REG))]
12459 "TARGET_TBM"
12460 "blcs\t{%1, %0|%0, %1}"
12461 [(set_attr "type" "bitmanip")
12462 (set_attr "mode" "<MODE>")])
12463
12464 (define_insn "*tbm_blsfill_<mode>"
12465 [(set (match_operand:SWI48 0 "register_operand" "=r")
12466 (ior:SWI48
12467 (plus:SWI48
12468 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12469 (const_int -1))
12470 (match_dup 1)))
12471 (clobber (reg:CC FLAGS_REG))]
12472 "TARGET_TBM"
12473 "blsfill\t{%1, %0|%0, %1}"
12474 [(set_attr "type" "bitmanip")
12475 (set_attr "mode" "<MODE>")])
12476
12477 (define_insn "*tbm_blsic_<mode>"
12478 [(set (match_operand:SWI48 0 "register_operand" "=r")
12479 (ior:SWI48
12480 (plus:SWI48
12481 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12482 (const_int -1))
12483 (not:SWI48
12484 (match_dup 1))))
12485 (clobber (reg:CC FLAGS_REG))]
12486 "TARGET_TBM"
12487 "blsic\t{%1, %0|%0, %1}"
12488 [(set_attr "type" "bitmanip")
12489 (set_attr "mode" "<MODE>")])
12490
12491 (define_insn "*tbm_t1mskc_<mode>"
12492 [(set (match_operand:SWI48 0 "register_operand" "=r")
12493 (ior:SWI48
12494 (plus:SWI48
12495 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12496 (const_int 1))
12497 (not:SWI48
12498 (match_dup 1))))
12499 (clobber (reg:CC FLAGS_REG))]
12500 "TARGET_TBM"
12501 "t1mskc\t{%1, %0|%0, %1}"
12502 [(set_attr "type" "bitmanip")
12503 (set_attr "mode" "<MODE>")])
12504
12505 (define_insn "*tbm_tzmsk_<mode>"
12506 [(set (match_operand:SWI48 0 "register_operand" "=r")
12507 (and:SWI48
12508 (plus:SWI48
12509 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12510 (const_int -1))
12511 (not:SWI48
12512 (match_dup 1))))
12513 (clobber (reg:CC FLAGS_REG))]
12514 "TARGET_TBM"
12515 "tzmsk\t{%1, %0|%0, %1}"
12516 [(set_attr "type" "bitmanip")
12517 (set_attr "mode" "<MODE>")])
12518
12519 (define_insn "bsr_rex64"
12520 [(set (match_operand:DI 0 "register_operand" "=r")
12521 (minus:DI (const_int 63)
12522 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12523 (clobber (reg:CC FLAGS_REG))]
12524 "TARGET_64BIT"
12525 "bsr{q}\t{%1, %0|%0, %1}"
12526 [(set_attr "type" "alu1")
12527 (set_attr "prefix_0f" "1")
12528 (set_attr "mode" "DI")])
12529
12530 (define_insn "bsr"
12531 [(set (match_operand:SI 0 "register_operand" "=r")
12532 (minus:SI (const_int 31)
12533 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12534 (clobber (reg:CC FLAGS_REG))]
12535 ""
12536 "bsr{l}\t{%1, %0|%0, %1}"
12537 [(set_attr "type" "alu1")
12538 (set_attr "prefix_0f" "1")
12539 (set_attr "mode" "SI")])
12540
12541 (define_insn "*bsrhi"
12542 [(set (match_operand:HI 0 "register_operand" "=r")
12543 (minus:HI (const_int 15)
12544 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12545 (clobber (reg:CC FLAGS_REG))]
12546 ""
12547 "bsr{w}\t{%1, %0|%0, %1}"
12548 [(set_attr "type" "alu1")
12549 (set_attr "prefix_0f" "1")
12550 (set_attr "mode" "HI")])
12551
12552 (define_insn "popcount<mode>2"
12553 [(set (match_operand:SWI248 0 "register_operand" "=r")
12554 (popcount:SWI248
12555 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12556 (clobber (reg:CC FLAGS_REG))]
12557 "TARGET_POPCNT"
12558 {
12559 #if TARGET_MACHO
12560 return "popcnt\t{%1, %0|%0, %1}";
12561 #else
12562 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12563 #endif
12564 }
12565 [(set_attr "prefix_rep" "1")
12566 (set_attr "type" "bitmanip")
12567 (set_attr "mode" "<MODE>")])
12568
12569 (define_insn "*popcount<mode>2_cmp"
12570 [(set (reg FLAGS_REG)
12571 (compare
12572 (popcount:SWI248
12573 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12574 (const_int 0)))
12575 (set (match_operand:SWI248 0 "register_operand" "=r")
12576 (popcount:SWI248 (match_dup 1)))]
12577 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12578 {
12579 #if TARGET_MACHO
12580 return "popcnt\t{%1, %0|%0, %1}";
12581 #else
12582 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12583 #endif
12584 }
12585 [(set_attr "prefix_rep" "1")
12586 (set_attr "type" "bitmanip")
12587 (set_attr "mode" "<MODE>")])
12588
12589 (define_insn "*popcountsi2_cmp_zext"
12590 [(set (reg FLAGS_REG)
12591 (compare
12592 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12593 (const_int 0)))
12594 (set (match_operand:DI 0 "register_operand" "=r")
12595 (zero_extend:DI(popcount:SI (match_dup 1))))]
12596 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12597 {
12598 #if TARGET_MACHO
12599 return "popcnt\t{%1, %0|%0, %1}";
12600 #else
12601 return "popcnt{l}\t{%1, %0|%0, %1}";
12602 #endif
12603 }
12604 [(set_attr "prefix_rep" "1")
12605 (set_attr "type" "bitmanip")
12606 (set_attr "mode" "SI")])
12607
12608 (define_expand "bswapdi2"
12609 [(set (match_operand:DI 0 "register_operand")
12610 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12611 ""
12612 {
12613 if (TARGET_64BIT && !TARGET_MOVBE)
12614 operands[1] = force_reg (DImode, operands[1]);
12615 })
12616
12617 (define_insn_and_split "*bswapdi2_doubleword"
12618 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12619 (bswap:DI
12620 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12621 "!TARGET_64BIT
12622 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12623 "#"
12624 "&& reload_completed"
12625 [(set (match_dup 2)
12626 (bswap:SI (match_dup 1)))
12627 (set (match_dup 0)
12628 (bswap:SI (match_dup 3)))]
12629 {
12630 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12631
12632 if (REG_P (operands[0]) && REG_P (operands[1]))
12633 {
12634 emit_insn (gen_swapsi (operands[0], operands[2]));
12635 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12636 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12637 DONE;
12638 }
12639
12640 if (!TARGET_MOVBE)
12641 {
12642 if (MEM_P (operands[0]))
12643 {
12644 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12645 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12646
12647 emit_move_insn (operands[0], operands[3]);
12648 emit_move_insn (operands[2], operands[1]);
12649 }
12650 if (MEM_P (operands[1]))
12651 {
12652 emit_move_insn (operands[2], operands[1]);
12653 emit_move_insn (operands[0], operands[3]);
12654
12655 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12656 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12657 }
12658 DONE;
12659 }
12660 })
12661
12662 (define_expand "bswapsi2"
12663 [(set (match_operand:SI 0 "register_operand")
12664 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12665 ""
12666 {
12667 if (TARGET_MOVBE)
12668 ;
12669 else if (TARGET_BSWAP)
12670 operands[1] = force_reg (SImode, operands[1]);
12671 else
12672 {
12673 rtx x = operands[0];
12674
12675 emit_move_insn (x, operands[1]);
12676 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12677 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12678 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12679 DONE;
12680 }
12681 })
12682
12683 (define_insn "*bswap<mode>2_movbe"
12684 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12685 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12686 "TARGET_MOVBE
12687 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12688 "@
12689 bswap\t%0
12690 movbe\t{%1, %0|%0, %1}
12691 movbe\t{%1, %0|%0, %1}"
12692 [(set_attr "type" "bitmanip,imov,imov")
12693 (set_attr "modrm" "0,1,1")
12694 (set_attr "prefix_0f" "*,1,1")
12695 (set_attr "prefix_extra" "*,1,1")
12696 (set_attr "mode" "<MODE>")])
12697
12698 (define_insn "*bswap<mode>2"
12699 [(set (match_operand:SWI48 0 "register_operand" "=r")
12700 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12701 "TARGET_BSWAP"
12702 "bswap\t%0"
12703 [(set_attr "type" "bitmanip")
12704 (set_attr "modrm" "0")
12705 (set_attr "mode" "<MODE>")])
12706
12707 (define_insn "*bswaphi_lowpart_1"
12708 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12709 (bswap:HI (match_dup 0)))
12710 (clobber (reg:CC FLAGS_REG))]
12711 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12712 "@
12713 xchg{b}\t{%h0, %b0|%b0, %h0}
12714 rol{w}\t{$8, %0|%0, 8}"
12715 [(set_attr "length" "2,4")
12716 (set_attr "mode" "QI,HI")])
12717
12718 (define_insn "bswaphi_lowpart"
12719 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12720 (bswap:HI (match_dup 0)))
12721 (clobber (reg:CC FLAGS_REG))]
12722 ""
12723 "rol{w}\t{$8, %0|%0, 8}"
12724 [(set_attr "length" "4")
12725 (set_attr "mode" "HI")])
12726
12727 (define_expand "paritydi2"
12728 [(set (match_operand:DI 0 "register_operand")
12729 (parity:DI (match_operand:DI 1 "register_operand")))]
12730 "! TARGET_POPCNT"
12731 {
12732 rtx scratch = gen_reg_rtx (QImode);
12733 rtx cond;
12734
12735 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12736 NULL_RTX, operands[1]));
12737
12738 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12739 gen_rtx_REG (CCmode, FLAGS_REG),
12740 const0_rtx);
12741 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12742
12743 if (TARGET_64BIT)
12744 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12745 else
12746 {
12747 rtx tmp = gen_reg_rtx (SImode);
12748
12749 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12750 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12751 }
12752 DONE;
12753 })
12754
12755 (define_expand "paritysi2"
12756 [(set (match_operand:SI 0 "register_operand")
12757 (parity:SI (match_operand:SI 1 "register_operand")))]
12758 "! TARGET_POPCNT"
12759 {
12760 rtx scratch = gen_reg_rtx (QImode);
12761 rtx cond;
12762
12763 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12764
12765 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12766 gen_rtx_REG (CCmode, FLAGS_REG),
12767 const0_rtx);
12768 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12769
12770 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12771 DONE;
12772 })
12773
12774 (define_insn_and_split "paritydi2_cmp"
12775 [(set (reg:CC FLAGS_REG)
12776 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12777 UNSPEC_PARITY))
12778 (clobber (match_scratch:DI 0 "=r"))
12779 (clobber (match_scratch:SI 1 "=&r"))
12780 (clobber (match_scratch:HI 2 "=Q"))]
12781 "! TARGET_POPCNT"
12782 "#"
12783 "&& reload_completed"
12784 [(parallel
12785 [(set (match_dup 1)
12786 (xor:SI (match_dup 1) (match_dup 4)))
12787 (clobber (reg:CC FLAGS_REG))])
12788 (parallel
12789 [(set (reg:CC FLAGS_REG)
12790 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12791 (clobber (match_dup 1))
12792 (clobber (match_dup 2))])]
12793 {
12794 operands[4] = gen_lowpart (SImode, operands[3]);
12795
12796 if (TARGET_64BIT)
12797 {
12798 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12799 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12800 }
12801 else
12802 operands[1] = gen_highpart (SImode, operands[3]);
12803 })
12804
12805 (define_insn_and_split "paritysi2_cmp"
12806 [(set (reg:CC FLAGS_REG)
12807 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12808 UNSPEC_PARITY))
12809 (clobber (match_scratch:SI 0 "=r"))
12810 (clobber (match_scratch:HI 1 "=&Q"))]
12811 "! TARGET_POPCNT"
12812 "#"
12813 "&& reload_completed"
12814 [(parallel
12815 [(set (match_dup 1)
12816 (xor:HI (match_dup 1) (match_dup 3)))
12817 (clobber (reg:CC FLAGS_REG))])
12818 (parallel
12819 [(set (reg:CC FLAGS_REG)
12820 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12821 (clobber (match_dup 1))])]
12822 {
12823 operands[3] = gen_lowpart (HImode, operands[2]);
12824
12825 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12826 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12827 })
12828
12829 (define_insn "*parityhi2_cmp"
12830 [(set (reg:CC FLAGS_REG)
12831 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12832 UNSPEC_PARITY))
12833 (clobber (match_scratch:HI 0 "=Q"))]
12834 "! TARGET_POPCNT"
12835 "xor{b}\t{%h0, %b0|%b0, %h0}"
12836 [(set_attr "length" "2")
12837 (set_attr "mode" "HI")])
12838
12839 \f
12840 ;; Thread-local storage patterns for ELF.
12841 ;;
12842 ;; Note that these code sequences must appear exactly as shown
12843 ;; in order to allow linker relaxation.
12844
12845 (define_insn "*tls_global_dynamic_32_gnu"
12846 [(set (match_operand:SI 0 "register_operand" "=a")
12847 (unspec:SI
12848 [(match_operand:SI 1 "register_operand" "b")
12849 (match_operand 2 "tls_symbolic_operand")
12850 (match_operand 3 "constant_call_address_operand" "z")]
12851 UNSPEC_TLS_GD))
12852 (clobber (match_scratch:SI 4 "=d"))
12853 (clobber (match_scratch:SI 5 "=c"))
12854 (clobber (reg:CC FLAGS_REG))]
12855 "!TARGET_64BIT && TARGET_GNU_TLS"
12856 {
12857 output_asm_insn
12858 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12859 if (TARGET_SUN_TLS)
12860 #ifdef HAVE_AS_IX86_TLSGDPLT
12861 return "call\t%a2@tlsgdplt";
12862 #else
12863 return "call\t%p3@plt";
12864 #endif
12865 return "call\t%P3";
12866 }
12867 [(set_attr "type" "multi")
12868 (set_attr "length" "12")])
12869
12870 (define_expand "tls_global_dynamic_32"
12871 [(parallel
12872 [(set (match_operand:SI 0 "register_operand")
12873 (unspec:SI [(match_operand:SI 2 "register_operand")
12874 (match_operand 1 "tls_symbolic_operand")
12875 (match_operand 3 "constant_call_address_operand")]
12876 UNSPEC_TLS_GD))
12877 (clobber (match_scratch:SI 4))
12878 (clobber (match_scratch:SI 5))
12879 (clobber (reg:CC FLAGS_REG))])])
12880
12881 (define_insn "*tls_global_dynamic_64_<mode>"
12882 [(set (match_operand:P 0 "register_operand" "=a")
12883 (call:P
12884 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12885 (match_operand 3)))
12886 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12887 UNSPEC_TLS_GD)]
12888 "TARGET_64BIT"
12889 {
12890 if (!TARGET_X32)
12891 fputs (ASM_BYTE "0x66\n", asm_out_file);
12892 output_asm_insn
12893 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12894 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12895 fputs ("\trex64\n", asm_out_file);
12896 if (TARGET_SUN_TLS)
12897 return "call\t%p2@plt";
12898 return "call\t%P2";
12899 }
12900 [(set_attr "type" "multi")
12901 (set (attr "length")
12902 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12903
12904 (define_expand "tls_global_dynamic_64_<mode>"
12905 [(parallel
12906 [(set (match_operand:P 0 "register_operand")
12907 (call:P
12908 (mem:QI (match_operand 2 "constant_call_address_operand"))
12909 (const_int 0)))
12910 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12911 UNSPEC_TLS_GD)])]
12912 "TARGET_64BIT")
12913
12914 (define_insn "*tls_local_dynamic_base_32_gnu"
12915 [(set (match_operand:SI 0 "register_operand" "=a")
12916 (unspec:SI
12917 [(match_operand:SI 1 "register_operand" "b")
12918 (match_operand 2 "constant_call_address_operand" "z")]
12919 UNSPEC_TLS_LD_BASE))
12920 (clobber (match_scratch:SI 3 "=d"))
12921 (clobber (match_scratch:SI 4 "=c"))
12922 (clobber (reg:CC FLAGS_REG))]
12923 "!TARGET_64BIT && TARGET_GNU_TLS"
12924 {
12925 output_asm_insn
12926 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12927 if (TARGET_SUN_TLS)
12928 #ifdef HAVE_AS_IX86_TLSLDMPLT
12929 return "call\t%&@tlsldmplt";
12930 #else
12931 return "call\t%p2@plt";
12932 #endif
12933 return "call\t%P2";
12934 }
12935 [(set_attr "type" "multi")
12936 (set_attr "length" "11")])
12937
12938 (define_expand "tls_local_dynamic_base_32"
12939 [(parallel
12940 [(set (match_operand:SI 0 "register_operand")
12941 (unspec:SI
12942 [(match_operand:SI 1 "register_operand")
12943 (match_operand 2 "constant_call_address_operand")]
12944 UNSPEC_TLS_LD_BASE))
12945 (clobber (match_scratch:SI 3))
12946 (clobber (match_scratch:SI 4))
12947 (clobber (reg:CC FLAGS_REG))])])
12948
12949 (define_insn "*tls_local_dynamic_base_64_<mode>"
12950 [(set (match_operand:P 0 "register_operand" "=a")
12951 (call:P
12952 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12953 (match_operand 2)))
12954 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12955 "TARGET_64BIT"
12956 {
12957 output_asm_insn
12958 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12959 if (TARGET_SUN_TLS)
12960 return "call\t%p1@plt";
12961 return "call\t%P1";
12962 }
12963 [(set_attr "type" "multi")
12964 (set_attr "length" "12")])
12965
12966 (define_expand "tls_local_dynamic_base_64_<mode>"
12967 [(parallel
12968 [(set (match_operand:P 0 "register_operand")
12969 (call:P
12970 (mem:QI (match_operand 1 "constant_call_address_operand"))
12971 (const_int 0)))
12972 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12973 "TARGET_64BIT")
12974
12975 ;; Local dynamic of a single variable is a lose. Show combine how
12976 ;; to convert that back to global dynamic.
12977
12978 (define_insn_and_split "*tls_local_dynamic_32_once"
12979 [(set (match_operand:SI 0 "register_operand" "=a")
12980 (plus:SI
12981 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12982 (match_operand 2 "constant_call_address_operand" "z")]
12983 UNSPEC_TLS_LD_BASE)
12984 (const:SI (unspec:SI
12985 [(match_operand 3 "tls_symbolic_operand")]
12986 UNSPEC_DTPOFF))))
12987 (clobber (match_scratch:SI 4 "=d"))
12988 (clobber (match_scratch:SI 5 "=c"))
12989 (clobber (reg:CC FLAGS_REG))]
12990 ""
12991 "#"
12992 ""
12993 [(parallel
12994 [(set (match_dup 0)
12995 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12996 UNSPEC_TLS_GD))
12997 (clobber (match_dup 4))
12998 (clobber (match_dup 5))
12999 (clobber (reg:CC FLAGS_REG))])])
13000
13001 ;; Segment register for the thread base ptr load
13002 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13003
13004 ;; Load and add the thread base pointer from %<tp_seg>:0.
13005 (define_insn "*load_tp_x32"
13006 [(set (match_operand:SI 0 "register_operand" "=r")
13007 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13008 "TARGET_X32"
13009 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13010 [(set_attr "type" "imov")
13011 (set_attr "modrm" "0")
13012 (set_attr "length" "7")
13013 (set_attr "memory" "load")
13014 (set_attr "imm_disp" "false")])
13015
13016 (define_insn "*load_tp_x32_zext"
13017 [(set (match_operand:DI 0 "register_operand" "=r")
13018 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13019 "TARGET_X32"
13020 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13021 [(set_attr "type" "imov")
13022 (set_attr "modrm" "0")
13023 (set_attr "length" "7")
13024 (set_attr "memory" "load")
13025 (set_attr "imm_disp" "false")])
13026
13027 (define_insn "*load_tp_<mode>"
13028 [(set (match_operand:P 0 "register_operand" "=r")
13029 (unspec:P [(const_int 0)] UNSPEC_TP))]
13030 "!TARGET_X32"
13031 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13032 [(set_attr "type" "imov")
13033 (set_attr "modrm" "0")
13034 (set_attr "length" "7")
13035 (set_attr "memory" "load")
13036 (set_attr "imm_disp" "false")])
13037
13038 (define_insn "*add_tp_x32"
13039 [(set (match_operand:SI 0 "register_operand" "=r")
13040 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13041 (match_operand:SI 1 "register_operand" "0")))
13042 (clobber (reg:CC FLAGS_REG))]
13043 "TARGET_X32"
13044 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13045 [(set_attr "type" "alu")
13046 (set_attr "modrm" "0")
13047 (set_attr "length" "7")
13048 (set_attr "memory" "load")
13049 (set_attr "imm_disp" "false")])
13050
13051 (define_insn "*add_tp_x32_zext"
13052 [(set (match_operand:DI 0 "register_operand" "=r")
13053 (zero_extend:DI
13054 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13055 (match_operand:SI 1 "register_operand" "0"))))
13056 (clobber (reg:CC FLAGS_REG))]
13057 "TARGET_X32"
13058 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13059 [(set_attr "type" "alu")
13060 (set_attr "modrm" "0")
13061 (set_attr "length" "7")
13062 (set_attr "memory" "load")
13063 (set_attr "imm_disp" "false")])
13064
13065 (define_insn "*add_tp_<mode>"
13066 [(set (match_operand:P 0 "register_operand" "=r")
13067 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13068 (match_operand:P 1 "register_operand" "0")))
13069 (clobber (reg:CC FLAGS_REG))]
13070 "!TARGET_X32"
13071 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13072 [(set_attr "type" "alu")
13073 (set_attr "modrm" "0")
13074 (set_attr "length" "7")
13075 (set_attr "memory" "load")
13076 (set_attr "imm_disp" "false")])
13077
13078 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13079 ;; %rax as destination of the initial executable code sequence.
13080 (define_insn "tls_initial_exec_64_sun"
13081 [(set (match_operand:DI 0 "register_operand" "=a")
13082 (unspec:DI
13083 [(match_operand 1 "tls_symbolic_operand")]
13084 UNSPEC_TLS_IE_SUN))
13085 (clobber (reg:CC FLAGS_REG))]
13086 "TARGET_64BIT && TARGET_SUN_TLS"
13087 {
13088 output_asm_insn
13089 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13090 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13091 }
13092 [(set_attr "type" "multi")])
13093
13094 ;; GNU2 TLS patterns can be split.
13095
13096 (define_expand "tls_dynamic_gnu2_32"
13097 [(set (match_dup 3)
13098 (plus:SI (match_operand:SI 2 "register_operand")
13099 (const:SI
13100 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13101 UNSPEC_TLSDESC))))
13102 (parallel
13103 [(set (match_operand:SI 0 "register_operand")
13104 (unspec:SI [(match_dup 1) (match_dup 3)
13105 (match_dup 2) (reg:SI SP_REG)]
13106 UNSPEC_TLSDESC))
13107 (clobber (reg:CC FLAGS_REG))])]
13108 "!TARGET_64BIT && TARGET_GNU2_TLS"
13109 {
13110 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13111 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13112 })
13113
13114 (define_insn "*tls_dynamic_gnu2_lea_32"
13115 [(set (match_operand:SI 0 "register_operand" "=r")
13116 (plus:SI (match_operand:SI 1 "register_operand" "b")
13117 (const:SI
13118 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13119 UNSPEC_TLSDESC))))]
13120 "!TARGET_64BIT && TARGET_GNU2_TLS"
13121 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13122 [(set_attr "type" "lea")
13123 (set_attr "mode" "SI")
13124 (set_attr "length" "6")
13125 (set_attr "length_address" "4")])
13126
13127 (define_insn "*tls_dynamic_gnu2_call_32"
13128 [(set (match_operand:SI 0 "register_operand" "=a")
13129 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13130 (match_operand:SI 2 "register_operand" "0")
13131 ;; we have to make sure %ebx still points to the GOT
13132 (match_operand:SI 3 "register_operand" "b")
13133 (reg:SI SP_REG)]
13134 UNSPEC_TLSDESC))
13135 (clobber (reg:CC FLAGS_REG))]
13136 "!TARGET_64BIT && TARGET_GNU2_TLS"
13137 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13138 [(set_attr "type" "call")
13139 (set_attr "length" "2")
13140 (set_attr "length_address" "0")])
13141
13142 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13143 [(set (match_operand:SI 0 "register_operand" "=&a")
13144 (plus:SI
13145 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13146 (match_operand:SI 4)
13147 (match_operand:SI 2 "register_operand" "b")
13148 (reg:SI SP_REG)]
13149 UNSPEC_TLSDESC)
13150 (const:SI (unspec:SI
13151 [(match_operand 1 "tls_symbolic_operand")]
13152 UNSPEC_DTPOFF))))
13153 (clobber (reg:CC FLAGS_REG))]
13154 "!TARGET_64BIT && TARGET_GNU2_TLS"
13155 "#"
13156 ""
13157 [(set (match_dup 0) (match_dup 5))]
13158 {
13159 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13160 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13161 })
13162
13163 (define_expand "tls_dynamic_gnu2_64"
13164 [(set (match_dup 2)
13165 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13166 UNSPEC_TLSDESC))
13167 (parallel
13168 [(set (match_operand:DI 0 "register_operand")
13169 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13170 UNSPEC_TLSDESC))
13171 (clobber (reg:CC FLAGS_REG))])]
13172 "TARGET_64BIT && TARGET_GNU2_TLS"
13173 {
13174 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13175 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13176 })
13177
13178 (define_insn "*tls_dynamic_gnu2_lea_64"
13179 [(set (match_operand:DI 0 "register_operand" "=r")
13180 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13181 UNSPEC_TLSDESC))]
13182 "TARGET_64BIT && TARGET_GNU2_TLS"
13183 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13184 [(set_attr "type" "lea")
13185 (set_attr "mode" "DI")
13186 (set_attr "length" "7")
13187 (set_attr "length_address" "4")])
13188
13189 (define_insn "*tls_dynamic_gnu2_call_64"
13190 [(set (match_operand:DI 0 "register_operand" "=a")
13191 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13192 (match_operand:DI 2 "register_operand" "0")
13193 (reg:DI SP_REG)]
13194 UNSPEC_TLSDESC))
13195 (clobber (reg:CC FLAGS_REG))]
13196 "TARGET_64BIT && TARGET_GNU2_TLS"
13197 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13198 [(set_attr "type" "call")
13199 (set_attr "length" "2")
13200 (set_attr "length_address" "0")])
13201
13202 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13203 [(set (match_operand:DI 0 "register_operand" "=&a")
13204 (plus:DI
13205 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13206 (match_operand:DI 3)
13207 (reg:DI SP_REG)]
13208 UNSPEC_TLSDESC)
13209 (const:DI (unspec:DI
13210 [(match_operand 1 "tls_symbolic_operand")]
13211 UNSPEC_DTPOFF))))
13212 (clobber (reg:CC FLAGS_REG))]
13213 "TARGET_64BIT && TARGET_GNU2_TLS"
13214 "#"
13215 ""
13216 [(set (match_dup 0) (match_dup 4))]
13217 {
13218 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13219 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13220 })
13221 \f
13222 ;; These patterns match the binary 387 instructions for addM3, subM3,
13223 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13224 ;; SFmode. The first is the normal insn, the second the same insn but
13225 ;; with one operand a conversion, and the third the same insn but with
13226 ;; the other operand a conversion. The conversion may be SFmode or
13227 ;; SImode if the target mode DFmode, but only SImode if the target mode
13228 ;; is SFmode.
13229
13230 ;; Gcc is slightly more smart about handling normal two address instructions
13231 ;; so use special patterns for add and mull.
13232
13233 (define_insn "*fop_<mode>_comm_mixed"
13234 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13235 (match_operator:MODEF 3 "binary_fp_operator"
13236 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13237 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13238 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13239 && COMMUTATIVE_ARITH_P (operands[3])
13240 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13241 "* return output_387_binary_op (insn, operands);"
13242 [(set (attr "type")
13243 (if_then_else (eq_attr "alternative" "1,2")
13244 (if_then_else (match_operand:MODEF 3 "mult_operator")
13245 (const_string "ssemul")
13246 (const_string "sseadd"))
13247 (if_then_else (match_operand:MODEF 3 "mult_operator")
13248 (const_string "fmul")
13249 (const_string "fop"))))
13250 (set_attr "isa" "*,noavx,avx")
13251 (set_attr "prefix" "orig,orig,vex")
13252 (set_attr "mode" "<MODE>")])
13253
13254 (define_insn "*fop_<mode>_comm_sse"
13255 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13256 (match_operator:MODEF 3 "binary_fp_operator"
13257 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13258 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13259 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13260 && COMMUTATIVE_ARITH_P (operands[3])
13261 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13262 "* return output_387_binary_op (insn, operands);"
13263 [(set (attr "type")
13264 (if_then_else (match_operand:MODEF 3 "mult_operator")
13265 (const_string "ssemul")
13266 (const_string "sseadd")))
13267 (set_attr "isa" "noavx,avx")
13268 (set_attr "prefix" "orig,vex")
13269 (set_attr "mode" "<MODE>")])
13270
13271 (define_insn "*fop_<mode>_comm_i387"
13272 [(set (match_operand:MODEF 0 "register_operand" "=f")
13273 (match_operator:MODEF 3 "binary_fp_operator"
13274 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13275 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13276 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13277 && COMMUTATIVE_ARITH_P (operands[3])
13278 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13279 "* return output_387_binary_op (insn, operands);"
13280 [(set (attr "type")
13281 (if_then_else (match_operand:MODEF 3 "mult_operator")
13282 (const_string "fmul")
13283 (const_string "fop")))
13284 (set_attr "mode" "<MODE>")])
13285
13286 (define_insn "*fop_<mode>_1_mixed"
13287 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13288 (match_operator:MODEF 3 "binary_fp_operator"
13289 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13290 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13291 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13292 && !COMMUTATIVE_ARITH_P (operands[3])
13293 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13294 "* return output_387_binary_op (insn, operands);"
13295 [(set (attr "type")
13296 (cond [(and (eq_attr "alternative" "2,3")
13297 (match_operand:MODEF 3 "mult_operator"))
13298 (const_string "ssemul")
13299 (and (eq_attr "alternative" "2,3")
13300 (match_operand:MODEF 3 "div_operator"))
13301 (const_string "ssediv")
13302 (eq_attr "alternative" "2,3")
13303 (const_string "sseadd")
13304 (match_operand:MODEF 3 "mult_operator")
13305 (const_string "fmul")
13306 (match_operand:MODEF 3 "div_operator")
13307 (const_string "fdiv")
13308 ]
13309 (const_string "fop")))
13310 (set_attr "isa" "*,*,noavx,avx")
13311 (set_attr "prefix" "orig,orig,orig,vex")
13312 (set_attr "mode" "<MODE>")])
13313
13314 (define_insn "*rcpsf2_sse"
13315 [(set (match_operand:SF 0 "register_operand" "=x")
13316 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13317 UNSPEC_RCP))]
13318 "TARGET_SSE_MATH"
13319 "%vrcpss\t{%1, %d0|%d0, %1}"
13320 [(set_attr "type" "sse")
13321 (set_attr "atom_sse_attr" "rcp")
13322 (set_attr "prefix" "maybe_vex")
13323 (set_attr "mode" "SF")])
13324
13325 (define_insn "*fop_<mode>_1_sse"
13326 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13327 (match_operator:MODEF 3 "binary_fp_operator"
13328 [(match_operand:MODEF 1 "register_operand" "0,x")
13329 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13330 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13331 && !COMMUTATIVE_ARITH_P (operands[3])"
13332 "* return output_387_binary_op (insn, operands);"
13333 [(set (attr "type")
13334 (cond [(match_operand:MODEF 3 "mult_operator")
13335 (const_string "ssemul")
13336 (match_operand:MODEF 3 "div_operator")
13337 (const_string "ssediv")
13338 ]
13339 (const_string "sseadd")))
13340 (set_attr "isa" "noavx,avx")
13341 (set_attr "prefix" "orig,vex")
13342 (set_attr "mode" "<MODE>")])
13343
13344 ;; This pattern is not fully shadowed by the pattern above.
13345 (define_insn "*fop_<mode>_1_i387"
13346 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13347 (match_operator:MODEF 3 "binary_fp_operator"
13348 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13349 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13350 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13351 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13352 && !COMMUTATIVE_ARITH_P (operands[3])
13353 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13354 "* return output_387_binary_op (insn, operands);"
13355 [(set (attr "type")
13356 (cond [(match_operand:MODEF 3 "mult_operator")
13357 (const_string "fmul")
13358 (match_operand:MODEF 3 "div_operator")
13359 (const_string "fdiv")
13360 ]
13361 (const_string "fop")))
13362 (set_attr "mode" "<MODE>")])
13363
13364 ;; ??? Add SSE splitters for these!
13365 (define_insn "*fop_<MODEF:mode>_2_i387"
13366 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13367 (match_operator:MODEF 3 "binary_fp_operator"
13368 [(float:MODEF
13369 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13370 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13371 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13372 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13373 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13374 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13375 [(set (attr "type")
13376 (cond [(match_operand:MODEF 3 "mult_operator")
13377 (const_string "fmul")
13378 (match_operand:MODEF 3 "div_operator")
13379 (const_string "fdiv")
13380 ]
13381 (const_string "fop")))
13382 (set_attr "fp_int_src" "true")
13383 (set_attr "mode" "<SWI24:MODE>")])
13384
13385 (define_insn "*fop_<MODEF:mode>_3_i387"
13386 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13387 (match_operator:MODEF 3 "binary_fp_operator"
13388 [(match_operand:MODEF 1 "register_operand" "0,0")
13389 (float:MODEF
13390 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13391 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13392 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13393 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13394 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13395 [(set (attr "type")
13396 (cond [(match_operand:MODEF 3 "mult_operator")
13397 (const_string "fmul")
13398 (match_operand:MODEF 3 "div_operator")
13399 (const_string "fdiv")
13400 ]
13401 (const_string "fop")))
13402 (set_attr "fp_int_src" "true")
13403 (set_attr "mode" "<MODE>")])
13404
13405 (define_insn "*fop_df_4_i387"
13406 [(set (match_operand:DF 0 "register_operand" "=f,f")
13407 (match_operator:DF 3 "binary_fp_operator"
13408 [(float_extend:DF
13409 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13410 (match_operand:DF 2 "register_operand" "0,f")]))]
13411 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13412 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13413 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13414 "* return output_387_binary_op (insn, operands);"
13415 [(set (attr "type")
13416 (cond [(match_operand:DF 3 "mult_operator")
13417 (const_string "fmul")
13418 (match_operand:DF 3 "div_operator")
13419 (const_string "fdiv")
13420 ]
13421 (const_string "fop")))
13422 (set_attr "mode" "SF")])
13423
13424 (define_insn "*fop_df_5_i387"
13425 [(set (match_operand:DF 0 "register_operand" "=f,f")
13426 (match_operator:DF 3 "binary_fp_operator"
13427 [(match_operand:DF 1 "register_operand" "0,f")
13428 (float_extend:DF
13429 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13430 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13431 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13432 "* return output_387_binary_op (insn, operands);"
13433 [(set (attr "type")
13434 (cond [(match_operand:DF 3 "mult_operator")
13435 (const_string "fmul")
13436 (match_operand:DF 3 "div_operator")
13437 (const_string "fdiv")
13438 ]
13439 (const_string "fop")))
13440 (set_attr "mode" "SF")])
13441
13442 (define_insn "*fop_df_6_i387"
13443 [(set (match_operand:DF 0 "register_operand" "=f,f")
13444 (match_operator:DF 3 "binary_fp_operator"
13445 [(float_extend:DF
13446 (match_operand:SF 1 "register_operand" "0,f"))
13447 (float_extend:DF
13448 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13449 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13450 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13451 "* return output_387_binary_op (insn, operands);"
13452 [(set (attr "type")
13453 (cond [(match_operand:DF 3 "mult_operator")
13454 (const_string "fmul")
13455 (match_operand:DF 3 "div_operator")
13456 (const_string "fdiv")
13457 ]
13458 (const_string "fop")))
13459 (set_attr "mode" "SF")])
13460
13461 (define_insn "*fop_xf_comm_i387"
13462 [(set (match_operand:XF 0 "register_operand" "=f")
13463 (match_operator:XF 3 "binary_fp_operator"
13464 [(match_operand:XF 1 "register_operand" "%0")
13465 (match_operand:XF 2 "register_operand" "f")]))]
13466 "TARGET_80387
13467 && COMMUTATIVE_ARITH_P (operands[3])"
13468 "* return output_387_binary_op (insn, operands);"
13469 [(set (attr "type")
13470 (if_then_else (match_operand:XF 3 "mult_operator")
13471 (const_string "fmul")
13472 (const_string "fop")))
13473 (set_attr "mode" "XF")])
13474
13475 (define_insn "*fop_xf_1_i387"
13476 [(set (match_operand:XF 0 "register_operand" "=f,f")
13477 (match_operator:XF 3 "binary_fp_operator"
13478 [(match_operand:XF 1 "register_operand" "0,f")
13479 (match_operand:XF 2 "register_operand" "f,0")]))]
13480 "TARGET_80387
13481 && !COMMUTATIVE_ARITH_P (operands[3])"
13482 "* return output_387_binary_op (insn, operands);"
13483 [(set (attr "type")
13484 (cond [(match_operand:XF 3 "mult_operator")
13485 (const_string "fmul")
13486 (match_operand:XF 3 "div_operator")
13487 (const_string "fdiv")
13488 ]
13489 (const_string "fop")))
13490 (set_attr "mode" "XF")])
13491
13492 (define_insn "*fop_xf_2_i387"
13493 [(set (match_operand:XF 0 "register_operand" "=f,f")
13494 (match_operator:XF 3 "binary_fp_operator"
13495 [(float:XF
13496 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13497 (match_operand:XF 2 "register_operand" "0,0")]))]
13498 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13499 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13500 [(set (attr "type")
13501 (cond [(match_operand:XF 3 "mult_operator")
13502 (const_string "fmul")
13503 (match_operand:XF 3 "div_operator")
13504 (const_string "fdiv")
13505 ]
13506 (const_string "fop")))
13507 (set_attr "fp_int_src" "true")
13508 (set_attr "mode" "<MODE>")])
13509
13510 (define_insn "*fop_xf_3_i387"
13511 [(set (match_operand:XF 0 "register_operand" "=f,f")
13512 (match_operator:XF 3 "binary_fp_operator"
13513 [(match_operand:XF 1 "register_operand" "0,0")
13514 (float:XF
13515 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13516 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13517 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13518 [(set (attr "type")
13519 (cond [(match_operand:XF 3 "mult_operator")
13520 (const_string "fmul")
13521 (match_operand:XF 3 "div_operator")
13522 (const_string "fdiv")
13523 ]
13524 (const_string "fop")))
13525 (set_attr "fp_int_src" "true")
13526 (set_attr "mode" "<MODE>")])
13527
13528 (define_insn "*fop_xf_4_i387"
13529 [(set (match_operand:XF 0 "register_operand" "=f,f")
13530 (match_operator:XF 3 "binary_fp_operator"
13531 [(float_extend:XF
13532 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13533 (match_operand:XF 2 "register_operand" "0,f")]))]
13534 "TARGET_80387"
13535 "* return output_387_binary_op (insn, operands);"
13536 [(set (attr "type")
13537 (cond [(match_operand:XF 3 "mult_operator")
13538 (const_string "fmul")
13539 (match_operand:XF 3 "div_operator")
13540 (const_string "fdiv")
13541 ]
13542 (const_string "fop")))
13543 (set_attr "mode" "<MODE>")])
13544
13545 (define_insn "*fop_xf_5_i387"
13546 [(set (match_operand:XF 0 "register_operand" "=f,f")
13547 (match_operator:XF 3 "binary_fp_operator"
13548 [(match_operand:XF 1 "register_operand" "0,f")
13549 (float_extend:XF
13550 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13551 "TARGET_80387"
13552 "* return output_387_binary_op (insn, operands);"
13553 [(set (attr "type")
13554 (cond [(match_operand:XF 3 "mult_operator")
13555 (const_string "fmul")
13556 (match_operand:XF 3 "div_operator")
13557 (const_string "fdiv")
13558 ]
13559 (const_string "fop")))
13560 (set_attr "mode" "<MODE>")])
13561
13562 (define_insn "*fop_xf_6_i387"
13563 [(set (match_operand:XF 0 "register_operand" "=f,f")
13564 (match_operator:XF 3 "binary_fp_operator"
13565 [(float_extend:XF
13566 (match_operand:MODEF 1 "register_operand" "0,f"))
13567 (float_extend:XF
13568 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13569 "TARGET_80387"
13570 "* return output_387_binary_op (insn, operands);"
13571 [(set (attr "type")
13572 (cond [(match_operand:XF 3 "mult_operator")
13573 (const_string "fmul")
13574 (match_operand:XF 3 "div_operator")
13575 (const_string "fdiv")
13576 ]
13577 (const_string "fop")))
13578 (set_attr "mode" "<MODE>")])
13579
13580 (define_split
13581 [(set (match_operand 0 "register_operand")
13582 (match_operator 3 "binary_fp_operator"
13583 [(float (match_operand:SWI24 1 "register_operand"))
13584 (match_operand 2 "register_operand")]))]
13585 "reload_completed
13586 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13587 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13588 [(const_int 0)]
13589 {
13590 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13591 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13592 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13593 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13594 GET_MODE (operands[3]),
13595 operands[4],
13596 operands[2])));
13597 ix86_free_from_memory (GET_MODE (operands[1]));
13598 DONE;
13599 })
13600
13601 (define_split
13602 [(set (match_operand 0 "register_operand")
13603 (match_operator 3 "binary_fp_operator"
13604 [(match_operand 1 "register_operand")
13605 (float (match_operand:SWI24 2 "register_operand"))]))]
13606 "reload_completed
13607 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13608 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13609 [(const_int 0)]
13610 {
13611 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13612 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13613 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13614 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13615 GET_MODE (operands[3]),
13616 operands[1],
13617 operands[4])));
13618 ix86_free_from_memory (GET_MODE (operands[2]));
13619 DONE;
13620 })
13621 \f
13622 ;; FPU special functions.
13623
13624 ;; This pattern implements a no-op XFmode truncation for
13625 ;; all fancy i386 XFmode math functions.
13626
13627 (define_insn "truncxf<mode>2_i387_noop_unspec"
13628 [(set (match_operand:MODEF 0 "register_operand" "=f")
13629 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13630 UNSPEC_TRUNC_NOOP))]
13631 "TARGET_USE_FANCY_MATH_387"
13632 "* return output_387_reg_move (insn, operands);"
13633 [(set_attr "type" "fmov")
13634 (set_attr "mode" "<MODE>")])
13635
13636 (define_insn "sqrtxf2"
13637 [(set (match_operand:XF 0 "register_operand" "=f")
13638 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13639 "TARGET_USE_FANCY_MATH_387"
13640 "fsqrt"
13641 [(set_attr "type" "fpspc")
13642 (set_attr "mode" "XF")
13643 (set_attr "athlon_decode" "direct")
13644 (set_attr "amdfam10_decode" "direct")
13645 (set_attr "bdver1_decode" "direct")])
13646
13647 (define_insn "sqrt_extend<mode>xf2_i387"
13648 [(set (match_operand:XF 0 "register_operand" "=f")
13649 (sqrt:XF
13650 (float_extend:XF
13651 (match_operand:MODEF 1 "register_operand" "0"))))]
13652 "TARGET_USE_FANCY_MATH_387"
13653 "fsqrt"
13654 [(set_attr "type" "fpspc")
13655 (set_attr "mode" "XF")
13656 (set_attr "athlon_decode" "direct")
13657 (set_attr "amdfam10_decode" "direct")
13658 (set_attr "bdver1_decode" "direct")])
13659
13660 (define_insn "*rsqrtsf2_sse"
13661 [(set (match_operand:SF 0 "register_operand" "=x")
13662 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13663 UNSPEC_RSQRT))]
13664 "TARGET_SSE_MATH"
13665 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13666 [(set_attr "type" "sse")
13667 (set_attr "atom_sse_attr" "rcp")
13668 (set_attr "prefix" "maybe_vex")
13669 (set_attr "mode" "SF")])
13670
13671 (define_expand "rsqrtsf2"
13672 [(set (match_operand:SF 0 "register_operand")
13673 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13674 UNSPEC_RSQRT))]
13675 "TARGET_SSE_MATH"
13676 {
13677 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13678 DONE;
13679 })
13680
13681 (define_insn "*sqrt<mode>2_sse"
13682 [(set (match_operand:MODEF 0 "register_operand" "=x")
13683 (sqrt:MODEF
13684 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13685 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13686 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13687 [(set_attr "type" "sse")
13688 (set_attr "atom_sse_attr" "sqrt")
13689 (set_attr "prefix" "maybe_vex")
13690 (set_attr "mode" "<MODE>")
13691 (set_attr "athlon_decode" "*")
13692 (set_attr "amdfam10_decode" "*")
13693 (set_attr "bdver1_decode" "*")])
13694
13695 (define_expand "sqrt<mode>2"
13696 [(set (match_operand:MODEF 0 "register_operand")
13697 (sqrt:MODEF
13698 (match_operand:MODEF 1 "nonimmediate_operand")))]
13699 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13700 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13701 {
13702 if (<MODE>mode == SFmode
13703 && TARGET_SSE_MATH
13704 && TARGET_RECIP_SQRT
13705 && !optimize_function_for_size_p (cfun)
13706 && flag_finite_math_only && !flag_trapping_math
13707 && flag_unsafe_math_optimizations)
13708 {
13709 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13710 DONE;
13711 }
13712
13713 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13714 {
13715 rtx op0 = gen_reg_rtx (XFmode);
13716 rtx op1 = force_reg (<MODE>mode, operands[1]);
13717
13718 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13719 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13720 DONE;
13721 }
13722 })
13723
13724 (define_insn "fpremxf4_i387"
13725 [(set (match_operand:XF 0 "register_operand" "=f")
13726 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13727 (match_operand:XF 3 "register_operand" "1")]
13728 UNSPEC_FPREM_F))
13729 (set (match_operand:XF 1 "register_operand" "=u")
13730 (unspec:XF [(match_dup 2) (match_dup 3)]
13731 UNSPEC_FPREM_U))
13732 (set (reg:CCFP FPSR_REG)
13733 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13734 UNSPEC_C2_FLAG))]
13735 "TARGET_USE_FANCY_MATH_387"
13736 "fprem"
13737 [(set_attr "type" "fpspc")
13738 (set_attr "mode" "XF")])
13739
13740 (define_expand "fmodxf3"
13741 [(use (match_operand:XF 0 "register_operand"))
13742 (use (match_operand:XF 1 "general_operand"))
13743 (use (match_operand:XF 2 "general_operand"))]
13744 "TARGET_USE_FANCY_MATH_387"
13745 {
13746 rtx label = gen_label_rtx ();
13747
13748 rtx op1 = gen_reg_rtx (XFmode);
13749 rtx op2 = gen_reg_rtx (XFmode);
13750
13751 emit_move_insn (op2, operands[2]);
13752 emit_move_insn (op1, operands[1]);
13753
13754 emit_label (label);
13755 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13756 ix86_emit_fp_unordered_jump (label);
13757 LABEL_NUSES (label) = 1;
13758
13759 emit_move_insn (operands[0], op1);
13760 DONE;
13761 })
13762
13763 (define_expand "fmod<mode>3"
13764 [(use (match_operand:MODEF 0 "register_operand"))
13765 (use (match_operand:MODEF 1 "general_operand"))
13766 (use (match_operand:MODEF 2 "general_operand"))]
13767 "TARGET_USE_FANCY_MATH_387"
13768 {
13769 rtx (*gen_truncxf) (rtx, rtx);
13770
13771 rtx label = gen_label_rtx ();
13772
13773 rtx op1 = gen_reg_rtx (XFmode);
13774 rtx op2 = gen_reg_rtx (XFmode);
13775
13776 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13777 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13778
13779 emit_label (label);
13780 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13781 ix86_emit_fp_unordered_jump (label);
13782 LABEL_NUSES (label) = 1;
13783
13784 /* Truncate the result properly for strict SSE math. */
13785 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13786 && !TARGET_MIX_SSE_I387)
13787 gen_truncxf = gen_truncxf<mode>2;
13788 else
13789 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13790
13791 emit_insn (gen_truncxf (operands[0], op1));
13792 DONE;
13793 })
13794
13795 (define_insn "fprem1xf4_i387"
13796 [(set (match_operand:XF 0 "register_operand" "=f")
13797 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13798 (match_operand:XF 3 "register_operand" "1")]
13799 UNSPEC_FPREM1_F))
13800 (set (match_operand:XF 1 "register_operand" "=u")
13801 (unspec:XF [(match_dup 2) (match_dup 3)]
13802 UNSPEC_FPREM1_U))
13803 (set (reg:CCFP FPSR_REG)
13804 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13805 UNSPEC_C2_FLAG))]
13806 "TARGET_USE_FANCY_MATH_387"
13807 "fprem1"
13808 [(set_attr "type" "fpspc")
13809 (set_attr "mode" "XF")])
13810
13811 (define_expand "remainderxf3"
13812 [(use (match_operand:XF 0 "register_operand"))
13813 (use (match_operand:XF 1 "general_operand"))
13814 (use (match_operand:XF 2 "general_operand"))]
13815 "TARGET_USE_FANCY_MATH_387"
13816 {
13817 rtx label = gen_label_rtx ();
13818
13819 rtx op1 = gen_reg_rtx (XFmode);
13820 rtx op2 = gen_reg_rtx (XFmode);
13821
13822 emit_move_insn (op2, operands[2]);
13823 emit_move_insn (op1, operands[1]);
13824
13825 emit_label (label);
13826 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13827 ix86_emit_fp_unordered_jump (label);
13828 LABEL_NUSES (label) = 1;
13829
13830 emit_move_insn (operands[0], op1);
13831 DONE;
13832 })
13833
13834 (define_expand "remainder<mode>3"
13835 [(use (match_operand:MODEF 0 "register_operand"))
13836 (use (match_operand:MODEF 1 "general_operand"))
13837 (use (match_operand:MODEF 2 "general_operand"))]
13838 "TARGET_USE_FANCY_MATH_387"
13839 {
13840 rtx (*gen_truncxf) (rtx, rtx);
13841
13842 rtx label = gen_label_rtx ();
13843
13844 rtx op1 = gen_reg_rtx (XFmode);
13845 rtx op2 = gen_reg_rtx (XFmode);
13846
13847 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13848 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13849
13850 emit_label (label);
13851
13852 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13853 ix86_emit_fp_unordered_jump (label);
13854 LABEL_NUSES (label) = 1;
13855
13856 /* Truncate the result properly for strict SSE math. */
13857 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13858 && !TARGET_MIX_SSE_I387)
13859 gen_truncxf = gen_truncxf<mode>2;
13860 else
13861 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13862
13863 emit_insn (gen_truncxf (operands[0], op1));
13864 DONE;
13865 })
13866
13867 (define_int_iterator SINCOS
13868 [UNSPEC_SIN
13869 UNSPEC_COS])
13870
13871 (define_int_attr sincos
13872 [(UNSPEC_SIN "sin")
13873 (UNSPEC_COS "cos")])
13874
13875 (define_insn "*<sincos>xf2_i387"
13876 [(set (match_operand:XF 0 "register_operand" "=f")
13877 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13878 SINCOS))]
13879 "TARGET_USE_FANCY_MATH_387
13880 && flag_unsafe_math_optimizations"
13881 "f<sincos>"
13882 [(set_attr "type" "fpspc")
13883 (set_attr "mode" "XF")])
13884
13885 (define_insn "*<sincos>_extend<mode>xf2_i387"
13886 [(set (match_operand:XF 0 "register_operand" "=f")
13887 (unspec:XF [(float_extend:XF
13888 (match_operand:MODEF 1 "register_operand" "0"))]
13889 SINCOS))]
13890 "TARGET_USE_FANCY_MATH_387
13891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13892 || TARGET_MIX_SSE_I387)
13893 && flag_unsafe_math_optimizations"
13894 "f<sincos>"
13895 [(set_attr "type" "fpspc")
13896 (set_attr "mode" "XF")])
13897
13898 ;; When sincos pattern is defined, sin and cos builtin functions will be
13899 ;; expanded to sincos pattern with one of its outputs left unused.
13900 ;; CSE pass will figure out if two sincos patterns can be combined,
13901 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13902 ;; depending on the unused output.
13903
13904 (define_insn "sincosxf3"
13905 [(set (match_operand:XF 0 "register_operand" "=f")
13906 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13907 UNSPEC_SINCOS_COS))
13908 (set (match_operand:XF 1 "register_operand" "=u")
13909 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13910 "TARGET_USE_FANCY_MATH_387
13911 && flag_unsafe_math_optimizations"
13912 "fsincos"
13913 [(set_attr "type" "fpspc")
13914 (set_attr "mode" "XF")])
13915
13916 (define_split
13917 [(set (match_operand:XF 0 "register_operand")
13918 (unspec:XF [(match_operand:XF 2 "register_operand")]
13919 UNSPEC_SINCOS_COS))
13920 (set (match_operand:XF 1 "register_operand")
13921 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13922 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13923 && can_create_pseudo_p ()"
13924 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13925
13926 (define_split
13927 [(set (match_operand:XF 0 "register_operand")
13928 (unspec:XF [(match_operand:XF 2 "register_operand")]
13929 UNSPEC_SINCOS_COS))
13930 (set (match_operand:XF 1 "register_operand")
13931 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13932 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13933 && can_create_pseudo_p ()"
13934 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13935
13936 (define_insn "sincos_extend<mode>xf3_i387"
13937 [(set (match_operand:XF 0 "register_operand" "=f")
13938 (unspec:XF [(float_extend:XF
13939 (match_operand:MODEF 2 "register_operand" "0"))]
13940 UNSPEC_SINCOS_COS))
13941 (set (match_operand:XF 1 "register_operand" "=u")
13942 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13943 "TARGET_USE_FANCY_MATH_387
13944 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13945 || TARGET_MIX_SSE_I387)
13946 && flag_unsafe_math_optimizations"
13947 "fsincos"
13948 [(set_attr "type" "fpspc")
13949 (set_attr "mode" "XF")])
13950
13951 (define_split
13952 [(set (match_operand:XF 0 "register_operand")
13953 (unspec:XF [(float_extend:XF
13954 (match_operand:MODEF 2 "register_operand"))]
13955 UNSPEC_SINCOS_COS))
13956 (set (match_operand:XF 1 "register_operand")
13957 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13958 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13959 && can_create_pseudo_p ()"
13960 [(set (match_dup 1)
13961 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13962
13963 (define_split
13964 [(set (match_operand:XF 0 "register_operand")
13965 (unspec:XF [(float_extend:XF
13966 (match_operand:MODEF 2 "register_operand"))]
13967 UNSPEC_SINCOS_COS))
13968 (set (match_operand:XF 1 "register_operand")
13969 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13970 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13971 && can_create_pseudo_p ()"
13972 [(set (match_dup 0)
13973 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13974
13975 (define_expand "sincos<mode>3"
13976 [(use (match_operand:MODEF 0 "register_operand"))
13977 (use (match_operand:MODEF 1 "register_operand"))
13978 (use (match_operand:MODEF 2 "register_operand"))]
13979 "TARGET_USE_FANCY_MATH_387
13980 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13981 || TARGET_MIX_SSE_I387)
13982 && flag_unsafe_math_optimizations"
13983 {
13984 rtx op0 = gen_reg_rtx (XFmode);
13985 rtx op1 = gen_reg_rtx (XFmode);
13986
13987 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13988 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13989 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13990 DONE;
13991 })
13992
13993 (define_insn "fptanxf4_i387"
13994 [(set (match_operand:XF 0 "register_operand" "=f")
13995 (match_operand:XF 3 "const_double_operand" "F"))
13996 (set (match_operand:XF 1 "register_operand" "=u")
13997 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13998 UNSPEC_TAN))]
13999 "TARGET_USE_FANCY_MATH_387
14000 && flag_unsafe_math_optimizations
14001 && standard_80387_constant_p (operands[3]) == 2"
14002 "fptan"
14003 [(set_attr "type" "fpspc")
14004 (set_attr "mode" "XF")])
14005
14006 (define_insn "fptan_extend<mode>xf4_i387"
14007 [(set (match_operand:MODEF 0 "register_operand" "=f")
14008 (match_operand:MODEF 3 "const_double_operand" "F"))
14009 (set (match_operand:XF 1 "register_operand" "=u")
14010 (unspec:XF [(float_extend:XF
14011 (match_operand:MODEF 2 "register_operand" "0"))]
14012 UNSPEC_TAN))]
14013 "TARGET_USE_FANCY_MATH_387
14014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14015 || TARGET_MIX_SSE_I387)
14016 && flag_unsafe_math_optimizations
14017 && standard_80387_constant_p (operands[3]) == 2"
14018 "fptan"
14019 [(set_attr "type" "fpspc")
14020 (set_attr "mode" "XF")])
14021
14022 (define_expand "tanxf2"
14023 [(use (match_operand:XF 0 "register_operand"))
14024 (use (match_operand:XF 1 "register_operand"))]
14025 "TARGET_USE_FANCY_MATH_387
14026 && flag_unsafe_math_optimizations"
14027 {
14028 rtx one = gen_reg_rtx (XFmode);
14029 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14030
14031 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14032 DONE;
14033 })
14034
14035 (define_expand "tan<mode>2"
14036 [(use (match_operand:MODEF 0 "register_operand"))
14037 (use (match_operand:MODEF 1 "register_operand"))]
14038 "TARGET_USE_FANCY_MATH_387
14039 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14040 || TARGET_MIX_SSE_I387)
14041 && flag_unsafe_math_optimizations"
14042 {
14043 rtx op0 = gen_reg_rtx (XFmode);
14044
14045 rtx one = gen_reg_rtx (<MODE>mode);
14046 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14047
14048 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14049 operands[1], op2));
14050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14051 DONE;
14052 })
14053
14054 (define_insn "*fpatanxf3_i387"
14055 [(set (match_operand:XF 0 "register_operand" "=f")
14056 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14057 (match_operand:XF 2 "register_operand" "u")]
14058 UNSPEC_FPATAN))
14059 (clobber (match_scratch:XF 3 "=2"))]
14060 "TARGET_USE_FANCY_MATH_387
14061 && flag_unsafe_math_optimizations"
14062 "fpatan"
14063 [(set_attr "type" "fpspc")
14064 (set_attr "mode" "XF")])
14065
14066 (define_insn "fpatan_extend<mode>xf3_i387"
14067 [(set (match_operand:XF 0 "register_operand" "=f")
14068 (unspec:XF [(float_extend:XF
14069 (match_operand:MODEF 1 "register_operand" "0"))
14070 (float_extend:XF
14071 (match_operand:MODEF 2 "register_operand" "u"))]
14072 UNSPEC_FPATAN))
14073 (clobber (match_scratch:XF 3 "=2"))]
14074 "TARGET_USE_FANCY_MATH_387
14075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14076 || TARGET_MIX_SSE_I387)
14077 && flag_unsafe_math_optimizations"
14078 "fpatan"
14079 [(set_attr "type" "fpspc")
14080 (set_attr "mode" "XF")])
14081
14082 (define_expand "atan2xf3"
14083 [(parallel [(set (match_operand:XF 0 "register_operand")
14084 (unspec:XF [(match_operand:XF 2 "register_operand")
14085 (match_operand:XF 1 "register_operand")]
14086 UNSPEC_FPATAN))
14087 (clobber (match_scratch:XF 3))])]
14088 "TARGET_USE_FANCY_MATH_387
14089 && flag_unsafe_math_optimizations")
14090
14091 (define_expand "atan2<mode>3"
14092 [(use (match_operand:MODEF 0 "register_operand"))
14093 (use (match_operand:MODEF 1 "register_operand"))
14094 (use (match_operand:MODEF 2 "register_operand"))]
14095 "TARGET_USE_FANCY_MATH_387
14096 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14097 || TARGET_MIX_SSE_I387)
14098 && flag_unsafe_math_optimizations"
14099 {
14100 rtx op0 = gen_reg_rtx (XFmode);
14101
14102 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14103 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14104 DONE;
14105 })
14106
14107 (define_expand "atanxf2"
14108 [(parallel [(set (match_operand:XF 0 "register_operand")
14109 (unspec:XF [(match_dup 2)
14110 (match_operand:XF 1 "register_operand")]
14111 UNSPEC_FPATAN))
14112 (clobber (match_scratch:XF 3))])]
14113 "TARGET_USE_FANCY_MATH_387
14114 && flag_unsafe_math_optimizations"
14115 {
14116 operands[2] = gen_reg_rtx (XFmode);
14117 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14118 })
14119
14120 (define_expand "atan<mode>2"
14121 [(use (match_operand:MODEF 0 "register_operand"))
14122 (use (match_operand:MODEF 1 "register_operand"))]
14123 "TARGET_USE_FANCY_MATH_387
14124 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14125 || TARGET_MIX_SSE_I387)
14126 && flag_unsafe_math_optimizations"
14127 {
14128 rtx op0 = gen_reg_rtx (XFmode);
14129
14130 rtx op2 = gen_reg_rtx (<MODE>mode);
14131 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14132
14133 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14134 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14135 DONE;
14136 })
14137
14138 (define_expand "asinxf2"
14139 [(set (match_dup 2)
14140 (mult:XF (match_operand:XF 1 "register_operand")
14141 (match_dup 1)))
14142 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14143 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14144 (parallel [(set (match_operand:XF 0 "register_operand")
14145 (unspec:XF [(match_dup 5) (match_dup 1)]
14146 UNSPEC_FPATAN))
14147 (clobber (match_scratch:XF 6))])]
14148 "TARGET_USE_FANCY_MATH_387
14149 && flag_unsafe_math_optimizations"
14150 {
14151 int i;
14152
14153 if (optimize_insn_for_size_p ())
14154 FAIL;
14155
14156 for (i = 2; i < 6; i++)
14157 operands[i] = gen_reg_rtx (XFmode);
14158
14159 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14160 })
14161
14162 (define_expand "asin<mode>2"
14163 [(use (match_operand:MODEF 0 "register_operand"))
14164 (use (match_operand:MODEF 1 "general_operand"))]
14165 "TARGET_USE_FANCY_MATH_387
14166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14167 || TARGET_MIX_SSE_I387)
14168 && flag_unsafe_math_optimizations"
14169 {
14170 rtx op0 = gen_reg_rtx (XFmode);
14171 rtx op1 = gen_reg_rtx (XFmode);
14172
14173 if (optimize_insn_for_size_p ())
14174 FAIL;
14175
14176 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14177 emit_insn (gen_asinxf2 (op0, op1));
14178 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14179 DONE;
14180 })
14181
14182 (define_expand "acosxf2"
14183 [(set (match_dup 2)
14184 (mult:XF (match_operand:XF 1 "register_operand")
14185 (match_dup 1)))
14186 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14187 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14188 (parallel [(set (match_operand:XF 0 "register_operand")
14189 (unspec:XF [(match_dup 1) (match_dup 5)]
14190 UNSPEC_FPATAN))
14191 (clobber (match_scratch:XF 6))])]
14192 "TARGET_USE_FANCY_MATH_387
14193 && flag_unsafe_math_optimizations"
14194 {
14195 int i;
14196
14197 if (optimize_insn_for_size_p ())
14198 FAIL;
14199
14200 for (i = 2; i < 6; i++)
14201 operands[i] = gen_reg_rtx (XFmode);
14202
14203 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14204 })
14205
14206 (define_expand "acos<mode>2"
14207 [(use (match_operand:MODEF 0 "register_operand"))
14208 (use (match_operand:MODEF 1 "general_operand"))]
14209 "TARGET_USE_FANCY_MATH_387
14210 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14211 || TARGET_MIX_SSE_I387)
14212 && flag_unsafe_math_optimizations"
14213 {
14214 rtx op0 = gen_reg_rtx (XFmode);
14215 rtx op1 = gen_reg_rtx (XFmode);
14216
14217 if (optimize_insn_for_size_p ())
14218 FAIL;
14219
14220 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14221 emit_insn (gen_acosxf2 (op0, op1));
14222 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14223 DONE;
14224 })
14225
14226 (define_insn "fyl2xxf3_i387"
14227 [(set (match_operand:XF 0 "register_operand" "=f")
14228 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14229 (match_operand:XF 2 "register_operand" "u")]
14230 UNSPEC_FYL2X))
14231 (clobber (match_scratch:XF 3 "=2"))]
14232 "TARGET_USE_FANCY_MATH_387
14233 && flag_unsafe_math_optimizations"
14234 "fyl2x"
14235 [(set_attr "type" "fpspc")
14236 (set_attr "mode" "XF")])
14237
14238 (define_insn "fyl2x_extend<mode>xf3_i387"
14239 [(set (match_operand:XF 0 "register_operand" "=f")
14240 (unspec:XF [(float_extend:XF
14241 (match_operand:MODEF 1 "register_operand" "0"))
14242 (match_operand:XF 2 "register_operand" "u")]
14243 UNSPEC_FYL2X))
14244 (clobber (match_scratch:XF 3 "=2"))]
14245 "TARGET_USE_FANCY_MATH_387
14246 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14247 || TARGET_MIX_SSE_I387)
14248 && flag_unsafe_math_optimizations"
14249 "fyl2x"
14250 [(set_attr "type" "fpspc")
14251 (set_attr "mode" "XF")])
14252
14253 (define_expand "logxf2"
14254 [(parallel [(set (match_operand:XF 0 "register_operand")
14255 (unspec:XF [(match_operand:XF 1 "register_operand")
14256 (match_dup 2)] UNSPEC_FYL2X))
14257 (clobber (match_scratch:XF 3))])]
14258 "TARGET_USE_FANCY_MATH_387
14259 && flag_unsafe_math_optimizations"
14260 {
14261 operands[2] = gen_reg_rtx (XFmode);
14262 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14263 })
14264
14265 (define_expand "log<mode>2"
14266 [(use (match_operand:MODEF 0 "register_operand"))
14267 (use (match_operand:MODEF 1 "register_operand"))]
14268 "TARGET_USE_FANCY_MATH_387
14269 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14270 || TARGET_MIX_SSE_I387)
14271 && flag_unsafe_math_optimizations"
14272 {
14273 rtx op0 = gen_reg_rtx (XFmode);
14274
14275 rtx op2 = gen_reg_rtx (XFmode);
14276 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14277
14278 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14279 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14280 DONE;
14281 })
14282
14283 (define_expand "log10xf2"
14284 [(parallel [(set (match_operand:XF 0 "register_operand")
14285 (unspec:XF [(match_operand:XF 1 "register_operand")
14286 (match_dup 2)] UNSPEC_FYL2X))
14287 (clobber (match_scratch:XF 3))])]
14288 "TARGET_USE_FANCY_MATH_387
14289 && flag_unsafe_math_optimizations"
14290 {
14291 operands[2] = gen_reg_rtx (XFmode);
14292 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14293 })
14294
14295 (define_expand "log10<mode>2"
14296 [(use (match_operand:MODEF 0 "register_operand"))
14297 (use (match_operand:MODEF 1 "register_operand"))]
14298 "TARGET_USE_FANCY_MATH_387
14299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14300 || TARGET_MIX_SSE_I387)
14301 && flag_unsafe_math_optimizations"
14302 {
14303 rtx op0 = gen_reg_rtx (XFmode);
14304
14305 rtx op2 = gen_reg_rtx (XFmode);
14306 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14307
14308 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14309 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14310 DONE;
14311 })
14312
14313 (define_expand "log2xf2"
14314 [(parallel [(set (match_operand:XF 0 "register_operand")
14315 (unspec:XF [(match_operand:XF 1 "register_operand")
14316 (match_dup 2)] UNSPEC_FYL2X))
14317 (clobber (match_scratch:XF 3))])]
14318 "TARGET_USE_FANCY_MATH_387
14319 && flag_unsafe_math_optimizations"
14320 {
14321 operands[2] = gen_reg_rtx (XFmode);
14322 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14323 })
14324
14325 (define_expand "log2<mode>2"
14326 [(use (match_operand:MODEF 0 "register_operand"))
14327 (use (match_operand:MODEF 1 "register_operand"))]
14328 "TARGET_USE_FANCY_MATH_387
14329 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14330 || TARGET_MIX_SSE_I387)
14331 && flag_unsafe_math_optimizations"
14332 {
14333 rtx op0 = gen_reg_rtx (XFmode);
14334
14335 rtx op2 = gen_reg_rtx (XFmode);
14336 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14337
14338 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14339 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14340 DONE;
14341 })
14342
14343 (define_insn "fyl2xp1xf3_i387"
14344 [(set (match_operand:XF 0 "register_operand" "=f")
14345 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14346 (match_operand:XF 2 "register_operand" "u")]
14347 UNSPEC_FYL2XP1))
14348 (clobber (match_scratch:XF 3 "=2"))]
14349 "TARGET_USE_FANCY_MATH_387
14350 && flag_unsafe_math_optimizations"
14351 "fyl2xp1"
14352 [(set_attr "type" "fpspc")
14353 (set_attr "mode" "XF")])
14354
14355 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14356 [(set (match_operand:XF 0 "register_operand" "=f")
14357 (unspec:XF [(float_extend:XF
14358 (match_operand:MODEF 1 "register_operand" "0"))
14359 (match_operand:XF 2 "register_operand" "u")]
14360 UNSPEC_FYL2XP1))
14361 (clobber (match_scratch:XF 3 "=2"))]
14362 "TARGET_USE_FANCY_MATH_387
14363 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14364 || TARGET_MIX_SSE_I387)
14365 && flag_unsafe_math_optimizations"
14366 "fyl2xp1"
14367 [(set_attr "type" "fpspc")
14368 (set_attr "mode" "XF")])
14369
14370 (define_expand "log1pxf2"
14371 [(use (match_operand:XF 0 "register_operand"))
14372 (use (match_operand:XF 1 "register_operand"))]
14373 "TARGET_USE_FANCY_MATH_387
14374 && flag_unsafe_math_optimizations"
14375 {
14376 if (optimize_insn_for_size_p ())
14377 FAIL;
14378
14379 ix86_emit_i387_log1p (operands[0], operands[1]);
14380 DONE;
14381 })
14382
14383 (define_expand "log1p<mode>2"
14384 [(use (match_operand:MODEF 0 "register_operand"))
14385 (use (match_operand:MODEF 1 "register_operand"))]
14386 "TARGET_USE_FANCY_MATH_387
14387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14388 || TARGET_MIX_SSE_I387)
14389 && flag_unsafe_math_optimizations"
14390 {
14391 rtx op0;
14392
14393 if (optimize_insn_for_size_p ())
14394 FAIL;
14395
14396 op0 = gen_reg_rtx (XFmode);
14397
14398 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14399
14400 ix86_emit_i387_log1p (op0, operands[1]);
14401 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14402 DONE;
14403 })
14404
14405 (define_insn "fxtractxf3_i387"
14406 [(set (match_operand:XF 0 "register_operand" "=f")
14407 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14408 UNSPEC_XTRACT_FRACT))
14409 (set (match_operand:XF 1 "register_operand" "=u")
14410 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14411 "TARGET_USE_FANCY_MATH_387
14412 && flag_unsafe_math_optimizations"
14413 "fxtract"
14414 [(set_attr "type" "fpspc")
14415 (set_attr "mode" "XF")])
14416
14417 (define_insn "fxtract_extend<mode>xf3_i387"
14418 [(set (match_operand:XF 0 "register_operand" "=f")
14419 (unspec:XF [(float_extend:XF
14420 (match_operand:MODEF 2 "register_operand" "0"))]
14421 UNSPEC_XTRACT_FRACT))
14422 (set (match_operand:XF 1 "register_operand" "=u")
14423 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14424 "TARGET_USE_FANCY_MATH_387
14425 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14426 || TARGET_MIX_SSE_I387)
14427 && flag_unsafe_math_optimizations"
14428 "fxtract"
14429 [(set_attr "type" "fpspc")
14430 (set_attr "mode" "XF")])
14431
14432 (define_expand "logbxf2"
14433 [(parallel [(set (match_dup 2)
14434 (unspec:XF [(match_operand:XF 1 "register_operand")]
14435 UNSPEC_XTRACT_FRACT))
14436 (set (match_operand:XF 0 "register_operand")
14437 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14438 "TARGET_USE_FANCY_MATH_387
14439 && flag_unsafe_math_optimizations"
14440 "operands[2] = gen_reg_rtx (XFmode);")
14441
14442 (define_expand "logb<mode>2"
14443 [(use (match_operand:MODEF 0 "register_operand"))
14444 (use (match_operand:MODEF 1 "register_operand"))]
14445 "TARGET_USE_FANCY_MATH_387
14446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14447 || TARGET_MIX_SSE_I387)
14448 && flag_unsafe_math_optimizations"
14449 {
14450 rtx op0 = gen_reg_rtx (XFmode);
14451 rtx op1 = gen_reg_rtx (XFmode);
14452
14453 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14454 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14455 DONE;
14456 })
14457
14458 (define_expand "ilogbxf2"
14459 [(use (match_operand:SI 0 "register_operand"))
14460 (use (match_operand:XF 1 "register_operand"))]
14461 "TARGET_USE_FANCY_MATH_387
14462 && flag_unsafe_math_optimizations"
14463 {
14464 rtx op0, op1;
14465
14466 if (optimize_insn_for_size_p ())
14467 FAIL;
14468
14469 op0 = gen_reg_rtx (XFmode);
14470 op1 = gen_reg_rtx (XFmode);
14471
14472 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14473 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14474 DONE;
14475 })
14476
14477 (define_expand "ilogb<mode>2"
14478 [(use (match_operand:SI 0 "register_operand"))
14479 (use (match_operand:MODEF 1 "register_operand"))]
14480 "TARGET_USE_FANCY_MATH_387
14481 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14482 || TARGET_MIX_SSE_I387)
14483 && flag_unsafe_math_optimizations"
14484 {
14485 rtx op0, op1;
14486
14487 if (optimize_insn_for_size_p ())
14488 FAIL;
14489
14490 op0 = gen_reg_rtx (XFmode);
14491 op1 = gen_reg_rtx (XFmode);
14492
14493 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14494 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14495 DONE;
14496 })
14497
14498 (define_insn "*f2xm1xf2_i387"
14499 [(set (match_operand:XF 0 "register_operand" "=f")
14500 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14501 UNSPEC_F2XM1))]
14502 "TARGET_USE_FANCY_MATH_387
14503 && flag_unsafe_math_optimizations"
14504 "f2xm1"
14505 [(set_attr "type" "fpspc")
14506 (set_attr "mode" "XF")])
14507
14508 (define_insn "*fscalexf4_i387"
14509 [(set (match_operand:XF 0 "register_operand" "=f")
14510 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14511 (match_operand:XF 3 "register_operand" "1")]
14512 UNSPEC_FSCALE_FRACT))
14513 (set (match_operand:XF 1 "register_operand" "=u")
14514 (unspec:XF [(match_dup 2) (match_dup 3)]
14515 UNSPEC_FSCALE_EXP))]
14516 "TARGET_USE_FANCY_MATH_387
14517 && flag_unsafe_math_optimizations"
14518 "fscale"
14519 [(set_attr "type" "fpspc")
14520 (set_attr "mode" "XF")])
14521
14522 (define_expand "expNcorexf3"
14523 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14524 (match_operand:XF 2 "register_operand")))
14525 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14526 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14527 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14528 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14529 (parallel [(set (match_operand:XF 0 "register_operand")
14530 (unspec:XF [(match_dup 8) (match_dup 4)]
14531 UNSPEC_FSCALE_FRACT))
14532 (set (match_dup 9)
14533 (unspec:XF [(match_dup 8) (match_dup 4)]
14534 UNSPEC_FSCALE_EXP))])]
14535 "TARGET_USE_FANCY_MATH_387
14536 && flag_unsafe_math_optimizations"
14537 {
14538 int i;
14539
14540 if (optimize_insn_for_size_p ())
14541 FAIL;
14542
14543 for (i = 3; i < 10; i++)
14544 operands[i] = gen_reg_rtx (XFmode);
14545
14546 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14547 })
14548
14549 (define_expand "expxf2"
14550 [(use (match_operand:XF 0 "register_operand"))
14551 (use (match_operand:XF 1 "register_operand"))]
14552 "TARGET_USE_FANCY_MATH_387
14553 && flag_unsafe_math_optimizations"
14554 {
14555 rtx op2;
14556
14557 if (optimize_insn_for_size_p ())
14558 FAIL;
14559
14560 op2 = gen_reg_rtx (XFmode);
14561 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14562
14563 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14564 DONE;
14565 })
14566
14567 (define_expand "exp<mode>2"
14568 [(use (match_operand:MODEF 0 "register_operand"))
14569 (use (match_operand:MODEF 1 "general_operand"))]
14570 "TARGET_USE_FANCY_MATH_387
14571 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14572 || TARGET_MIX_SSE_I387)
14573 && flag_unsafe_math_optimizations"
14574 {
14575 rtx op0, op1;
14576
14577 if (optimize_insn_for_size_p ())
14578 FAIL;
14579
14580 op0 = gen_reg_rtx (XFmode);
14581 op1 = gen_reg_rtx (XFmode);
14582
14583 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14584 emit_insn (gen_expxf2 (op0, op1));
14585 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14586 DONE;
14587 })
14588
14589 (define_expand "exp10xf2"
14590 [(use (match_operand:XF 0 "register_operand"))
14591 (use (match_operand:XF 1 "register_operand"))]
14592 "TARGET_USE_FANCY_MATH_387
14593 && flag_unsafe_math_optimizations"
14594 {
14595 rtx op2;
14596
14597 if (optimize_insn_for_size_p ())
14598 FAIL;
14599
14600 op2 = gen_reg_rtx (XFmode);
14601 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14602
14603 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14604 DONE;
14605 })
14606
14607 (define_expand "exp10<mode>2"
14608 [(use (match_operand:MODEF 0 "register_operand"))
14609 (use (match_operand:MODEF 1 "general_operand"))]
14610 "TARGET_USE_FANCY_MATH_387
14611 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14612 || TARGET_MIX_SSE_I387)
14613 && flag_unsafe_math_optimizations"
14614 {
14615 rtx op0, op1;
14616
14617 if (optimize_insn_for_size_p ())
14618 FAIL;
14619
14620 op0 = gen_reg_rtx (XFmode);
14621 op1 = gen_reg_rtx (XFmode);
14622
14623 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14624 emit_insn (gen_exp10xf2 (op0, op1));
14625 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14626 DONE;
14627 })
14628
14629 (define_expand "exp2xf2"
14630 [(use (match_operand:XF 0 "register_operand"))
14631 (use (match_operand:XF 1 "register_operand"))]
14632 "TARGET_USE_FANCY_MATH_387
14633 && flag_unsafe_math_optimizations"
14634 {
14635 rtx op2;
14636
14637 if (optimize_insn_for_size_p ())
14638 FAIL;
14639
14640 op2 = gen_reg_rtx (XFmode);
14641 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14642
14643 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14644 DONE;
14645 })
14646
14647 (define_expand "exp2<mode>2"
14648 [(use (match_operand:MODEF 0 "register_operand"))
14649 (use (match_operand:MODEF 1 "general_operand"))]
14650 "TARGET_USE_FANCY_MATH_387
14651 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14652 || TARGET_MIX_SSE_I387)
14653 && flag_unsafe_math_optimizations"
14654 {
14655 rtx op0, op1;
14656
14657 if (optimize_insn_for_size_p ())
14658 FAIL;
14659
14660 op0 = gen_reg_rtx (XFmode);
14661 op1 = gen_reg_rtx (XFmode);
14662
14663 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14664 emit_insn (gen_exp2xf2 (op0, op1));
14665 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14666 DONE;
14667 })
14668
14669 (define_expand "expm1xf2"
14670 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14671 (match_dup 2)))
14672 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14673 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14674 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14675 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14676 (parallel [(set (match_dup 7)
14677 (unspec:XF [(match_dup 6) (match_dup 4)]
14678 UNSPEC_FSCALE_FRACT))
14679 (set (match_dup 8)
14680 (unspec:XF [(match_dup 6) (match_dup 4)]
14681 UNSPEC_FSCALE_EXP))])
14682 (parallel [(set (match_dup 10)
14683 (unspec:XF [(match_dup 9) (match_dup 8)]
14684 UNSPEC_FSCALE_FRACT))
14685 (set (match_dup 11)
14686 (unspec:XF [(match_dup 9) (match_dup 8)]
14687 UNSPEC_FSCALE_EXP))])
14688 (set (match_dup 12) (minus:XF (match_dup 10)
14689 (float_extend:XF (match_dup 13))))
14690 (set (match_operand:XF 0 "register_operand")
14691 (plus:XF (match_dup 12) (match_dup 7)))]
14692 "TARGET_USE_FANCY_MATH_387
14693 && flag_unsafe_math_optimizations"
14694 {
14695 int i;
14696
14697 if (optimize_insn_for_size_p ())
14698 FAIL;
14699
14700 for (i = 2; i < 13; i++)
14701 operands[i] = gen_reg_rtx (XFmode);
14702
14703 operands[13]
14704 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14705
14706 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14707 })
14708
14709 (define_expand "expm1<mode>2"
14710 [(use (match_operand:MODEF 0 "register_operand"))
14711 (use (match_operand:MODEF 1 "general_operand"))]
14712 "TARGET_USE_FANCY_MATH_387
14713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14714 || TARGET_MIX_SSE_I387)
14715 && flag_unsafe_math_optimizations"
14716 {
14717 rtx op0, op1;
14718
14719 if (optimize_insn_for_size_p ())
14720 FAIL;
14721
14722 op0 = gen_reg_rtx (XFmode);
14723 op1 = gen_reg_rtx (XFmode);
14724
14725 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14726 emit_insn (gen_expm1xf2 (op0, op1));
14727 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14728 DONE;
14729 })
14730
14731 (define_expand "ldexpxf3"
14732 [(set (match_dup 3)
14733 (float:XF (match_operand:SI 2 "register_operand")))
14734 (parallel [(set (match_operand:XF 0 " register_operand")
14735 (unspec:XF [(match_operand:XF 1 "register_operand")
14736 (match_dup 3)]
14737 UNSPEC_FSCALE_FRACT))
14738 (set (match_dup 4)
14739 (unspec:XF [(match_dup 1) (match_dup 3)]
14740 UNSPEC_FSCALE_EXP))])]
14741 "TARGET_USE_FANCY_MATH_387
14742 && flag_unsafe_math_optimizations"
14743 {
14744 if (optimize_insn_for_size_p ())
14745 FAIL;
14746
14747 operands[3] = gen_reg_rtx (XFmode);
14748 operands[4] = gen_reg_rtx (XFmode);
14749 })
14750
14751 (define_expand "ldexp<mode>3"
14752 [(use (match_operand:MODEF 0 "register_operand"))
14753 (use (match_operand:MODEF 1 "general_operand"))
14754 (use (match_operand:SI 2 "register_operand"))]
14755 "TARGET_USE_FANCY_MATH_387
14756 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14757 || TARGET_MIX_SSE_I387)
14758 && flag_unsafe_math_optimizations"
14759 {
14760 rtx op0, op1;
14761
14762 if (optimize_insn_for_size_p ())
14763 FAIL;
14764
14765 op0 = gen_reg_rtx (XFmode);
14766 op1 = gen_reg_rtx (XFmode);
14767
14768 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14769 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14770 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14771 DONE;
14772 })
14773
14774 (define_expand "scalbxf3"
14775 [(parallel [(set (match_operand:XF 0 " register_operand")
14776 (unspec:XF [(match_operand:XF 1 "register_operand")
14777 (match_operand:XF 2 "register_operand")]
14778 UNSPEC_FSCALE_FRACT))
14779 (set (match_dup 3)
14780 (unspec:XF [(match_dup 1) (match_dup 2)]
14781 UNSPEC_FSCALE_EXP))])]
14782 "TARGET_USE_FANCY_MATH_387
14783 && flag_unsafe_math_optimizations"
14784 {
14785 if (optimize_insn_for_size_p ())
14786 FAIL;
14787
14788 operands[3] = gen_reg_rtx (XFmode);
14789 })
14790
14791 (define_expand "scalb<mode>3"
14792 [(use (match_operand:MODEF 0 "register_operand"))
14793 (use (match_operand:MODEF 1 "general_operand"))
14794 (use (match_operand:MODEF 2 "general_operand"))]
14795 "TARGET_USE_FANCY_MATH_387
14796 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14797 || TARGET_MIX_SSE_I387)
14798 && flag_unsafe_math_optimizations"
14799 {
14800 rtx op0, op1, op2;
14801
14802 if (optimize_insn_for_size_p ())
14803 FAIL;
14804
14805 op0 = gen_reg_rtx (XFmode);
14806 op1 = gen_reg_rtx (XFmode);
14807 op2 = gen_reg_rtx (XFmode);
14808
14809 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14810 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14811 emit_insn (gen_scalbxf3 (op0, op1, op2));
14812 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14813 DONE;
14814 })
14815
14816 (define_expand "significandxf2"
14817 [(parallel [(set (match_operand:XF 0 "register_operand")
14818 (unspec:XF [(match_operand:XF 1 "register_operand")]
14819 UNSPEC_XTRACT_FRACT))
14820 (set (match_dup 2)
14821 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14822 "TARGET_USE_FANCY_MATH_387
14823 && flag_unsafe_math_optimizations"
14824 "operands[2] = gen_reg_rtx (XFmode);")
14825
14826 (define_expand "significand<mode>2"
14827 [(use (match_operand:MODEF 0 "register_operand"))
14828 (use (match_operand:MODEF 1 "register_operand"))]
14829 "TARGET_USE_FANCY_MATH_387
14830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14831 || TARGET_MIX_SSE_I387)
14832 && flag_unsafe_math_optimizations"
14833 {
14834 rtx op0 = gen_reg_rtx (XFmode);
14835 rtx op1 = gen_reg_rtx (XFmode);
14836
14837 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14839 DONE;
14840 })
14841 \f
14842
14843 (define_insn "sse4_1_round<mode>2"
14844 [(set (match_operand:MODEF 0 "register_operand" "=x")
14845 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14846 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14847 UNSPEC_ROUND))]
14848 "TARGET_ROUND"
14849 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14850 [(set_attr "type" "ssecvt")
14851 (set_attr "prefix_extra" "1")
14852 (set_attr "prefix" "maybe_vex")
14853 (set_attr "mode" "<MODE>")])
14854
14855 (define_insn "rintxf2"
14856 [(set (match_operand:XF 0 "register_operand" "=f")
14857 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14858 UNSPEC_FRNDINT))]
14859 "TARGET_USE_FANCY_MATH_387
14860 && flag_unsafe_math_optimizations"
14861 "frndint"
14862 [(set_attr "type" "fpspc")
14863 (set_attr "mode" "XF")])
14864
14865 (define_expand "rint<mode>2"
14866 [(use (match_operand:MODEF 0 "register_operand"))
14867 (use (match_operand:MODEF 1 "register_operand"))]
14868 "(TARGET_USE_FANCY_MATH_387
14869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14870 || TARGET_MIX_SSE_I387)
14871 && flag_unsafe_math_optimizations)
14872 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14873 && !flag_trapping_math)"
14874 {
14875 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14876 && !flag_trapping_math)
14877 {
14878 if (TARGET_ROUND)
14879 emit_insn (gen_sse4_1_round<mode>2
14880 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14881 else if (optimize_insn_for_size_p ())
14882 FAIL;
14883 else
14884 ix86_expand_rint (operands[0], operands[1]);
14885 }
14886 else
14887 {
14888 rtx op0 = gen_reg_rtx (XFmode);
14889 rtx op1 = gen_reg_rtx (XFmode);
14890
14891 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14892 emit_insn (gen_rintxf2 (op0, op1));
14893
14894 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14895 }
14896 DONE;
14897 })
14898
14899 (define_expand "round<mode>2"
14900 [(match_operand:X87MODEF 0 "register_operand")
14901 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14902 "(TARGET_USE_FANCY_MATH_387
14903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14904 || TARGET_MIX_SSE_I387)
14905 && flag_unsafe_math_optimizations)
14906 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14907 && !flag_trapping_math && !flag_rounding_math)"
14908 {
14909 if (optimize_insn_for_size_p ())
14910 FAIL;
14911
14912 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14913 && !flag_trapping_math && !flag_rounding_math)
14914 {
14915 if (TARGET_ROUND)
14916 {
14917 operands[1] = force_reg (<MODE>mode, operands[1]);
14918 ix86_expand_round_sse4 (operands[0], operands[1]);
14919 }
14920 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14921 ix86_expand_round (operands[0], operands[1]);
14922 else
14923 ix86_expand_rounddf_32 (operands[0], operands[1]);
14924 }
14925 else
14926 {
14927 operands[1] = force_reg (<MODE>mode, operands[1]);
14928 ix86_emit_i387_round (operands[0], operands[1]);
14929 }
14930 DONE;
14931 })
14932
14933 (define_insn_and_split "*fistdi2_1"
14934 [(set (match_operand:DI 0 "nonimmediate_operand")
14935 (unspec:DI [(match_operand:XF 1 "register_operand")]
14936 UNSPEC_FIST))]
14937 "TARGET_USE_FANCY_MATH_387
14938 && can_create_pseudo_p ()"
14939 "#"
14940 "&& 1"
14941 [(const_int 0)]
14942 {
14943 if (memory_operand (operands[0], VOIDmode))
14944 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14945 else
14946 {
14947 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14948 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14949 operands[2]));
14950 }
14951 DONE;
14952 }
14953 [(set_attr "type" "fpspc")
14954 (set_attr "mode" "DI")])
14955
14956 (define_insn "fistdi2"
14957 [(set (match_operand:DI 0 "memory_operand" "=m")
14958 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14959 UNSPEC_FIST))
14960 (clobber (match_scratch:XF 2 "=&1f"))]
14961 "TARGET_USE_FANCY_MATH_387"
14962 "* return output_fix_trunc (insn, operands, false);"
14963 [(set_attr "type" "fpspc")
14964 (set_attr "mode" "DI")])
14965
14966 (define_insn "fistdi2_with_temp"
14967 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14968 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14969 UNSPEC_FIST))
14970 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14971 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14972 "TARGET_USE_FANCY_MATH_387"
14973 "#"
14974 [(set_attr "type" "fpspc")
14975 (set_attr "mode" "DI")])
14976
14977 (define_split
14978 [(set (match_operand:DI 0 "register_operand")
14979 (unspec:DI [(match_operand:XF 1 "register_operand")]
14980 UNSPEC_FIST))
14981 (clobber (match_operand:DI 2 "memory_operand"))
14982 (clobber (match_scratch 3))]
14983 "reload_completed"
14984 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14985 (clobber (match_dup 3))])
14986 (set (match_dup 0) (match_dup 2))])
14987
14988 (define_split
14989 [(set (match_operand:DI 0 "memory_operand")
14990 (unspec:DI [(match_operand:XF 1 "register_operand")]
14991 UNSPEC_FIST))
14992 (clobber (match_operand:DI 2 "memory_operand"))
14993 (clobber (match_scratch 3))]
14994 "reload_completed"
14995 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14996 (clobber (match_dup 3))])])
14997
14998 (define_insn_and_split "*fist<mode>2_1"
14999 [(set (match_operand:SWI24 0 "register_operand")
15000 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15001 UNSPEC_FIST))]
15002 "TARGET_USE_FANCY_MATH_387
15003 && can_create_pseudo_p ()"
15004 "#"
15005 "&& 1"
15006 [(const_int 0)]
15007 {
15008 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15009 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15010 operands[2]));
15011 DONE;
15012 }
15013 [(set_attr "type" "fpspc")
15014 (set_attr "mode" "<MODE>")])
15015
15016 (define_insn "fist<mode>2"
15017 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15018 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15019 UNSPEC_FIST))]
15020 "TARGET_USE_FANCY_MATH_387"
15021 "* return output_fix_trunc (insn, operands, false);"
15022 [(set_attr "type" "fpspc")
15023 (set_attr "mode" "<MODE>")])
15024
15025 (define_insn "fist<mode>2_with_temp"
15026 [(set (match_operand:SWI24 0 "register_operand" "=r")
15027 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15028 UNSPEC_FIST))
15029 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15030 "TARGET_USE_FANCY_MATH_387"
15031 "#"
15032 [(set_attr "type" "fpspc")
15033 (set_attr "mode" "<MODE>")])
15034
15035 (define_split
15036 [(set (match_operand:SWI24 0 "register_operand")
15037 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15038 UNSPEC_FIST))
15039 (clobber (match_operand:SWI24 2 "memory_operand"))]
15040 "reload_completed"
15041 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15042 (set (match_dup 0) (match_dup 2))])
15043
15044 (define_split
15045 [(set (match_operand:SWI24 0 "memory_operand")
15046 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15047 UNSPEC_FIST))
15048 (clobber (match_operand:SWI24 2 "memory_operand"))]
15049 "reload_completed"
15050 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15051
15052 (define_expand "lrintxf<mode>2"
15053 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15054 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15055 UNSPEC_FIST))]
15056 "TARGET_USE_FANCY_MATH_387")
15057
15058 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15059 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15060 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15061 UNSPEC_FIX_NOTRUNC))]
15062 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15063 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15064
15065 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15066 [(match_operand:SWI248x 0 "nonimmediate_operand")
15067 (match_operand:X87MODEF 1 "register_operand")]
15068 "(TARGET_USE_FANCY_MATH_387
15069 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15070 || TARGET_MIX_SSE_I387)
15071 && flag_unsafe_math_optimizations)
15072 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15073 && <SWI248x:MODE>mode != HImode
15074 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15075 && !flag_trapping_math && !flag_rounding_math)"
15076 {
15077 if (optimize_insn_for_size_p ())
15078 FAIL;
15079
15080 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15081 && <SWI248x:MODE>mode != HImode
15082 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15083 && !flag_trapping_math && !flag_rounding_math)
15084 ix86_expand_lround (operands[0], operands[1]);
15085 else
15086 ix86_emit_i387_round (operands[0], operands[1]);
15087 DONE;
15088 })
15089
15090 (define_int_iterator FRNDINT_ROUNDING
15091 [UNSPEC_FRNDINT_FLOOR
15092 UNSPEC_FRNDINT_CEIL
15093 UNSPEC_FRNDINT_TRUNC])
15094
15095 (define_int_iterator FIST_ROUNDING
15096 [UNSPEC_FIST_FLOOR
15097 UNSPEC_FIST_CEIL])
15098
15099 ;; Base name for define_insn
15100 (define_int_attr rounding_insn
15101 [(UNSPEC_FRNDINT_FLOOR "floor")
15102 (UNSPEC_FRNDINT_CEIL "ceil")
15103 (UNSPEC_FRNDINT_TRUNC "btrunc")
15104 (UNSPEC_FIST_FLOOR "floor")
15105 (UNSPEC_FIST_CEIL "ceil")])
15106
15107 (define_int_attr rounding
15108 [(UNSPEC_FRNDINT_FLOOR "floor")
15109 (UNSPEC_FRNDINT_CEIL "ceil")
15110 (UNSPEC_FRNDINT_TRUNC "trunc")
15111 (UNSPEC_FIST_FLOOR "floor")
15112 (UNSPEC_FIST_CEIL "ceil")])
15113
15114 (define_int_attr ROUNDING
15115 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15116 (UNSPEC_FRNDINT_CEIL "CEIL")
15117 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15118 (UNSPEC_FIST_FLOOR "FLOOR")
15119 (UNSPEC_FIST_CEIL "CEIL")])
15120
15121 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15122 (define_insn_and_split "frndintxf2_<rounding>"
15123 [(set (match_operand:XF 0 "register_operand")
15124 (unspec:XF [(match_operand:XF 1 "register_operand")]
15125 FRNDINT_ROUNDING))
15126 (clobber (reg:CC FLAGS_REG))]
15127 "TARGET_USE_FANCY_MATH_387
15128 && flag_unsafe_math_optimizations
15129 && can_create_pseudo_p ()"
15130 "#"
15131 "&& 1"
15132 [(const_int 0)]
15133 {
15134 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15135
15136 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15137 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15138
15139 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15140 operands[2], operands[3]));
15141 DONE;
15142 }
15143 [(set_attr "type" "frndint")
15144 (set_attr "i387_cw" "<rounding>")
15145 (set_attr "mode" "XF")])
15146
15147 (define_insn "frndintxf2_<rounding>_i387"
15148 [(set (match_operand:XF 0 "register_operand" "=f")
15149 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15150 FRNDINT_ROUNDING))
15151 (use (match_operand:HI 2 "memory_operand" "m"))
15152 (use (match_operand:HI 3 "memory_operand" "m"))]
15153 "TARGET_USE_FANCY_MATH_387
15154 && flag_unsafe_math_optimizations"
15155 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15156 [(set_attr "type" "frndint")
15157 (set_attr "i387_cw" "<rounding>")
15158 (set_attr "mode" "XF")])
15159
15160 (define_expand "<rounding_insn>xf2"
15161 [(parallel [(set (match_operand:XF 0 "register_operand")
15162 (unspec:XF [(match_operand:XF 1 "register_operand")]
15163 FRNDINT_ROUNDING))
15164 (clobber (reg:CC FLAGS_REG))])]
15165 "TARGET_USE_FANCY_MATH_387
15166 && flag_unsafe_math_optimizations
15167 && !optimize_insn_for_size_p ()")
15168
15169 (define_expand "<rounding_insn><mode>2"
15170 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15171 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15172 FRNDINT_ROUNDING))
15173 (clobber (reg:CC FLAGS_REG))])]
15174 "(TARGET_USE_FANCY_MATH_387
15175 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15176 || TARGET_MIX_SSE_I387)
15177 && flag_unsafe_math_optimizations)
15178 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15179 && !flag_trapping_math)"
15180 {
15181 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15182 && !flag_trapping_math)
15183 {
15184 if (TARGET_ROUND)
15185 emit_insn (gen_sse4_1_round<mode>2
15186 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15187 else if (optimize_insn_for_size_p ())
15188 FAIL;
15189 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15190 {
15191 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15192 ix86_expand_floorceil (operands[0], operands[1], true);
15193 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15194 ix86_expand_floorceil (operands[0], operands[1], false);
15195 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15196 ix86_expand_trunc (operands[0], operands[1]);
15197 else
15198 gcc_unreachable ();
15199 }
15200 else
15201 {
15202 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15203 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15204 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15205 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15206 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15207 ix86_expand_truncdf_32 (operands[0], operands[1]);
15208 else
15209 gcc_unreachable ();
15210 }
15211 }
15212 else
15213 {
15214 rtx op0, op1;
15215
15216 if (optimize_insn_for_size_p ())
15217 FAIL;
15218
15219 op0 = gen_reg_rtx (XFmode);
15220 op1 = gen_reg_rtx (XFmode);
15221 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15222 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15223
15224 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15225 }
15226 DONE;
15227 })
15228
15229 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15230 (define_insn_and_split "frndintxf2_mask_pm"
15231 [(set (match_operand:XF 0 "register_operand")
15232 (unspec:XF [(match_operand:XF 1 "register_operand")]
15233 UNSPEC_FRNDINT_MASK_PM))
15234 (clobber (reg:CC FLAGS_REG))]
15235 "TARGET_USE_FANCY_MATH_387
15236 && flag_unsafe_math_optimizations
15237 && can_create_pseudo_p ()"
15238 "#"
15239 "&& 1"
15240 [(const_int 0)]
15241 {
15242 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15243
15244 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15245 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15246
15247 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15248 operands[2], operands[3]));
15249 DONE;
15250 }
15251 [(set_attr "type" "frndint")
15252 (set_attr "i387_cw" "mask_pm")
15253 (set_attr "mode" "XF")])
15254
15255 (define_insn "frndintxf2_mask_pm_i387"
15256 [(set (match_operand:XF 0 "register_operand" "=f")
15257 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15258 UNSPEC_FRNDINT_MASK_PM))
15259 (use (match_operand:HI 2 "memory_operand" "m"))
15260 (use (match_operand:HI 3 "memory_operand" "m"))]
15261 "TARGET_USE_FANCY_MATH_387
15262 && flag_unsafe_math_optimizations"
15263 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15264 [(set_attr "type" "frndint")
15265 (set_attr "i387_cw" "mask_pm")
15266 (set_attr "mode" "XF")])
15267
15268 (define_expand "nearbyintxf2"
15269 [(parallel [(set (match_operand:XF 0 "register_operand")
15270 (unspec:XF [(match_operand:XF 1 "register_operand")]
15271 UNSPEC_FRNDINT_MASK_PM))
15272 (clobber (reg:CC FLAGS_REG))])]
15273 "TARGET_USE_FANCY_MATH_387
15274 && flag_unsafe_math_optimizations")
15275
15276 (define_expand "nearbyint<mode>2"
15277 [(use (match_operand:MODEF 0 "register_operand"))
15278 (use (match_operand:MODEF 1 "register_operand"))]
15279 "TARGET_USE_FANCY_MATH_387
15280 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15281 || TARGET_MIX_SSE_I387)
15282 && flag_unsafe_math_optimizations"
15283 {
15284 rtx op0 = gen_reg_rtx (XFmode);
15285 rtx op1 = gen_reg_rtx (XFmode);
15286
15287 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15288 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15289
15290 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15291 DONE;
15292 })
15293
15294 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15295 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15296 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15297 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15298 FIST_ROUNDING))
15299 (clobber (reg:CC FLAGS_REG))]
15300 "TARGET_USE_FANCY_MATH_387
15301 && flag_unsafe_math_optimizations
15302 && can_create_pseudo_p ()"
15303 "#"
15304 "&& 1"
15305 [(const_int 0)]
15306 {
15307 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15308
15309 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15310 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15311 if (memory_operand (operands[0], VOIDmode))
15312 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15313 operands[2], operands[3]));
15314 else
15315 {
15316 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15317 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15318 (operands[0], operands[1], operands[2],
15319 operands[3], operands[4]));
15320 }
15321 DONE;
15322 }
15323 [(set_attr "type" "fistp")
15324 (set_attr "i387_cw" "<rounding>")
15325 (set_attr "mode" "<MODE>")])
15326
15327 (define_insn "fistdi2_<rounding>"
15328 [(set (match_operand:DI 0 "memory_operand" "=m")
15329 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15330 FIST_ROUNDING))
15331 (use (match_operand:HI 2 "memory_operand" "m"))
15332 (use (match_operand:HI 3 "memory_operand" "m"))
15333 (clobber (match_scratch:XF 4 "=&1f"))]
15334 "TARGET_USE_FANCY_MATH_387
15335 && flag_unsafe_math_optimizations"
15336 "* return output_fix_trunc (insn, operands, false);"
15337 [(set_attr "type" "fistp")
15338 (set_attr "i387_cw" "<rounding>")
15339 (set_attr "mode" "DI")])
15340
15341 (define_insn "fistdi2_<rounding>_with_temp"
15342 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15343 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15344 FIST_ROUNDING))
15345 (use (match_operand:HI 2 "memory_operand" "m,m"))
15346 (use (match_operand:HI 3 "memory_operand" "m,m"))
15347 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15348 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15349 "TARGET_USE_FANCY_MATH_387
15350 && flag_unsafe_math_optimizations"
15351 "#"
15352 [(set_attr "type" "fistp")
15353 (set_attr "i387_cw" "<rounding>")
15354 (set_attr "mode" "DI")])
15355
15356 (define_split
15357 [(set (match_operand:DI 0 "register_operand")
15358 (unspec:DI [(match_operand:XF 1 "register_operand")]
15359 FIST_ROUNDING))
15360 (use (match_operand:HI 2 "memory_operand"))
15361 (use (match_operand:HI 3 "memory_operand"))
15362 (clobber (match_operand:DI 4 "memory_operand"))
15363 (clobber (match_scratch 5))]
15364 "reload_completed"
15365 [(parallel [(set (match_dup 4)
15366 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15367 (use (match_dup 2))
15368 (use (match_dup 3))
15369 (clobber (match_dup 5))])
15370 (set (match_dup 0) (match_dup 4))])
15371
15372 (define_split
15373 [(set (match_operand:DI 0 "memory_operand")
15374 (unspec:DI [(match_operand:XF 1 "register_operand")]
15375 FIST_ROUNDING))
15376 (use (match_operand:HI 2 "memory_operand"))
15377 (use (match_operand:HI 3 "memory_operand"))
15378 (clobber (match_operand:DI 4 "memory_operand"))
15379 (clobber (match_scratch 5))]
15380 "reload_completed"
15381 [(parallel [(set (match_dup 0)
15382 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15383 (use (match_dup 2))
15384 (use (match_dup 3))
15385 (clobber (match_dup 5))])])
15386
15387 (define_insn "fist<mode>2_<rounding>"
15388 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15389 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15390 FIST_ROUNDING))
15391 (use (match_operand:HI 2 "memory_operand" "m"))
15392 (use (match_operand:HI 3 "memory_operand" "m"))]
15393 "TARGET_USE_FANCY_MATH_387
15394 && flag_unsafe_math_optimizations"
15395 "* return output_fix_trunc (insn, operands, false);"
15396 [(set_attr "type" "fistp")
15397 (set_attr "i387_cw" "<rounding>")
15398 (set_attr "mode" "<MODE>")])
15399
15400 (define_insn "fist<mode>2_<rounding>_with_temp"
15401 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15402 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15403 FIST_ROUNDING))
15404 (use (match_operand:HI 2 "memory_operand" "m,m"))
15405 (use (match_operand:HI 3 "memory_operand" "m,m"))
15406 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15407 "TARGET_USE_FANCY_MATH_387
15408 && flag_unsafe_math_optimizations"
15409 "#"
15410 [(set_attr "type" "fistp")
15411 (set_attr "i387_cw" "<rounding>")
15412 (set_attr "mode" "<MODE>")])
15413
15414 (define_split
15415 [(set (match_operand:SWI24 0 "register_operand")
15416 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15417 FIST_ROUNDING))
15418 (use (match_operand:HI 2 "memory_operand"))
15419 (use (match_operand:HI 3 "memory_operand"))
15420 (clobber (match_operand:SWI24 4 "memory_operand"))]
15421 "reload_completed"
15422 [(parallel [(set (match_dup 4)
15423 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15424 (use (match_dup 2))
15425 (use (match_dup 3))])
15426 (set (match_dup 0) (match_dup 4))])
15427
15428 (define_split
15429 [(set (match_operand:SWI24 0 "memory_operand")
15430 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15431 FIST_ROUNDING))
15432 (use (match_operand:HI 2 "memory_operand"))
15433 (use (match_operand:HI 3 "memory_operand"))
15434 (clobber (match_operand:SWI24 4 "memory_operand"))]
15435 "reload_completed"
15436 [(parallel [(set (match_dup 0)
15437 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15438 (use (match_dup 2))
15439 (use (match_dup 3))])])
15440
15441 (define_expand "l<rounding_insn>xf<mode>2"
15442 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15443 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15444 FIST_ROUNDING))
15445 (clobber (reg:CC FLAGS_REG))])]
15446 "TARGET_USE_FANCY_MATH_387
15447 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15448 && flag_unsafe_math_optimizations")
15449
15450 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15451 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15452 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15453 FIST_ROUNDING))
15454 (clobber (reg:CC FLAGS_REG))])]
15455 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15456 && !flag_trapping_math"
15457 {
15458 if (TARGET_64BIT && optimize_insn_for_size_p ())
15459 FAIL;
15460
15461 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15462 ix86_expand_lfloorceil (operands[0], operands[1], true);
15463 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15464 ix86_expand_lfloorceil (operands[0], operands[1], false);
15465 else
15466 gcc_unreachable ();
15467
15468 DONE;
15469 })
15470
15471 (define_insn "fxam<mode>2_i387"
15472 [(set (match_operand:HI 0 "register_operand" "=a")
15473 (unspec:HI
15474 [(match_operand:X87MODEF 1 "register_operand" "f")]
15475 UNSPEC_FXAM))]
15476 "TARGET_USE_FANCY_MATH_387"
15477 "fxam\n\tfnstsw\t%0"
15478 [(set_attr "type" "multi")
15479 (set_attr "length" "4")
15480 (set_attr "unit" "i387")
15481 (set_attr "mode" "<MODE>")])
15482
15483 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15484 [(set (match_operand:HI 0 "register_operand")
15485 (unspec:HI
15486 [(match_operand:MODEF 1 "memory_operand")]
15487 UNSPEC_FXAM_MEM))]
15488 "TARGET_USE_FANCY_MATH_387
15489 && can_create_pseudo_p ()"
15490 "#"
15491 "&& 1"
15492 [(set (match_dup 2)(match_dup 1))
15493 (set (match_dup 0)
15494 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15495 {
15496 operands[2] = gen_reg_rtx (<MODE>mode);
15497
15498 MEM_VOLATILE_P (operands[1]) = 1;
15499 }
15500 [(set_attr "type" "multi")
15501 (set_attr "unit" "i387")
15502 (set_attr "mode" "<MODE>")])
15503
15504 (define_expand "isinfxf2"
15505 [(use (match_operand:SI 0 "register_operand"))
15506 (use (match_operand:XF 1 "register_operand"))]
15507 "TARGET_USE_FANCY_MATH_387
15508 && TARGET_C99_FUNCTIONS"
15509 {
15510 rtx mask = GEN_INT (0x45);
15511 rtx val = GEN_INT (0x05);
15512
15513 rtx cond;
15514
15515 rtx scratch = gen_reg_rtx (HImode);
15516 rtx res = gen_reg_rtx (QImode);
15517
15518 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15519
15520 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15521 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15522 cond = gen_rtx_fmt_ee (EQ, QImode,
15523 gen_rtx_REG (CCmode, FLAGS_REG),
15524 const0_rtx);
15525 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15526 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15527 DONE;
15528 })
15529
15530 (define_expand "isinf<mode>2"
15531 [(use (match_operand:SI 0 "register_operand"))
15532 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15533 "TARGET_USE_FANCY_MATH_387
15534 && TARGET_C99_FUNCTIONS
15535 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15536 {
15537 rtx mask = GEN_INT (0x45);
15538 rtx val = GEN_INT (0x05);
15539
15540 rtx cond;
15541
15542 rtx scratch = gen_reg_rtx (HImode);
15543 rtx res = gen_reg_rtx (QImode);
15544
15545 /* Remove excess precision by forcing value through memory. */
15546 if (memory_operand (operands[1], VOIDmode))
15547 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15548 else
15549 {
15550 enum ix86_stack_slot slot = (virtuals_instantiated
15551 ? SLOT_TEMP
15552 : SLOT_VIRTUAL);
15553 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15554
15555 emit_move_insn (temp, operands[1]);
15556 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15557 }
15558
15559 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15560 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15561 cond = gen_rtx_fmt_ee (EQ, QImode,
15562 gen_rtx_REG (CCmode, FLAGS_REG),
15563 const0_rtx);
15564 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15565 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15566 DONE;
15567 })
15568
15569 (define_expand "signbitxf2"
15570 [(use (match_operand:SI 0 "register_operand"))
15571 (use (match_operand:XF 1 "register_operand"))]
15572 "TARGET_USE_FANCY_MATH_387"
15573 {
15574 rtx scratch = gen_reg_rtx (HImode);
15575
15576 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15577 emit_insn (gen_andsi3 (operands[0],
15578 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15579 DONE;
15580 })
15581
15582 (define_insn "movmsk_df"
15583 [(set (match_operand:SI 0 "register_operand" "=r")
15584 (unspec:SI
15585 [(match_operand:DF 1 "register_operand" "x")]
15586 UNSPEC_MOVMSK))]
15587 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15588 "%vmovmskpd\t{%1, %0|%0, %1}"
15589 [(set_attr "type" "ssemov")
15590 (set_attr "prefix" "maybe_vex")
15591 (set_attr "mode" "DF")])
15592
15593 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15594 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15595 (define_expand "signbitdf2"
15596 [(use (match_operand:SI 0 "register_operand"))
15597 (use (match_operand:DF 1 "register_operand"))]
15598 "TARGET_USE_FANCY_MATH_387
15599 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15600 {
15601 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15602 {
15603 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15604 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15605 }
15606 else
15607 {
15608 rtx scratch = gen_reg_rtx (HImode);
15609
15610 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15611 emit_insn (gen_andsi3 (operands[0],
15612 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15613 }
15614 DONE;
15615 })
15616
15617 (define_expand "signbitsf2"
15618 [(use (match_operand:SI 0 "register_operand"))
15619 (use (match_operand:SF 1 "register_operand"))]
15620 "TARGET_USE_FANCY_MATH_387
15621 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15622 {
15623 rtx scratch = gen_reg_rtx (HImode);
15624
15625 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15626 emit_insn (gen_andsi3 (operands[0],
15627 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15628 DONE;
15629 })
15630 \f
15631 ;; Block operation instructions
15632
15633 (define_insn "cld"
15634 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15635 ""
15636 "cld"
15637 [(set_attr "length" "1")
15638 (set_attr "length_immediate" "0")
15639 (set_attr "modrm" "0")])
15640
15641 (define_expand "movmem<mode>"
15642 [(use (match_operand:BLK 0 "memory_operand"))
15643 (use (match_operand:BLK 1 "memory_operand"))
15644 (use (match_operand:SWI48 2 "nonmemory_operand"))
15645 (use (match_operand:SWI48 3 "const_int_operand"))
15646 (use (match_operand:SI 4 "const_int_operand"))
15647 (use (match_operand:SI 5 "const_int_operand"))]
15648 ""
15649 {
15650 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15651 operands[4], operands[5]))
15652 DONE;
15653 else
15654 FAIL;
15655 })
15656
15657 ;; Most CPUs don't like single string operations
15658 ;; Handle this case here to simplify previous expander.
15659
15660 (define_expand "strmov"
15661 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15662 (set (match_operand 1 "memory_operand") (match_dup 4))
15663 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15664 (clobber (reg:CC FLAGS_REG))])
15665 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15666 (clobber (reg:CC FLAGS_REG))])]
15667 ""
15668 {
15669 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15670
15671 /* If .md ever supports :P for Pmode, these can be directly
15672 in the pattern above. */
15673 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15674 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15675
15676 /* Can't use this if the user has appropriated esi or edi. */
15677 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15678 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15679 {
15680 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15681 operands[2], operands[3],
15682 operands[5], operands[6]));
15683 DONE;
15684 }
15685
15686 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15687 })
15688
15689 (define_expand "strmov_singleop"
15690 [(parallel [(set (match_operand 1 "memory_operand")
15691 (match_operand 3 "memory_operand"))
15692 (set (match_operand 0 "register_operand")
15693 (match_operand 4))
15694 (set (match_operand 2 "register_operand")
15695 (match_operand 5))])]
15696 ""
15697 "ix86_current_function_needs_cld = 1;")
15698
15699 (define_insn "*strmovdi_rex_1"
15700 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15701 (mem:DI (match_operand:P 3 "register_operand" "1")))
15702 (set (match_operand:P 0 "register_operand" "=D")
15703 (plus:P (match_dup 2)
15704 (const_int 8)))
15705 (set (match_operand:P 1 "register_operand" "=S")
15706 (plus:P (match_dup 3)
15707 (const_int 8)))]
15708 "TARGET_64BIT
15709 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15710 "%^movsq"
15711 [(set_attr "type" "str")
15712 (set_attr "memory" "both")
15713 (set_attr "mode" "DI")])
15714
15715 (define_insn "*strmovsi_1"
15716 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15717 (mem:SI (match_operand:P 3 "register_operand" "1")))
15718 (set (match_operand:P 0 "register_operand" "=D")
15719 (plus:P (match_dup 2)
15720 (const_int 4)))
15721 (set (match_operand:P 1 "register_operand" "=S")
15722 (plus:P (match_dup 3)
15723 (const_int 4)))]
15724 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15725 "%^movs{l|d}"
15726 [(set_attr "type" "str")
15727 (set_attr "memory" "both")
15728 (set_attr "mode" "SI")])
15729
15730 (define_insn "*strmovhi_1"
15731 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15732 (mem:HI (match_operand:P 3 "register_operand" "1")))
15733 (set (match_operand:P 0 "register_operand" "=D")
15734 (plus:P (match_dup 2)
15735 (const_int 2)))
15736 (set (match_operand:P 1 "register_operand" "=S")
15737 (plus:P (match_dup 3)
15738 (const_int 2)))]
15739 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15740 "%^movsw"
15741 [(set_attr "type" "str")
15742 (set_attr "memory" "both")
15743 (set_attr "mode" "HI")])
15744
15745 (define_insn "*strmovqi_1"
15746 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15747 (mem:QI (match_operand:P 3 "register_operand" "1")))
15748 (set (match_operand:P 0 "register_operand" "=D")
15749 (plus:P (match_dup 2)
15750 (const_int 1)))
15751 (set (match_operand:P 1 "register_operand" "=S")
15752 (plus:P (match_dup 3)
15753 (const_int 1)))]
15754 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15755 "%^movsb"
15756 [(set_attr "type" "str")
15757 (set_attr "memory" "both")
15758 (set (attr "prefix_rex")
15759 (if_then_else
15760 (match_test "<P:MODE>mode == DImode")
15761 (const_string "0")
15762 (const_string "*")))
15763 (set_attr "mode" "QI")])
15764
15765 (define_expand "rep_mov"
15766 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15767 (set (match_operand 0 "register_operand")
15768 (match_operand 5))
15769 (set (match_operand 2 "register_operand")
15770 (match_operand 6))
15771 (set (match_operand 1 "memory_operand")
15772 (match_operand 3 "memory_operand"))
15773 (use (match_dup 4))])]
15774 ""
15775 "ix86_current_function_needs_cld = 1;")
15776
15777 (define_insn "*rep_movdi_rex64"
15778 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15779 (set (match_operand:P 0 "register_operand" "=D")
15780 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15781 (const_int 3))
15782 (match_operand:P 3 "register_operand" "0")))
15783 (set (match_operand:P 1 "register_operand" "=S")
15784 (plus:P (ashift:P (match_dup 5) (const_int 3))
15785 (match_operand:P 4 "register_operand" "1")))
15786 (set (mem:BLK (match_dup 3))
15787 (mem:BLK (match_dup 4)))
15788 (use (match_dup 5))]
15789 "TARGET_64BIT
15790 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15791 "%^rep{%;} movsq"
15792 [(set_attr "type" "str")
15793 (set_attr "prefix_rep" "1")
15794 (set_attr "memory" "both")
15795 (set_attr "mode" "DI")])
15796
15797 (define_insn "*rep_movsi"
15798 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15799 (set (match_operand:P 0 "register_operand" "=D")
15800 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15801 (const_int 2))
15802 (match_operand:P 3 "register_operand" "0")))
15803 (set (match_operand:P 1 "register_operand" "=S")
15804 (plus:P (ashift:P (match_dup 5) (const_int 2))
15805 (match_operand:P 4 "register_operand" "1")))
15806 (set (mem:BLK (match_dup 3))
15807 (mem:BLK (match_dup 4)))
15808 (use (match_dup 5))]
15809 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15810 "%^rep{%;} movs{l|d}"
15811 [(set_attr "type" "str")
15812 (set_attr "prefix_rep" "1")
15813 (set_attr "memory" "both")
15814 (set_attr "mode" "SI")])
15815
15816 (define_insn "*rep_movqi"
15817 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15818 (set (match_operand:P 0 "register_operand" "=D")
15819 (plus:P (match_operand:P 3 "register_operand" "0")
15820 (match_operand:P 5 "register_operand" "2")))
15821 (set (match_operand:P 1 "register_operand" "=S")
15822 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15823 (set (mem:BLK (match_dup 3))
15824 (mem:BLK (match_dup 4)))
15825 (use (match_dup 5))]
15826 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15827 "%^rep{%;} movsb"
15828 [(set_attr "type" "str")
15829 (set_attr "prefix_rep" "1")
15830 (set_attr "memory" "both")
15831 (set_attr "mode" "QI")])
15832
15833 (define_expand "setmem<mode>"
15834 [(use (match_operand:BLK 0 "memory_operand"))
15835 (use (match_operand:SWI48 1 "nonmemory_operand"))
15836 (use (match_operand:QI 2 "nonmemory_operand"))
15837 (use (match_operand 3 "const_int_operand"))
15838 (use (match_operand:SI 4 "const_int_operand"))
15839 (use (match_operand:SI 5 "const_int_operand"))]
15840 ""
15841 {
15842 if (ix86_expand_setmem (operands[0], operands[1],
15843 operands[2], operands[3],
15844 operands[4], operands[5]))
15845 DONE;
15846 else
15847 FAIL;
15848 })
15849
15850 ;; Most CPUs don't like single string operations
15851 ;; Handle this case here to simplify previous expander.
15852
15853 (define_expand "strset"
15854 [(set (match_operand 1 "memory_operand")
15855 (match_operand 2 "register_operand"))
15856 (parallel [(set (match_operand 0 "register_operand")
15857 (match_dup 3))
15858 (clobber (reg:CC FLAGS_REG))])]
15859 ""
15860 {
15861 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15862 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15863
15864 /* If .md ever supports :P for Pmode, this can be directly
15865 in the pattern above. */
15866 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15867 GEN_INT (GET_MODE_SIZE (GET_MODE
15868 (operands[2]))));
15869 /* Can't use this if the user has appropriated eax or edi. */
15870 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15871 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15872 {
15873 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15874 operands[3]));
15875 DONE;
15876 }
15877 })
15878
15879 (define_expand "strset_singleop"
15880 [(parallel [(set (match_operand 1 "memory_operand")
15881 (match_operand 2 "register_operand"))
15882 (set (match_operand 0 "register_operand")
15883 (match_operand 3))])]
15884 ""
15885 "ix86_current_function_needs_cld = 1;")
15886
15887 (define_insn "*strsetdi_rex_1"
15888 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15889 (match_operand:DI 2 "register_operand" "a"))
15890 (set (match_operand:P 0 "register_operand" "=D")
15891 (plus:P (match_dup 1)
15892 (const_int 8)))]
15893 "TARGET_64BIT
15894 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15895 "%^stosq"
15896 [(set_attr "type" "str")
15897 (set_attr "memory" "store")
15898 (set_attr "mode" "DI")])
15899
15900 (define_insn "*strsetsi_1"
15901 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15902 (match_operand:SI 2 "register_operand" "a"))
15903 (set (match_operand:P 0 "register_operand" "=D")
15904 (plus:P (match_dup 1)
15905 (const_int 4)))]
15906 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15907 "%^stos{l|d}"
15908 [(set_attr "type" "str")
15909 (set_attr "memory" "store")
15910 (set_attr "mode" "SI")])
15911
15912 (define_insn "*strsethi_1"
15913 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15914 (match_operand:HI 2 "register_operand" "a"))
15915 (set (match_operand:P 0 "register_operand" "=D")
15916 (plus:P (match_dup 1)
15917 (const_int 2)))]
15918 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15919 "%^stosw"
15920 [(set_attr "type" "str")
15921 (set_attr "memory" "store")
15922 (set_attr "mode" "HI")])
15923
15924 (define_insn "*strsetqi_1"
15925 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15926 (match_operand:QI 2 "register_operand" "a"))
15927 (set (match_operand:P 0 "register_operand" "=D")
15928 (plus:P (match_dup 1)
15929 (const_int 1)))]
15930 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15931 "%^stosb"
15932 [(set_attr "type" "str")
15933 (set_attr "memory" "store")
15934 (set (attr "prefix_rex")
15935 (if_then_else
15936 (match_test "<P:MODE>mode == DImode")
15937 (const_string "0")
15938 (const_string "*")))
15939 (set_attr "mode" "QI")])
15940
15941 (define_expand "rep_stos"
15942 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15943 (set (match_operand 0 "register_operand")
15944 (match_operand 4))
15945 (set (match_operand 2 "memory_operand") (const_int 0))
15946 (use (match_operand 3 "register_operand"))
15947 (use (match_dup 1))])]
15948 ""
15949 "ix86_current_function_needs_cld = 1;")
15950
15951 (define_insn "*rep_stosdi_rex64"
15952 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15953 (set (match_operand:P 0 "register_operand" "=D")
15954 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15955 (const_int 3))
15956 (match_operand:P 3 "register_operand" "0")))
15957 (set (mem:BLK (match_dup 3))
15958 (const_int 0))
15959 (use (match_operand:DI 2 "register_operand" "a"))
15960 (use (match_dup 4))]
15961 "TARGET_64BIT
15962 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15963 "%^rep{%;} stosq"
15964 [(set_attr "type" "str")
15965 (set_attr "prefix_rep" "1")
15966 (set_attr "memory" "store")
15967 (set_attr "mode" "DI")])
15968
15969 (define_insn "*rep_stossi"
15970 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15971 (set (match_operand:P 0 "register_operand" "=D")
15972 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15973 (const_int 2))
15974 (match_operand:P 3 "register_operand" "0")))
15975 (set (mem:BLK (match_dup 3))
15976 (const_int 0))
15977 (use (match_operand:SI 2 "register_operand" "a"))
15978 (use (match_dup 4))]
15979 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15980 "%^rep{%;} stos{l|d}"
15981 [(set_attr "type" "str")
15982 (set_attr "prefix_rep" "1")
15983 (set_attr "memory" "store")
15984 (set_attr "mode" "SI")])
15985
15986 (define_insn "*rep_stosqi"
15987 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15988 (set (match_operand:P 0 "register_operand" "=D")
15989 (plus:P (match_operand:P 3 "register_operand" "0")
15990 (match_operand:P 4 "register_operand" "1")))
15991 (set (mem:BLK (match_dup 3))
15992 (const_int 0))
15993 (use (match_operand:QI 2 "register_operand" "a"))
15994 (use (match_dup 4))]
15995 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15996 "%^rep{%;} stosb"
15997 [(set_attr "type" "str")
15998 (set_attr "prefix_rep" "1")
15999 (set_attr "memory" "store")
16000 (set (attr "prefix_rex")
16001 (if_then_else
16002 (match_test "<P:MODE>mode == DImode")
16003 (const_string "0")
16004 (const_string "*")))
16005 (set_attr "mode" "QI")])
16006
16007 (define_expand "cmpstrnsi"
16008 [(set (match_operand:SI 0 "register_operand")
16009 (compare:SI (match_operand:BLK 1 "general_operand")
16010 (match_operand:BLK 2 "general_operand")))
16011 (use (match_operand 3 "general_operand"))
16012 (use (match_operand 4 "immediate_operand"))]
16013 ""
16014 {
16015 rtx addr1, addr2, out, outlow, count, countreg, align;
16016
16017 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16018 FAIL;
16019
16020 /* Can't use this if the user has appropriated ecx, esi or edi. */
16021 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16022 FAIL;
16023
16024 out = operands[0];
16025 if (!REG_P (out))
16026 out = gen_reg_rtx (SImode);
16027
16028 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16029 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16030 if (addr1 != XEXP (operands[1], 0))
16031 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16032 if (addr2 != XEXP (operands[2], 0))
16033 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16034
16035 count = operands[3];
16036 countreg = ix86_zero_extend_to_Pmode (count);
16037
16038 /* %%% Iff we are testing strict equality, we can use known alignment
16039 to good advantage. This may be possible with combine, particularly
16040 once cc0 is dead. */
16041 align = operands[4];
16042
16043 if (CONST_INT_P (count))
16044 {
16045 if (INTVAL (count) == 0)
16046 {
16047 emit_move_insn (operands[0], const0_rtx);
16048 DONE;
16049 }
16050 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16051 operands[1], operands[2]));
16052 }
16053 else
16054 {
16055 rtx (*gen_cmp) (rtx, rtx);
16056
16057 gen_cmp = (TARGET_64BIT
16058 ? gen_cmpdi_1 : gen_cmpsi_1);
16059
16060 emit_insn (gen_cmp (countreg, countreg));
16061 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16062 operands[1], operands[2]));
16063 }
16064
16065 outlow = gen_lowpart (QImode, out);
16066 emit_insn (gen_cmpintqi (outlow));
16067 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16068
16069 if (operands[0] != out)
16070 emit_move_insn (operands[0], out);
16071
16072 DONE;
16073 })
16074
16075 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16076
16077 (define_expand "cmpintqi"
16078 [(set (match_dup 1)
16079 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16080 (set (match_dup 2)
16081 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16082 (parallel [(set (match_operand:QI 0 "register_operand")
16083 (minus:QI (match_dup 1)
16084 (match_dup 2)))
16085 (clobber (reg:CC FLAGS_REG))])]
16086 ""
16087 {
16088 operands[1] = gen_reg_rtx (QImode);
16089 operands[2] = gen_reg_rtx (QImode);
16090 })
16091
16092 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16093 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16094
16095 (define_expand "cmpstrnqi_nz_1"
16096 [(parallel [(set (reg:CC FLAGS_REG)
16097 (compare:CC (match_operand 4 "memory_operand")
16098 (match_operand 5 "memory_operand")))
16099 (use (match_operand 2 "register_operand"))
16100 (use (match_operand:SI 3 "immediate_operand"))
16101 (clobber (match_operand 0 "register_operand"))
16102 (clobber (match_operand 1 "register_operand"))
16103 (clobber (match_dup 2))])]
16104 ""
16105 "ix86_current_function_needs_cld = 1;")
16106
16107 (define_insn "*cmpstrnqi_nz_1"
16108 [(set (reg:CC FLAGS_REG)
16109 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16110 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16111 (use (match_operand:P 6 "register_operand" "2"))
16112 (use (match_operand:SI 3 "immediate_operand" "i"))
16113 (clobber (match_operand:P 0 "register_operand" "=S"))
16114 (clobber (match_operand:P 1 "register_operand" "=D"))
16115 (clobber (match_operand:P 2 "register_operand" "=c"))]
16116 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16117 "%^repz{%;} cmpsb"
16118 [(set_attr "type" "str")
16119 (set_attr "mode" "QI")
16120 (set (attr "prefix_rex")
16121 (if_then_else
16122 (match_test "<P:MODE>mode == DImode")
16123 (const_string "0")
16124 (const_string "*")))
16125 (set_attr "prefix_rep" "1")])
16126
16127 ;; The same, but the count is not known to not be zero.
16128
16129 (define_expand "cmpstrnqi_1"
16130 [(parallel [(set (reg:CC FLAGS_REG)
16131 (if_then_else:CC (ne (match_operand 2 "register_operand")
16132 (const_int 0))
16133 (compare:CC (match_operand 4 "memory_operand")
16134 (match_operand 5 "memory_operand"))
16135 (const_int 0)))
16136 (use (match_operand:SI 3 "immediate_operand"))
16137 (use (reg:CC FLAGS_REG))
16138 (clobber (match_operand 0 "register_operand"))
16139 (clobber (match_operand 1 "register_operand"))
16140 (clobber (match_dup 2))])]
16141 ""
16142 "ix86_current_function_needs_cld = 1;")
16143
16144 (define_insn "*cmpstrnqi_1"
16145 [(set (reg:CC FLAGS_REG)
16146 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16147 (const_int 0))
16148 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16149 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16150 (const_int 0)))
16151 (use (match_operand:SI 3 "immediate_operand" "i"))
16152 (use (reg:CC FLAGS_REG))
16153 (clobber (match_operand:P 0 "register_operand" "=S"))
16154 (clobber (match_operand:P 1 "register_operand" "=D"))
16155 (clobber (match_operand:P 2 "register_operand" "=c"))]
16156 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16157 "%^repz{%;} cmpsb"
16158 [(set_attr "type" "str")
16159 (set_attr "mode" "QI")
16160 (set (attr "prefix_rex")
16161 (if_then_else
16162 (match_test "<P:MODE>mode == DImode")
16163 (const_string "0")
16164 (const_string "*")))
16165 (set_attr "prefix_rep" "1")])
16166
16167 (define_expand "strlen<mode>"
16168 [(set (match_operand:P 0 "register_operand")
16169 (unspec:P [(match_operand:BLK 1 "general_operand")
16170 (match_operand:QI 2 "immediate_operand")
16171 (match_operand 3 "immediate_operand")]
16172 UNSPEC_SCAS))]
16173 ""
16174 {
16175 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16176 DONE;
16177 else
16178 FAIL;
16179 })
16180
16181 (define_expand "strlenqi_1"
16182 [(parallel [(set (match_operand 0 "register_operand")
16183 (match_operand 2))
16184 (clobber (match_operand 1 "register_operand"))
16185 (clobber (reg:CC FLAGS_REG))])]
16186 ""
16187 "ix86_current_function_needs_cld = 1;")
16188
16189 (define_insn "*strlenqi_1"
16190 [(set (match_operand:P 0 "register_operand" "=&c")
16191 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16192 (match_operand:QI 2 "register_operand" "a")
16193 (match_operand:P 3 "immediate_operand" "i")
16194 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16195 (clobber (match_operand:P 1 "register_operand" "=D"))
16196 (clobber (reg:CC FLAGS_REG))]
16197 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16198 "%^repnz{%;} scasb"
16199 [(set_attr "type" "str")
16200 (set_attr "mode" "QI")
16201 (set (attr "prefix_rex")
16202 (if_then_else
16203 (match_test "<P:MODE>mode == DImode")
16204 (const_string "0")
16205 (const_string "*")))
16206 (set_attr "prefix_rep" "1")])
16207
16208 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16209 ;; handled in combine, but it is not currently up to the task.
16210 ;; When used for their truth value, the cmpstrn* expanders generate
16211 ;; code like this:
16212 ;;
16213 ;; repz cmpsb
16214 ;; seta %al
16215 ;; setb %dl
16216 ;; cmpb %al, %dl
16217 ;; jcc label
16218 ;;
16219 ;; The intermediate three instructions are unnecessary.
16220
16221 ;; This one handles cmpstrn*_nz_1...
16222 (define_peephole2
16223 [(parallel[
16224 (set (reg:CC FLAGS_REG)
16225 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16226 (mem:BLK (match_operand 5 "register_operand"))))
16227 (use (match_operand 6 "register_operand"))
16228 (use (match_operand:SI 3 "immediate_operand"))
16229 (clobber (match_operand 0 "register_operand"))
16230 (clobber (match_operand 1 "register_operand"))
16231 (clobber (match_operand 2 "register_operand"))])
16232 (set (match_operand:QI 7 "register_operand")
16233 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16234 (set (match_operand:QI 8 "register_operand")
16235 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16236 (set (reg FLAGS_REG)
16237 (compare (match_dup 7) (match_dup 8)))
16238 ]
16239 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16240 [(parallel[
16241 (set (reg:CC FLAGS_REG)
16242 (compare:CC (mem:BLK (match_dup 4))
16243 (mem:BLK (match_dup 5))))
16244 (use (match_dup 6))
16245 (use (match_dup 3))
16246 (clobber (match_dup 0))
16247 (clobber (match_dup 1))
16248 (clobber (match_dup 2))])])
16249
16250 ;; ...and this one handles cmpstrn*_1.
16251 (define_peephole2
16252 [(parallel[
16253 (set (reg:CC FLAGS_REG)
16254 (if_then_else:CC (ne (match_operand 6 "register_operand")
16255 (const_int 0))
16256 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16257 (mem:BLK (match_operand 5 "register_operand")))
16258 (const_int 0)))
16259 (use (match_operand:SI 3 "immediate_operand"))
16260 (use (reg:CC FLAGS_REG))
16261 (clobber (match_operand 0 "register_operand"))
16262 (clobber (match_operand 1 "register_operand"))
16263 (clobber (match_operand 2 "register_operand"))])
16264 (set (match_operand:QI 7 "register_operand")
16265 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16266 (set (match_operand:QI 8 "register_operand")
16267 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16268 (set (reg FLAGS_REG)
16269 (compare (match_dup 7) (match_dup 8)))
16270 ]
16271 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16272 [(parallel[
16273 (set (reg:CC FLAGS_REG)
16274 (if_then_else:CC (ne (match_dup 6)
16275 (const_int 0))
16276 (compare:CC (mem:BLK (match_dup 4))
16277 (mem:BLK (match_dup 5)))
16278 (const_int 0)))
16279 (use (match_dup 3))
16280 (use (reg:CC FLAGS_REG))
16281 (clobber (match_dup 0))
16282 (clobber (match_dup 1))
16283 (clobber (match_dup 2))])])
16284 \f
16285 ;; Conditional move instructions.
16286
16287 (define_expand "mov<mode>cc"
16288 [(set (match_operand:SWIM 0 "register_operand")
16289 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16290 (match_operand:SWIM 2 "<general_operand>")
16291 (match_operand:SWIM 3 "<general_operand>")))]
16292 ""
16293 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16294
16295 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16296 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16297 ;; So just document what we're doing explicitly.
16298
16299 (define_expand "x86_mov<mode>cc_0_m1"
16300 [(parallel
16301 [(set (match_operand:SWI48 0 "register_operand")
16302 (if_then_else:SWI48
16303 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16304 [(match_operand 1 "flags_reg_operand")
16305 (const_int 0)])
16306 (const_int -1)
16307 (const_int 0)))
16308 (clobber (reg:CC FLAGS_REG))])])
16309
16310 (define_insn "*x86_mov<mode>cc_0_m1"
16311 [(set (match_operand:SWI48 0 "register_operand" "=r")
16312 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16313 [(reg FLAGS_REG) (const_int 0)])
16314 (const_int -1)
16315 (const_int 0)))
16316 (clobber (reg:CC FLAGS_REG))]
16317 ""
16318 "sbb{<imodesuffix>}\t%0, %0"
16319 ; Since we don't have the proper number of operands for an alu insn,
16320 ; fill in all the blanks.
16321 [(set_attr "type" "alu")
16322 (set_attr "use_carry" "1")
16323 (set_attr "pent_pair" "pu")
16324 (set_attr "memory" "none")
16325 (set_attr "imm_disp" "false")
16326 (set_attr "mode" "<MODE>")
16327 (set_attr "length_immediate" "0")])
16328
16329 (define_insn "*x86_mov<mode>cc_0_m1_se"
16330 [(set (match_operand:SWI48 0 "register_operand" "=r")
16331 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16332 [(reg FLAGS_REG) (const_int 0)])
16333 (const_int 1)
16334 (const_int 0)))
16335 (clobber (reg:CC FLAGS_REG))]
16336 ""
16337 "sbb{<imodesuffix>}\t%0, %0"
16338 [(set_attr "type" "alu")
16339 (set_attr "use_carry" "1")
16340 (set_attr "pent_pair" "pu")
16341 (set_attr "memory" "none")
16342 (set_attr "imm_disp" "false")
16343 (set_attr "mode" "<MODE>")
16344 (set_attr "length_immediate" "0")])
16345
16346 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16347 [(set (match_operand:SWI48 0 "register_operand" "=r")
16348 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16349 [(reg FLAGS_REG) (const_int 0)])))
16350 (clobber (reg:CC FLAGS_REG))]
16351 ""
16352 "sbb{<imodesuffix>}\t%0, %0"
16353 [(set_attr "type" "alu")
16354 (set_attr "use_carry" "1")
16355 (set_attr "pent_pair" "pu")
16356 (set_attr "memory" "none")
16357 (set_attr "imm_disp" "false")
16358 (set_attr "mode" "<MODE>")
16359 (set_attr "length_immediate" "0")])
16360
16361 (define_insn "*mov<mode>cc_noc"
16362 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16363 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16364 [(reg FLAGS_REG) (const_int 0)])
16365 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16366 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16367 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16368 "@
16369 cmov%O2%C1\t{%2, %0|%0, %2}
16370 cmov%O2%c1\t{%3, %0|%0, %3}"
16371 [(set_attr "type" "icmov")
16372 (set_attr "mode" "<MODE>")])
16373
16374 (define_insn_and_split "*movqicc_noc"
16375 [(set (match_operand:QI 0 "register_operand" "=r,r")
16376 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16377 [(match_operand 4 "flags_reg_operand")
16378 (const_int 0)])
16379 (match_operand:QI 2 "register_operand" "r,0")
16380 (match_operand:QI 3 "register_operand" "0,r")))]
16381 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16382 "#"
16383 "&& reload_completed"
16384 [(set (match_dup 0)
16385 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16386 (match_dup 2)
16387 (match_dup 3)))]
16388 "operands[0] = gen_lowpart (SImode, operands[0]);
16389 operands[2] = gen_lowpart (SImode, operands[2]);
16390 operands[3] = gen_lowpart (SImode, operands[3]);"
16391 [(set_attr "type" "icmov")
16392 (set_attr "mode" "SI")])
16393
16394 (define_expand "mov<mode>cc"
16395 [(set (match_operand:X87MODEF 0 "register_operand")
16396 (if_then_else:X87MODEF
16397 (match_operand 1 "ix86_fp_comparison_operator")
16398 (match_operand:X87MODEF 2 "register_operand")
16399 (match_operand:X87MODEF 3 "register_operand")))]
16400 "(TARGET_80387 && TARGET_CMOVE)
16401 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16402 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16403
16404 (define_insn "*movxfcc_1"
16405 [(set (match_operand:XF 0 "register_operand" "=f,f")
16406 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16407 [(reg FLAGS_REG) (const_int 0)])
16408 (match_operand:XF 2 "register_operand" "f,0")
16409 (match_operand:XF 3 "register_operand" "0,f")))]
16410 "TARGET_80387 && TARGET_CMOVE"
16411 "@
16412 fcmov%F1\t{%2, %0|%0, %2}
16413 fcmov%f1\t{%3, %0|%0, %3}"
16414 [(set_attr "type" "fcmov")
16415 (set_attr "mode" "XF")])
16416
16417 (define_insn "*movdfcc_1_rex64"
16418 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16419 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16420 [(reg FLAGS_REG) (const_int 0)])
16421 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16422 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16423 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16424 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16425 "@
16426 fcmov%F1\t{%2, %0|%0, %2}
16427 fcmov%f1\t{%3, %0|%0, %3}
16428 cmov%O2%C1\t{%2, %0|%0, %2}
16429 cmov%O2%c1\t{%3, %0|%0, %3}"
16430 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16431 (set_attr "mode" "DF,DF,DI,DI")])
16432
16433 (define_insn "*movdfcc_1"
16434 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16435 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16436 [(reg FLAGS_REG) (const_int 0)])
16437 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16438 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16439 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16440 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16441 "@
16442 fcmov%F1\t{%2, %0|%0, %2}
16443 fcmov%f1\t{%3, %0|%0, %3}
16444 #
16445 #"
16446 [(set_attr "type" "fcmov,fcmov,multi,multi")
16447 (set_attr "mode" "DF,DF,DI,DI")])
16448
16449 (define_split
16450 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16451 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16452 [(match_operand 4 "flags_reg_operand")
16453 (const_int 0)])
16454 (match_operand:DF 2 "nonimmediate_operand")
16455 (match_operand:DF 3 "nonimmediate_operand")))]
16456 "!TARGET_64BIT && reload_completed"
16457 [(set (match_dup 2)
16458 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16459 (match_dup 5)
16460 (match_dup 6)))
16461 (set (match_dup 3)
16462 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16463 (match_dup 7)
16464 (match_dup 8)))]
16465 {
16466 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16467 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16468 })
16469
16470 (define_insn "*movsfcc_1_387"
16471 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16472 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16473 [(reg FLAGS_REG) (const_int 0)])
16474 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16475 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16476 "TARGET_80387 && TARGET_CMOVE
16477 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16478 "@
16479 fcmov%F1\t{%2, %0|%0, %2}
16480 fcmov%f1\t{%3, %0|%0, %3}
16481 cmov%O2%C1\t{%2, %0|%0, %2}
16482 cmov%O2%c1\t{%3, %0|%0, %3}"
16483 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16484 (set_attr "mode" "SF,SF,SI,SI")])
16485
16486 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16487 ;; the scalar versions to have only XMM registers as operands.
16488
16489 ;; XOP conditional move
16490 (define_insn "*xop_pcmov_<mode>"
16491 [(set (match_operand:MODEF 0 "register_operand" "=x")
16492 (if_then_else:MODEF
16493 (match_operand:MODEF 1 "register_operand" "x")
16494 (match_operand:MODEF 2 "register_operand" "x")
16495 (match_operand:MODEF 3 "register_operand" "x")))]
16496 "TARGET_XOP"
16497 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16498 [(set_attr "type" "sse4arg")])
16499
16500 ;; These versions of the min/max patterns are intentionally ignorant of
16501 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16502 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16503 ;; are undefined in this condition, we're certain this is correct.
16504
16505 (define_insn "<code><mode>3"
16506 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16507 (smaxmin:MODEF
16508 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16509 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16510 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16511 "@
16512 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16513 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16514 [(set_attr "isa" "noavx,avx")
16515 (set_attr "prefix" "orig,vex")
16516 (set_attr "type" "sseadd")
16517 (set_attr "mode" "<MODE>")])
16518
16519 ;; These versions of the min/max patterns implement exactly the operations
16520 ;; min = (op1 < op2 ? op1 : op2)
16521 ;; max = (!(op1 < op2) ? op1 : op2)
16522 ;; Their operands are not commutative, and thus they may be used in the
16523 ;; presence of -0.0 and NaN.
16524
16525 (define_int_iterator IEEE_MAXMIN
16526 [UNSPEC_IEEE_MAX
16527 UNSPEC_IEEE_MIN])
16528
16529 (define_int_attr ieee_maxmin
16530 [(UNSPEC_IEEE_MAX "max")
16531 (UNSPEC_IEEE_MIN "min")])
16532
16533 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16534 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16535 (unspec:MODEF
16536 [(match_operand:MODEF 1 "register_operand" "0,x")
16537 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16538 IEEE_MAXMIN))]
16539 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16540 "@
16541 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16542 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16543 [(set_attr "isa" "noavx,avx")
16544 (set_attr "prefix" "orig,vex")
16545 (set_attr "type" "sseadd")
16546 (set_attr "mode" "<MODE>")])
16547
16548 ;; Make two stack loads independent:
16549 ;; fld aa fld aa
16550 ;; fld %st(0) -> fld bb
16551 ;; fmul bb fmul %st(1), %st
16552 ;;
16553 ;; Actually we only match the last two instructions for simplicity.
16554 (define_peephole2
16555 [(set (match_operand 0 "fp_register_operand")
16556 (match_operand 1 "fp_register_operand"))
16557 (set (match_dup 0)
16558 (match_operator 2 "binary_fp_operator"
16559 [(match_dup 0)
16560 (match_operand 3 "memory_operand")]))]
16561 "REGNO (operands[0]) != REGNO (operands[1])"
16562 [(set (match_dup 0) (match_dup 3))
16563 (set (match_dup 0) (match_dup 4))]
16564
16565 ;; The % modifier is not operational anymore in peephole2's, so we have to
16566 ;; swap the operands manually in the case of addition and multiplication.
16567 {
16568 rtx op0, op1;
16569
16570 if (COMMUTATIVE_ARITH_P (operands[2]))
16571 op0 = operands[0], op1 = operands[1];
16572 else
16573 op0 = operands[1], op1 = operands[0];
16574
16575 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16576 GET_MODE (operands[2]),
16577 op0, op1);
16578 })
16579
16580 ;; Conditional addition patterns
16581 (define_expand "add<mode>cc"
16582 [(match_operand:SWI 0 "register_operand")
16583 (match_operand 1 "ordered_comparison_operator")
16584 (match_operand:SWI 2 "register_operand")
16585 (match_operand:SWI 3 "const_int_operand")]
16586 ""
16587 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16588 \f
16589 ;; Misc patterns (?)
16590
16591 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16592 ;; Otherwise there will be nothing to keep
16593 ;;
16594 ;; [(set (reg ebp) (reg esp))]
16595 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16596 ;; (clobber (eflags)]
16597 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16598 ;;
16599 ;; in proper program order.
16600
16601 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16602 [(set (match_operand:P 0 "register_operand" "=r,r")
16603 (plus:P (match_operand:P 1 "register_operand" "0,r")
16604 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16605 (clobber (reg:CC FLAGS_REG))
16606 (clobber (mem:BLK (scratch)))]
16607 ""
16608 {
16609 switch (get_attr_type (insn))
16610 {
16611 case TYPE_IMOV:
16612 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16613
16614 case TYPE_ALU:
16615 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16616 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16617 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16618
16619 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16620
16621 default:
16622 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16623 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16624 }
16625 }
16626 [(set (attr "type")
16627 (cond [(and (eq_attr "alternative" "0")
16628 (not (match_test "TARGET_OPT_AGU")))
16629 (const_string "alu")
16630 (match_operand:<MODE> 2 "const0_operand")
16631 (const_string "imov")
16632 ]
16633 (const_string "lea")))
16634 (set (attr "length_immediate")
16635 (cond [(eq_attr "type" "imov")
16636 (const_string "0")
16637 (and (eq_attr "type" "alu")
16638 (match_operand 2 "const128_operand"))
16639 (const_string "1")
16640 ]
16641 (const_string "*")))
16642 (set_attr "mode" "<MODE>")])
16643
16644 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16645 [(set (match_operand:P 0 "register_operand" "=r")
16646 (minus:P (match_operand:P 1 "register_operand" "0")
16647 (match_operand:P 2 "register_operand" "r")))
16648 (clobber (reg:CC FLAGS_REG))
16649 (clobber (mem:BLK (scratch)))]
16650 ""
16651 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16652 [(set_attr "type" "alu")
16653 (set_attr "mode" "<MODE>")])
16654
16655 (define_insn "allocate_stack_worker_probe_<mode>"
16656 [(set (match_operand:P 0 "register_operand" "=a")
16657 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16658 UNSPECV_STACK_PROBE))
16659 (clobber (reg:CC FLAGS_REG))]
16660 "ix86_target_stack_probe ()"
16661 "call\t___chkstk_ms"
16662 [(set_attr "type" "multi")
16663 (set_attr "length" "5")])
16664
16665 (define_expand "allocate_stack"
16666 [(match_operand 0 "register_operand")
16667 (match_operand 1 "general_operand")]
16668 "ix86_target_stack_probe ()"
16669 {
16670 rtx x;
16671
16672 #ifndef CHECK_STACK_LIMIT
16673 #define CHECK_STACK_LIMIT 0
16674 #endif
16675
16676 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16677 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16678 x = operands[1];
16679 else
16680 {
16681 rtx (*insn) (rtx, rtx);
16682
16683 x = copy_to_mode_reg (Pmode, operands[1]);
16684
16685 insn = (TARGET_64BIT
16686 ? gen_allocate_stack_worker_probe_di
16687 : gen_allocate_stack_worker_probe_si);
16688
16689 emit_insn (insn (x, x));
16690 }
16691
16692 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16693 stack_pointer_rtx, 0, OPTAB_DIRECT);
16694
16695 if (x != stack_pointer_rtx)
16696 emit_move_insn (stack_pointer_rtx, x);
16697
16698 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16699 DONE;
16700 })
16701
16702 ;; Use IOR for stack probes, this is shorter.
16703 (define_expand "probe_stack"
16704 [(match_operand 0 "memory_operand")]
16705 ""
16706 {
16707 rtx (*gen_ior3) (rtx, rtx, rtx);
16708
16709 gen_ior3 = (GET_MODE (operands[0]) == DImode
16710 ? gen_iordi3 : gen_iorsi3);
16711
16712 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16713 DONE;
16714 })
16715
16716 (define_insn "adjust_stack_and_probe<mode>"
16717 [(set (match_operand:P 0 "register_operand" "=r")
16718 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16719 UNSPECV_PROBE_STACK_RANGE))
16720 (set (reg:P SP_REG)
16721 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16722 (clobber (reg:CC FLAGS_REG))
16723 (clobber (mem:BLK (scratch)))]
16724 ""
16725 "* return output_adjust_stack_and_probe (operands[0]);"
16726 [(set_attr "type" "multi")])
16727
16728 (define_insn "probe_stack_range<mode>"
16729 [(set (match_operand:P 0 "register_operand" "=r")
16730 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16731 (match_operand:P 2 "const_int_operand" "n")]
16732 UNSPECV_PROBE_STACK_RANGE))
16733 (clobber (reg:CC FLAGS_REG))]
16734 ""
16735 "* return output_probe_stack_range (operands[0], operands[2]);"
16736 [(set_attr "type" "multi")])
16737
16738 (define_expand "builtin_setjmp_receiver"
16739 [(label_ref (match_operand 0))]
16740 "!TARGET_64BIT && flag_pic"
16741 {
16742 #if TARGET_MACHO
16743 if (TARGET_MACHO)
16744 {
16745 rtx xops[3];
16746 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16747 rtx label_rtx = gen_label_rtx ();
16748 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16749 xops[0] = xops[1] = picreg;
16750 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16751 ix86_expand_binary_operator (MINUS, SImode, xops);
16752 }
16753 else
16754 #endif
16755 emit_insn (gen_set_got (pic_offset_table_rtx));
16756 DONE;
16757 })
16758 \f
16759 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16760
16761 (define_split
16762 [(set (match_operand 0 "register_operand")
16763 (match_operator 3 "promotable_binary_operator"
16764 [(match_operand 1 "register_operand")
16765 (match_operand 2 "aligned_operand")]))
16766 (clobber (reg:CC FLAGS_REG))]
16767 "! TARGET_PARTIAL_REG_STALL && reload_completed
16768 && ((GET_MODE (operands[0]) == HImode
16769 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16770 /* ??? next two lines just !satisfies_constraint_K (...) */
16771 || !CONST_INT_P (operands[2])
16772 || satisfies_constraint_K (operands[2])))
16773 || (GET_MODE (operands[0]) == QImode
16774 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16775 [(parallel [(set (match_dup 0)
16776 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16777 (clobber (reg:CC FLAGS_REG))])]
16778 {
16779 operands[0] = gen_lowpart (SImode, operands[0]);
16780 operands[1] = gen_lowpart (SImode, operands[1]);
16781 if (GET_CODE (operands[3]) != ASHIFT)
16782 operands[2] = gen_lowpart (SImode, operands[2]);
16783 PUT_MODE (operands[3], SImode);
16784 })
16785
16786 ; Promote the QImode tests, as i386 has encoding of the AND
16787 ; instruction with 32-bit sign-extended immediate and thus the
16788 ; instruction size is unchanged, except in the %eax case for
16789 ; which it is increased by one byte, hence the ! optimize_size.
16790 (define_split
16791 [(set (match_operand 0 "flags_reg_operand")
16792 (match_operator 2 "compare_operator"
16793 [(and (match_operand 3 "aligned_operand")
16794 (match_operand 4 "const_int_operand"))
16795 (const_int 0)]))
16796 (set (match_operand 1 "register_operand")
16797 (and (match_dup 3) (match_dup 4)))]
16798 "! TARGET_PARTIAL_REG_STALL && reload_completed
16799 && optimize_insn_for_speed_p ()
16800 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16801 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16802 /* Ensure that the operand will remain sign-extended immediate. */
16803 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16804 [(parallel [(set (match_dup 0)
16805 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16806 (const_int 0)]))
16807 (set (match_dup 1)
16808 (and:SI (match_dup 3) (match_dup 4)))])]
16809 {
16810 operands[4]
16811 = gen_int_mode (INTVAL (operands[4])
16812 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16813 operands[1] = gen_lowpart (SImode, operands[1]);
16814 operands[3] = gen_lowpart (SImode, operands[3]);
16815 })
16816
16817 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16818 ; the TEST instruction with 32-bit sign-extended immediate and thus
16819 ; the instruction size would at least double, which is not what we
16820 ; want even with ! optimize_size.
16821 (define_split
16822 [(set (match_operand 0 "flags_reg_operand")
16823 (match_operator 1 "compare_operator"
16824 [(and (match_operand:HI 2 "aligned_operand")
16825 (match_operand:HI 3 "const_int_operand"))
16826 (const_int 0)]))]
16827 "! TARGET_PARTIAL_REG_STALL && reload_completed
16828 && ! TARGET_FAST_PREFIX
16829 && optimize_insn_for_speed_p ()
16830 /* Ensure that the operand will remain sign-extended immediate. */
16831 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16832 [(set (match_dup 0)
16833 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16834 (const_int 0)]))]
16835 {
16836 operands[3]
16837 = gen_int_mode (INTVAL (operands[3])
16838 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16839 operands[2] = gen_lowpart (SImode, operands[2]);
16840 })
16841
16842 (define_split
16843 [(set (match_operand 0 "register_operand")
16844 (neg (match_operand 1 "register_operand")))
16845 (clobber (reg:CC FLAGS_REG))]
16846 "! TARGET_PARTIAL_REG_STALL && reload_completed
16847 && (GET_MODE (operands[0]) == HImode
16848 || (GET_MODE (operands[0]) == QImode
16849 && (TARGET_PROMOTE_QImode
16850 || optimize_insn_for_size_p ())))"
16851 [(parallel [(set (match_dup 0)
16852 (neg:SI (match_dup 1)))
16853 (clobber (reg:CC FLAGS_REG))])]
16854 {
16855 operands[0] = gen_lowpart (SImode, operands[0]);
16856 operands[1] = gen_lowpart (SImode, operands[1]);
16857 })
16858
16859 (define_split
16860 [(set (match_operand 0 "register_operand")
16861 (not (match_operand 1 "register_operand")))]
16862 "! TARGET_PARTIAL_REG_STALL && reload_completed
16863 && (GET_MODE (operands[0]) == HImode
16864 || (GET_MODE (operands[0]) == QImode
16865 && (TARGET_PROMOTE_QImode
16866 || optimize_insn_for_size_p ())))"
16867 [(set (match_dup 0)
16868 (not:SI (match_dup 1)))]
16869 {
16870 operands[0] = gen_lowpart (SImode, operands[0]);
16871 operands[1] = gen_lowpart (SImode, operands[1]);
16872 })
16873
16874 (define_split
16875 [(set (match_operand 0 "register_operand")
16876 (if_then_else (match_operator 1 "ordered_comparison_operator"
16877 [(reg FLAGS_REG) (const_int 0)])
16878 (match_operand 2 "register_operand")
16879 (match_operand 3 "register_operand")))]
16880 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16881 && (GET_MODE (operands[0]) == HImode
16882 || (GET_MODE (operands[0]) == QImode
16883 && (TARGET_PROMOTE_QImode
16884 || optimize_insn_for_size_p ())))"
16885 [(set (match_dup 0)
16886 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16887 {
16888 operands[0] = gen_lowpart (SImode, operands[0]);
16889 operands[2] = gen_lowpart (SImode, operands[2]);
16890 operands[3] = gen_lowpart (SImode, operands[3]);
16891 })
16892 \f
16893 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16894 ;; transform a complex memory operation into two memory to register operations.
16895
16896 ;; Don't push memory operands
16897 (define_peephole2
16898 [(set (match_operand:SWI 0 "push_operand")
16899 (match_operand:SWI 1 "memory_operand"))
16900 (match_scratch:SWI 2 "<r>")]
16901 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16902 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16903 [(set (match_dup 2) (match_dup 1))
16904 (set (match_dup 0) (match_dup 2))])
16905
16906 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16907 ;; SImode pushes.
16908 (define_peephole2
16909 [(set (match_operand:SF 0 "push_operand")
16910 (match_operand:SF 1 "memory_operand"))
16911 (match_scratch:SF 2 "r")]
16912 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16913 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16914 [(set (match_dup 2) (match_dup 1))
16915 (set (match_dup 0) (match_dup 2))])
16916
16917 ;; Don't move an immediate directly to memory when the instruction
16918 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16919 (define_peephole2
16920 [(match_scratch:SWI124 1 "<r>")
16921 (set (match_operand:SWI124 0 "memory_operand")
16922 (const_int 0))]
16923 "optimize_insn_for_speed_p ()
16924 && ((<MODE>mode == HImode
16925 && TARGET_LCP_STALL)
16926 || (!TARGET_USE_MOV0
16927 && TARGET_SPLIT_LONG_MOVES
16928 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16929 && peep2_regno_dead_p (0, FLAGS_REG)"
16930 [(parallel [(set (match_dup 2) (const_int 0))
16931 (clobber (reg:CC FLAGS_REG))])
16932 (set (match_dup 0) (match_dup 1))]
16933 "operands[2] = gen_lowpart (SImode, operands[1]);")
16934
16935 (define_peephole2
16936 [(match_scratch:SWI124 2 "<r>")
16937 (set (match_operand:SWI124 0 "memory_operand")
16938 (match_operand:SWI124 1 "immediate_operand"))]
16939 "optimize_insn_for_speed_p ()
16940 && ((<MODE>mode == HImode
16941 && TARGET_LCP_STALL)
16942 || (TARGET_SPLIT_LONG_MOVES
16943 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16944 [(set (match_dup 2) (match_dup 1))
16945 (set (match_dup 0) (match_dup 2))])
16946
16947 ;; Don't compare memory with zero, load and use a test instead.
16948 (define_peephole2
16949 [(set (match_operand 0 "flags_reg_operand")
16950 (match_operator 1 "compare_operator"
16951 [(match_operand:SI 2 "memory_operand")
16952 (const_int 0)]))
16953 (match_scratch:SI 3 "r")]
16954 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16955 [(set (match_dup 3) (match_dup 2))
16956 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16957
16958 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16959 ;; Don't split NOTs with a displacement operand, because resulting XOR
16960 ;; will not be pairable anyway.
16961 ;;
16962 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16963 ;; represented using a modRM byte. The XOR replacement is long decoded,
16964 ;; so this split helps here as well.
16965 ;;
16966 ;; Note: Can't do this as a regular split because we can't get proper
16967 ;; lifetime information then.
16968
16969 (define_peephole2
16970 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16971 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16972 "optimize_insn_for_speed_p ()
16973 && ((TARGET_NOT_UNPAIRABLE
16974 && (!MEM_P (operands[0])
16975 || !memory_displacement_operand (operands[0], <MODE>mode)))
16976 || (TARGET_NOT_VECTORMODE
16977 && long_memory_operand (operands[0], <MODE>mode)))
16978 && peep2_regno_dead_p (0, FLAGS_REG)"
16979 [(parallel [(set (match_dup 0)
16980 (xor:SWI124 (match_dup 1) (const_int -1)))
16981 (clobber (reg:CC FLAGS_REG))])])
16982
16983 ;; Non pairable "test imm, reg" instructions can be translated to
16984 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16985 ;; byte opcode instead of two, have a short form for byte operands),
16986 ;; so do it for other CPUs as well. Given that the value was dead,
16987 ;; this should not create any new dependencies. Pass on the sub-word
16988 ;; versions if we're concerned about partial register stalls.
16989
16990 (define_peephole2
16991 [(set (match_operand 0 "flags_reg_operand")
16992 (match_operator 1 "compare_operator"
16993 [(and:SI (match_operand:SI 2 "register_operand")
16994 (match_operand:SI 3 "immediate_operand"))
16995 (const_int 0)]))]
16996 "ix86_match_ccmode (insn, CCNOmode)
16997 && (true_regnum (operands[2]) != AX_REG
16998 || satisfies_constraint_K (operands[3]))
16999 && peep2_reg_dead_p (1, operands[2])"
17000 [(parallel
17001 [(set (match_dup 0)
17002 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17003 (const_int 0)]))
17004 (set (match_dup 2)
17005 (and:SI (match_dup 2) (match_dup 3)))])])
17006
17007 ;; We don't need to handle HImode case, because it will be promoted to SImode
17008 ;; on ! TARGET_PARTIAL_REG_STALL
17009
17010 (define_peephole2
17011 [(set (match_operand 0 "flags_reg_operand")
17012 (match_operator 1 "compare_operator"
17013 [(and:QI (match_operand:QI 2 "register_operand")
17014 (match_operand:QI 3 "immediate_operand"))
17015 (const_int 0)]))]
17016 "! TARGET_PARTIAL_REG_STALL
17017 && ix86_match_ccmode (insn, CCNOmode)
17018 && true_regnum (operands[2]) != AX_REG
17019 && peep2_reg_dead_p (1, operands[2])"
17020 [(parallel
17021 [(set (match_dup 0)
17022 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17023 (const_int 0)]))
17024 (set (match_dup 2)
17025 (and:QI (match_dup 2) (match_dup 3)))])])
17026
17027 (define_peephole2
17028 [(set (match_operand 0 "flags_reg_operand")
17029 (match_operator 1 "compare_operator"
17030 [(and:SI
17031 (zero_extract:SI
17032 (match_operand 2 "ext_register_operand")
17033 (const_int 8)
17034 (const_int 8))
17035 (match_operand 3 "const_int_operand"))
17036 (const_int 0)]))]
17037 "! TARGET_PARTIAL_REG_STALL
17038 && ix86_match_ccmode (insn, CCNOmode)
17039 && true_regnum (operands[2]) != AX_REG
17040 && peep2_reg_dead_p (1, operands[2])"
17041 [(parallel [(set (match_dup 0)
17042 (match_op_dup 1
17043 [(and:SI
17044 (zero_extract:SI
17045 (match_dup 2)
17046 (const_int 8)
17047 (const_int 8))
17048 (match_dup 3))
17049 (const_int 0)]))
17050 (set (zero_extract:SI (match_dup 2)
17051 (const_int 8)
17052 (const_int 8))
17053 (and:SI
17054 (zero_extract:SI
17055 (match_dup 2)
17056 (const_int 8)
17057 (const_int 8))
17058 (match_dup 3)))])])
17059
17060 ;; Don't do logical operations with memory inputs.
17061 (define_peephole2
17062 [(match_scratch:SI 2 "r")
17063 (parallel [(set (match_operand:SI 0 "register_operand")
17064 (match_operator:SI 3 "arith_or_logical_operator"
17065 [(match_dup 0)
17066 (match_operand:SI 1 "memory_operand")]))
17067 (clobber (reg:CC FLAGS_REG))])]
17068 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17069 [(set (match_dup 2) (match_dup 1))
17070 (parallel [(set (match_dup 0)
17071 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17072 (clobber (reg:CC FLAGS_REG))])])
17073
17074 (define_peephole2
17075 [(match_scratch:SI 2 "r")
17076 (parallel [(set (match_operand:SI 0 "register_operand")
17077 (match_operator:SI 3 "arith_or_logical_operator"
17078 [(match_operand:SI 1 "memory_operand")
17079 (match_dup 0)]))
17080 (clobber (reg:CC FLAGS_REG))])]
17081 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17082 [(set (match_dup 2) (match_dup 1))
17083 (parallel [(set (match_dup 0)
17084 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17085 (clobber (reg:CC FLAGS_REG))])])
17086
17087 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17088 ;; refers to the destination of the load!
17089
17090 (define_peephole2
17091 [(set (match_operand:SI 0 "register_operand")
17092 (match_operand:SI 1 "register_operand"))
17093 (parallel [(set (match_dup 0)
17094 (match_operator:SI 3 "commutative_operator"
17095 [(match_dup 0)
17096 (match_operand:SI 2 "memory_operand")]))
17097 (clobber (reg:CC FLAGS_REG))])]
17098 "REGNO (operands[0]) != REGNO (operands[1])
17099 && GENERAL_REGNO_P (REGNO (operands[0]))
17100 && GENERAL_REGNO_P (REGNO (operands[1]))"
17101 [(set (match_dup 0) (match_dup 4))
17102 (parallel [(set (match_dup 0)
17103 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17104 (clobber (reg:CC FLAGS_REG))])]
17105 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17106
17107 (define_peephole2
17108 [(set (match_operand 0 "register_operand")
17109 (match_operand 1 "register_operand"))
17110 (set (match_dup 0)
17111 (match_operator 3 "commutative_operator"
17112 [(match_dup 0)
17113 (match_operand 2 "memory_operand")]))]
17114 "REGNO (operands[0]) != REGNO (operands[1])
17115 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17116 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17117 [(set (match_dup 0) (match_dup 2))
17118 (set (match_dup 0)
17119 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17120
17121 ; Don't do logical operations with memory outputs
17122 ;
17123 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17124 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17125 ; the same decoder scheduling characteristics as the original.
17126
17127 (define_peephole2
17128 [(match_scratch:SI 2 "r")
17129 (parallel [(set (match_operand:SI 0 "memory_operand")
17130 (match_operator:SI 3 "arith_or_logical_operator"
17131 [(match_dup 0)
17132 (match_operand:SI 1 "nonmemory_operand")]))
17133 (clobber (reg:CC FLAGS_REG))])]
17134 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17135 /* Do not split stack checking probes. */
17136 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17137 [(set (match_dup 2) (match_dup 0))
17138 (parallel [(set (match_dup 2)
17139 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17140 (clobber (reg:CC FLAGS_REG))])
17141 (set (match_dup 0) (match_dup 2))])
17142
17143 (define_peephole2
17144 [(match_scratch:SI 2 "r")
17145 (parallel [(set (match_operand:SI 0 "memory_operand")
17146 (match_operator:SI 3 "arith_or_logical_operator"
17147 [(match_operand:SI 1 "nonmemory_operand")
17148 (match_dup 0)]))
17149 (clobber (reg:CC FLAGS_REG))])]
17150 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17151 /* Do not split stack checking probes. */
17152 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17153 [(set (match_dup 2) (match_dup 0))
17154 (parallel [(set (match_dup 2)
17155 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17156 (clobber (reg:CC FLAGS_REG))])
17157 (set (match_dup 0) (match_dup 2))])
17158
17159 ;; Attempt to use arith or logical operations with memory outputs with
17160 ;; setting of flags.
17161 (define_peephole2
17162 [(set (match_operand:SWI 0 "register_operand")
17163 (match_operand:SWI 1 "memory_operand"))
17164 (parallel [(set (match_dup 0)
17165 (match_operator:SWI 3 "plusminuslogic_operator"
17166 [(match_dup 0)
17167 (match_operand:SWI 2 "<nonmemory_operand>")]))
17168 (clobber (reg:CC FLAGS_REG))])
17169 (set (match_dup 1) (match_dup 0))
17170 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17171 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17172 && peep2_reg_dead_p (4, operands[0])
17173 && !reg_overlap_mentioned_p (operands[0], operands[1])
17174 && (<MODE>mode != QImode
17175 || immediate_operand (operands[2], QImode)
17176 || q_regs_operand (operands[2], QImode))
17177 && ix86_match_ccmode (peep2_next_insn (3),
17178 (GET_CODE (operands[3]) == PLUS
17179 || GET_CODE (operands[3]) == MINUS)
17180 ? CCGOCmode : CCNOmode)"
17181 [(parallel [(set (match_dup 4) (match_dup 5))
17182 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17183 (match_dup 2)]))])]
17184 {
17185 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17186 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17187 copy_rtx (operands[1]),
17188 copy_rtx (operands[2]));
17189 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17190 operands[5], const0_rtx);
17191 })
17192
17193 (define_peephole2
17194 [(parallel [(set (match_operand:SWI 0 "register_operand")
17195 (match_operator:SWI 2 "plusminuslogic_operator"
17196 [(match_dup 0)
17197 (match_operand:SWI 1 "memory_operand")]))
17198 (clobber (reg:CC FLAGS_REG))])
17199 (set (match_dup 1) (match_dup 0))
17200 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17201 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17202 && GET_CODE (operands[2]) != MINUS
17203 && peep2_reg_dead_p (3, operands[0])
17204 && !reg_overlap_mentioned_p (operands[0], operands[1])
17205 && ix86_match_ccmode (peep2_next_insn (2),
17206 GET_CODE (operands[2]) == PLUS
17207 ? CCGOCmode : CCNOmode)"
17208 [(parallel [(set (match_dup 3) (match_dup 4))
17209 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17210 (match_dup 0)]))])]
17211 {
17212 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17213 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17214 copy_rtx (operands[1]),
17215 copy_rtx (operands[0]));
17216 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17217 operands[4], const0_rtx);
17218 })
17219
17220 (define_peephole2
17221 [(set (match_operand:SWI12 0 "register_operand")
17222 (match_operand:SWI12 1 "memory_operand"))
17223 (parallel [(set (match_operand:SI 4 "register_operand")
17224 (match_operator:SI 3 "plusminuslogic_operator"
17225 [(match_dup 4)
17226 (match_operand:SI 2 "nonmemory_operand")]))
17227 (clobber (reg:CC FLAGS_REG))])
17228 (set (match_dup 1) (match_dup 0))
17229 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17230 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17231 && REG_P (operands[0]) && REG_P (operands[4])
17232 && REGNO (operands[0]) == REGNO (operands[4])
17233 && peep2_reg_dead_p (4, operands[0])
17234 && (<MODE>mode != QImode
17235 || immediate_operand (operands[2], SImode)
17236 || q_regs_operand (operands[2], SImode))
17237 && !reg_overlap_mentioned_p (operands[0], operands[1])
17238 && ix86_match_ccmode (peep2_next_insn (3),
17239 (GET_CODE (operands[3]) == PLUS
17240 || GET_CODE (operands[3]) == MINUS)
17241 ? CCGOCmode : CCNOmode)"
17242 [(parallel [(set (match_dup 4) (match_dup 5))
17243 (set (match_dup 1) (match_dup 6))])]
17244 {
17245 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17246 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17247 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17248 copy_rtx (operands[1]), operands[2]);
17249 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17250 operands[5], const0_rtx);
17251 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17252 copy_rtx (operands[1]),
17253 copy_rtx (operands[2]));
17254 })
17255
17256 ;; Attempt to always use XOR for zeroing registers.
17257 (define_peephole2
17258 [(set (match_operand 0 "register_operand")
17259 (match_operand 1 "const0_operand"))]
17260 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17261 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17262 && GENERAL_REG_P (operands[0])
17263 && peep2_regno_dead_p (0, FLAGS_REG)"
17264 [(parallel [(set (match_dup 0) (const_int 0))
17265 (clobber (reg:CC FLAGS_REG))])]
17266 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17267
17268 (define_peephole2
17269 [(set (strict_low_part (match_operand 0 "register_operand"))
17270 (const_int 0))]
17271 "(GET_MODE (operands[0]) == QImode
17272 || GET_MODE (operands[0]) == HImode)
17273 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17274 && peep2_regno_dead_p (0, FLAGS_REG)"
17275 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17276 (clobber (reg:CC FLAGS_REG))])])
17277
17278 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17279 (define_peephole2
17280 [(set (match_operand:SWI248 0 "register_operand")
17281 (const_int -1))]
17282 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17283 && peep2_regno_dead_p (0, FLAGS_REG)"
17284 [(parallel [(set (match_dup 0) (const_int -1))
17285 (clobber (reg:CC FLAGS_REG))])]
17286 {
17287 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17288 operands[0] = gen_lowpart (SImode, operands[0]);
17289 })
17290
17291 ;; Attempt to convert simple lea to add/shift.
17292 ;; These can be created by move expanders.
17293
17294 (define_peephole2
17295 [(set (match_operand:SWI48 0 "register_operand")
17296 (plus:SWI48 (match_dup 0)
17297 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17298 "peep2_regno_dead_p (0, FLAGS_REG)"
17299 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17300 (clobber (reg:CC FLAGS_REG))])])
17301
17302 (define_peephole2
17303 [(set (match_operand:SI 0 "register_operand")
17304 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17305 (match_operand:DI 2 "nonmemory_operand")) 0))]
17306 "TARGET_64BIT
17307 && peep2_regno_dead_p (0, FLAGS_REG)
17308 && REGNO (operands[0]) == REGNO (operands[1])"
17309 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17310 (clobber (reg:CC FLAGS_REG))])]
17311 "operands[2] = gen_lowpart (SImode, operands[2]);")
17312
17313 (define_peephole2
17314 [(set (match_operand:SWI48 0 "register_operand")
17315 (mult:SWI48 (match_dup 0)
17316 (match_operand:SWI48 1 "const_int_operand")))]
17317 "exact_log2 (INTVAL (operands[1])) >= 0
17318 && peep2_regno_dead_p (0, FLAGS_REG)"
17319 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17320 (clobber (reg:CC FLAGS_REG))])]
17321 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17322
17323 (define_peephole2
17324 [(set (match_operand:SI 0 "register_operand")
17325 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17326 (match_operand:DI 2 "const_int_operand")) 0))]
17327 "TARGET_64BIT
17328 && exact_log2 (INTVAL (operands[2])) >= 0
17329 && REGNO (operands[0]) == REGNO (operands[1])
17330 && peep2_regno_dead_p (0, FLAGS_REG)"
17331 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17332 (clobber (reg:CC FLAGS_REG))])]
17333 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17334
17335 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17336 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17337 ;; On many CPUs it is also faster, since special hardware to avoid esp
17338 ;; dependencies is present.
17339
17340 ;; While some of these conversions may be done using splitters, we use
17341 ;; peepholes in order to allow combine_stack_adjustments pass to see
17342 ;; nonobfuscated RTL.
17343
17344 ;; Convert prologue esp subtractions to push.
17345 ;; We need register to push. In order to keep verify_flow_info happy we have
17346 ;; two choices
17347 ;; - use scratch and clobber it in order to avoid dependencies
17348 ;; - use already live register
17349 ;; We can't use the second way right now, since there is no reliable way how to
17350 ;; verify that given register is live. First choice will also most likely in
17351 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17352 ;; call clobbered registers are dead. We may want to use base pointer as an
17353 ;; alternative when no register is available later.
17354
17355 (define_peephole2
17356 [(match_scratch:W 1 "r")
17357 (parallel [(set (reg:P SP_REG)
17358 (plus:P (reg:P SP_REG)
17359 (match_operand:P 0 "const_int_operand")))
17360 (clobber (reg:CC FLAGS_REG))
17361 (clobber (mem:BLK (scratch)))])]
17362 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17363 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17364 [(clobber (match_dup 1))
17365 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17366 (clobber (mem:BLK (scratch)))])])
17367
17368 (define_peephole2
17369 [(match_scratch:W 1 "r")
17370 (parallel [(set (reg:P SP_REG)
17371 (plus:P (reg:P SP_REG)
17372 (match_operand:P 0 "const_int_operand")))
17373 (clobber (reg:CC FLAGS_REG))
17374 (clobber (mem:BLK (scratch)))])]
17375 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17376 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17377 [(clobber (match_dup 1))
17378 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17379 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17380 (clobber (mem:BLK (scratch)))])])
17381
17382 ;; Convert esp subtractions to push.
17383 (define_peephole2
17384 [(match_scratch:W 1 "r")
17385 (parallel [(set (reg:P SP_REG)
17386 (plus:P (reg:P SP_REG)
17387 (match_operand:P 0 "const_int_operand")))
17388 (clobber (reg:CC FLAGS_REG))])]
17389 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17390 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17391 [(clobber (match_dup 1))
17392 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17393
17394 (define_peephole2
17395 [(match_scratch:W 1 "r")
17396 (parallel [(set (reg:P SP_REG)
17397 (plus:P (reg:P SP_REG)
17398 (match_operand:P 0 "const_int_operand")))
17399 (clobber (reg:CC FLAGS_REG))])]
17400 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17401 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17402 [(clobber (match_dup 1))
17403 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17404 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17405
17406 ;; Convert epilogue deallocator to pop.
17407 (define_peephole2
17408 [(match_scratch:W 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 (clobber (mem:BLK (scratch)))])]
17414 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17415 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17416 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17417 (clobber (mem:BLK (scratch)))])])
17418
17419 ;; Two pops case is tricky, since pop causes dependency
17420 ;; on destination register. We use two registers if available.
17421 (define_peephole2
17422 [(match_scratch:W 1 "r")
17423 (match_scratch:W 2 "r")
17424 (parallel [(set (reg:P SP_REG)
17425 (plus:P (reg:P SP_REG)
17426 (match_operand:P 0 "const_int_operand")))
17427 (clobber (reg:CC FLAGS_REG))
17428 (clobber (mem:BLK (scratch)))])]
17429 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17430 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17431 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17432 (clobber (mem:BLK (scratch)))])
17433 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17434
17435 (define_peephole2
17436 [(match_scratch:W 1 "r")
17437 (parallel [(set (reg:P SP_REG)
17438 (plus:P (reg:P SP_REG)
17439 (match_operand:P 0 "const_int_operand")))
17440 (clobber (reg:CC FLAGS_REG))
17441 (clobber (mem:BLK (scratch)))])]
17442 "optimize_insn_for_size_p ()
17443 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17444 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17445 (clobber (mem:BLK (scratch)))])
17446 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17447
17448 ;; Convert esp additions to pop.
17449 (define_peephole2
17450 [(match_scratch:W 1 "r")
17451 (parallel [(set (reg:P SP_REG)
17452 (plus:P (reg:P SP_REG)
17453 (match_operand:P 0 "const_int_operand")))
17454 (clobber (reg:CC FLAGS_REG))])]
17455 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17456 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17457
17458 ;; Two pops case is tricky, since pop causes dependency
17459 ;; on destination register. We use two registers if available.
17460 (define_peephole2
17461 [(match_scratch:W 1 "r")
17462 (match_scratch:W 2 "r")
17463 (parallel [(set (reg:P SP_REG)
17464 (plus:P (reg:P SP_REG)
17465 (match_operand:P 0 "const_int_operand")))
17466 (clobber (reg:CC FLAGS_REG))])]
17467 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17468 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17469 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17470
17471 (define_peephole2
17472 [(match_scratch:W 1 "r")
17473 (parallel [(set (reg:P SP_REG)
17474 (plus:P (reg:P SP_REG)
17475 (match_operand:P 0 "const_int_operand")))
17476 (clobber (reg:CC FLAGS_REG))])]
17477 "optimize_insn_for_size_p ()
17478 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17479 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17480 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17481 \f
17482 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17483 ;; required and register dies. Similarly for 128 to -128.
17484 (define_peephole2
17485 [(set (match_operand 0 "flags_reg_operand")
17486 (match_operator 1 "compare_operator"
17487 [(match_operand 2 "register_operand")
17488 (match_operand 3 "const_int_operand")]))]
17489 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17490 && incdec_operand (operands[3], GET_MODE (operands[3])))
17491 || (!TARGET_FUSE_CMP_AND_BRANCH
17492 && INTVAL (operands[3]) == 128))
17493 && ix86_match_ccmode (insn, CCGCmode)
17494 && peep2_reg_dead_p (1, operands[2])"
17495 [(parallel [(set (match_dup 0)
17496 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17497 (clobber (match_dup 2))])])
17498 \f
17499 ;; Convert imul by three, five and nine into lea
17500 (define_peephole2
17501 [(parallel
17502 [(set (match_operand:SWI48 0 "register_operand")
17503 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17504 (match_operand:SWI48 2 "const359_operand")))
17505 (clobber (reg:CC FLAGS_REG))])]
17506 "!TARGET_PARTIAL_REG_STALL
17507 || <MODE>mode == SImode
17508 || optimize_function_for_size_p (cfun)"
17509 [(set (match_dup 0)
17510 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17511 (match_dup 1)))]
17512 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17513
17514 (define_peephole2
17515 [(parallel
17516 [(set (match_operand:SWI48 0 "register_operand")
17517 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17518 (match_operand:SWI48 2 "const359_operand")))
17519 (clobber (reg:CC FLAGS_REG))])]
17520 "optimize_insn_for_speed_p ()
17521 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17522 [(set (match_dup 0) (match_dup 1))
17523 (set (match_dup 0)
17524 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17525 (match_dup 0)))]
17526 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17527
17528 ;; imul $32bit_imm, mem, reg is vector decoded, while
17529 ;; imul $32bit_imm, reg, reg is direct decoded.
17530 (define_peephole2
17531 [(match_scratch:SWI48 3 "r")
17532 (parallel [(set (match_operand:SWI48 0 "register_operand")
17533 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17534 (match_operand:SWI48 2 "immediate_operand")))
17535 (clobber (reg:CC FLAGS_REG))])]
17536 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17537 && !satisfies_constraint_K (operands[2])"
17538 [(set (match_dup 3) (match_dup 1))
17539 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17540 (clobber (reg:CC FLAGS_REG))])])
17541
17542 (define_peephole2
17543 [(match_scratch:SI 3 "r")
17544 (parallel [(set (match_operand:DI 0 "register_operand")
17545 (zero_extend:DI
17546 (mult:SI (match_operand:SI 1 "memory_operand")
17547 (match_operand:SI 2 "immediate_operand"))))
17548 (clobber (reg:CC FLAGS_REG))])]
17549 "TARGET_64BIT
17550 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17551 && !satisfies_constraint_K (operands[2])"
17552 [(set (match_dup 3) (match_dup 1))
17553 (parallel [(set (match_dup 0)
17554 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17555 (clobber (reg:CC FLAGS_REG))])])
17556
17557 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17558 ;; Convert it into imul reg, reg
17559 ;; It would be better to force assembler to encode instruction using long
17560 ;; immediate, but there is apparently no way to do so.
17561 (define_peephole2
17562 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17563 (mult:SWI248
17564 (match_operand:SWI248 1 "nonimmediate_operand")
17565 (match_operand:SWI248 2 "const_int_operand")))
17566 (clobber (reg:CC FLAGS_REG))])
17567 (match_scratch:SWI248 3 "r")]
17568 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17569 && satisfies_constraint_K (operands[2])"
17570 [(set (match_dup 3) (match_dup 2))
17571 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17572 (clobber (reg:CC FLAGS_REG))])]
17573 {
17574 if (!rtx_equal_p (operands[0], operands[1]))
17575 emit_move_insn (operands[0], operands[1]);
17576 })
17577
17578 ;; After splitting up read-modify operations, array accesses with memory
17579 ;; operands might end up in form:
17580 ;; sall $2, %eax
17581 ;; movl 4(%esp), %edx
17582 ;; addl %edx, %eax
17583 ;; instead of pre-splitting:
17584 ;; sall $2, %eax
17585 ;; addl 4(%esp), %eax
17586 ;; Turn it into:
17587 ;; movl 4(%esp), %edx
17588 ;; leal (%edx,%eax,4), %eax
17589
17590 (define_peephole2
17591 [(match_scratch:W 5 "r")
17592 (parallel [(set (match_operand 0 "register_operand")
17593 (ashift (match_operand 1 "register_operand")
17594 (match_operand 2 "const_int_operand")))
17595 (clobber (reg:CC FLAGS_REG))])
17596 (parallel [(set (match_operand 3 "register_operand")
17597 (plus (match_dup 0)
17598 (match_operand 4 "x86_64_general_operand")))
17599 (clobber (reg:CC FLAGS_REG))])]
17600 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17601 /* Validate MODE for lea. */
17602 && ((!TARGET_PARTIAL_REG_STALL
17603 && (GET_MODE (operands[0]) == QImode
17604 || GET_MODE (operands[0]) == HImode))
17605 || GET_MODE (operands[0]) == SImode
17606 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17607 && (rtx_equal_p (operands[0], operands[3])
17608 || peep2_reg_dead_p (2, operands[0]))
17609 /* We reorder load and the shift. */
17610 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17611 [(set (match_dup 5) (match_dup 4))
17612 (set (match_dup 0) (match_dup 1))]
17613 {
17614 enum machine_mode op1mode = GET_MODE (operands[1]);
17615 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17616 int scale = 1 << INTVAL (operands[2]);
17617 rtx index = gen_lowpart (word_mode, operands[1]);
17618 rtx base = gen_lowpart (word_mode, operands[5]);
17619 rtx dest = gen_lowpart (mode, operands[3]);
17620
17621 operands[1] = gen_rtx_PLUS (word_mode, base,
17622 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17623 operands[5] = base;
17624 if (mode != word_mode)
17625 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17626 if (op1mode != word_mode)
17627 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17628 operands[0] = dest;
17629 })
17630 \f
17631 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17632 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17633 ;; caught for use by garbage collectors and the like. Using an insn that
17634 ;; maps to SIGILL makes it more likely the program will rightfully die.
17635 ;; Keeping with tradition, "6" is in honor of #UD.
17636 (define_insn "trap"
17637 [(trap_if (const_int 1) (const_int 6))]
17638 ""
17639 { return ASM_SHORT "0x0b0f"; }
17640 [(set_attr "length" "2")])
17641
17642 (define_expand "prefetch"
17643 [(prefetch (match_operand 0 "address_operand")
17644 (match_operand:SI 1 "const_int_operand")
17645 (match_operand:SI 2 "const_int_operand"))]
17646 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17647 {
17648 int rw = INTVAL (operands[1]);
17649 int locality = INTVAL (operands[2]);
17650
17651 gcc_assert (rw == 0 || rw == 1);
17652 gcc_assert (locality >= 0 && locality <= 3);
17653 gcc_assert (GET_MODE (operands[0]) == Pmode
17654 || GET_MODE (operands[0]) == VOIDmode);
17655
17656 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17657 supported by SSE counterpart or the SSE prefetch is not available
17658 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17659 of locality. */
17660 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17661 operands[2] = GEN_INT (3);
17662 else
17663 operands[1] = const0_rtx;
17664 })
17665
17666 (define_insn "*prefetch_sse_<mode>"
17667 [(prefetch (match_operand:P 0 "address_operand" "p")
17668 (const_int 0)
17669 (match_operand:SI 1 "const_int_operand"))]
17670 "TARGET_PREFETCH_SSE"
17671 {
17672 static const char * const patterns[4] = {
17673 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17674 };
17675
17676 int locality = INTVAL (operands[1]);
17677 gcc_assert (locality >= 0 && locality <= 3);
17678
17679 return patterns[locality];
17680 }
17681 [(set_attr "type" "sse")
17682 (set_attr "atom_sse_attr" "prefetch")
17683 (set (attr "length_address")
17684 (symbol_ref "memory_address_length (operands[0])"))
17685 (set_attr "memory" "none")])
17686
17687 (define_insn "*prefetch_3dnow_<mode>"
17688 [(prefetch (match_operand:P 0 "address_operand" "p")
17689 (match_operand:SI 1 "const_int_operand" "n")
17690 (const_int 3))]
17691 "TARGET_3DNOW"
17692 {
17693 if (INTVAL (operands[1]) == 0)
17694 return "prefetch\t%a0";
17695 else
17696 return "prefetchw\t%a0";
17697 }
17698 [(set_attr "type" "mmx")
17699 (set (attr "length_address")
17700 (symbol_ref "memory_address_length (operands[0])"))
17701 (set_attr "memory" "none")])
17702
17703 (define_expand "stack_protect_set"
17704 [(match_operand 0 "memory_operand")
17705 (match_operand 1 "memory_operand")]
17706 ""
17707 {
17708 rtx (*insn)(rtx, rtx);
17709
17710 #ifdef TARGET_THREAD_SSP_OFFSET
17711 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17712 insn = (TARGET_LP64
17713 ? gen_stack_tls_protect_set_di
17714 : gen_stack_tls_protect_set_si);
17715 #else
17716 insn = (TARGET_LP64
17717 ? gen_stack_protect_set_di
17718 : gen_stack_protect_set_si);
17719 #endif
17720
17721 emit_insn (insn (operands[0], operands[1]));
17722 DONE;
17723 })
17724
17725 (define_insn "stack_protect_set_<mode>"
17726 [(set (match_operand:PTR 0 "memory_operand" "=m")
17727 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17728 UNSPEC_SP_SET))
17729 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17730 (clobber (reg:CC FLAGS_REG))]
17731 ""
17732 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17733 [(set_attr "type" "multi")])
17734
17735 (define_insn "stack_tls_protect_set_<mode>"
17736 [(set (match_operand:PTR 0 "memory_operand" "=m")
17737 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17738 UNSPEC_SP_TLS_SET))
17739 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17740 (clobber (reg:CC FLAGS_REG))]
17741 ""
17742 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17743 [(set_attr "type" "multi")])
17744
17745 (define_expand "stack_protect_test"
17746 [(match_operand 0 "memory_operand")
17747 (match_operand 1 "memory_operand")
17748 (match_operand 2)]
17749 ""
17750 {
17751 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17752
17753 rtx (*insn)(rtx, rtx, rtx);
17754
17755 #ifdef TARGET_THREAD_SSP_OFFSET
17756 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17757 insn = (TARGET_LP64
17758 ? gen_stack_tls_protect_test_di
17759 : gen_stack_tls_protect_test_si);
17760 #else
17761 insn = (TARGET_LP64
17762 ? gen_stack_protect_test_di
17763 : gen_stack_protect_test_si);
17764 #endif
17765
17766 emit_insn (insn (flags, operands[0], operands[1]));
17767
17768 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17769 flags, const0_rtx, operands[2]));
17770 DONE;
17771 })
17772
17773 (define_insn "stack_protect_test_<mode>"
17774 [(set (match_operand:CCZ 0 "flags_reg_operand")
17775 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17776 (match_operand:PTR 2 "memory_operand" "m")]
17777 UNSPEC_SP_TEST))
17778 (clobber (match_scratch:PTR 3 "=&r"))]
17779 ""
17780 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17781 [(set_attr "type" "multi")])
17782
17783 (define_insn "stack_tls_protect_test_<mode>"
17784 [(set (match_operand:CCZ 0 "flags_reg_operand")
17785 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17786 (match_operand:PTR 2 "const_int_operand" "i")]
17787 UNSPEC_SP_TLS_TEST))
17788 (clobber (match_scratch:PTR 3 "=r"))]
17789 ""
17790 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17791 [(set_attr "type" "multi")])
17792
17793 (define_insn "sse4_2_crc32<mode>"
17794 [(set (match_operand:SI 0 "register_operand" "=r")
17795 (unspec:SI
17796 [(match_operand:SI 1 "register_operand" "0")
17797 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17798 UNSPEC_CRC32))]
17799 "TARGET_SSE4_2 || TARGET_CRC32"
17800 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17801 [(set_attr "type" "sselog1")
17802 (set_attr "prefix_rep" "1")
17803 (set_attr "prefix_extra" "1")
17804 (set (attr "prefix_data16")
17805 (if_then_else (match_operand:HI 2)
17806 (const_string "1")
17807 (const_string "*")))
17808 (set (attr "prefix_rex")
17809 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17810 (const_string "1")
17811 (const_string "*")))
17812 (set_attr "mode" "SI")])
17813
17814 (define_insn "sse4_2_crc32di"
17815 [(set (match_operand:DI 0 "register_operand" "=r")
17816 (unspec:DI
17817 [(match_operand:DI 1 "register_operand" "0")
17818 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17819 UNSPEC_CRC32))]
17820 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17821 "crc32{q}\t{%2, %0|%0, %2}"
17822 [(set_attr "type" "sselog1")
17823 (set_attr "prefix_rep" "1")
17824 (set_attr "prefix_extra" "1")
17825 (set_attr "mode" "DI")])
17826
17827 (define_expand "rdpmc"
17828 [(match_operand:DI 0 "register_operand")
17829 (match_operand:SI 1 "register_operand")]
17830 ""
17831 {
17832 rtx reg = gen_reg_rtx (DImode);
17833 rtx si;
17834
17835 /* Force operand 1 into ECX. */
17836 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17837 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17838 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17839 UNSPECV_RDPMC);
17840
17841 if (TARGET_64BIT)
17842 {
17843 rtvec vec = rtvec_alloc (2);
17844 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17845 rtx upper = gen_reg_rtx (DImode);
17846 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17847 gen_rtvec (1, const0_rtx),
17848 UNSPECV_RDPMC);
17849 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17850 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17851 emit_insn (load);
17852 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17853 NULL, 1, OPTAB_DIRECT);
17854 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17855 OPTAB_DIRECT);
17856 }
17857 else
17858 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17859 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17860 DONE;
17861 })
17862
17863 (define_insn "*rdpmc"
17864 [(set (match_operand:DI 0 "register_operand" "=A")
17865 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17866 UNSPECV_RDPMC))]
17867 "!TARGET_64BIT"
17868 "rdpmc"
17869 [(set_attr "type" "other")
17870 (set_attr "length" "2")])
17871
17872 (define_insn "*rdpmc_rex64"
17873 [(set (match_operand:DI 0 "register_operand" "=a")
17874 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17875 UNSPECV_RDPMC))
17876 (set (match_operand:DI 1 "register_operand" "=d")
17877 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17878 "TARGET_64BIT"
17879 "rdpmc"
17880 [(set_attr "type" "other")
17881 (set_attr "length" "2")])
17882
17883 (define_expand "rdtsc"
17884 [(set (match_operand:DI 0 "register_operand")
17885 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17886 ""
17887 {
17888 if (TARGET_64BIT)
17889 {
17890 rtvec vec = rtvec_alloc (2);
17891 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17892 rtx upper = gen_reg_rtx (DImode);
17893 rtx lower = gen_reg_rtx (DImode);
17894 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17895 gen_rtvec (1, const0_rtx),
17896 UNSPECV_RDTSC);
17897 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17898 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17899 emit_insn (load);
17900 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17901 NULL, 1, OPTAB_DIRECT);
17902 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17903 OPTAB_DIRECT);
17904 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17905 DONE;
17906 }
17907 })
17908
17909 (define_insn "*rdtsc"
17910 [(set (match_operand:DI 0 "register_operand" "=A")
17911 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17912 "!TARGET_64BIT"
17913 "rdtsc"
17914 [(set_attr "type" "other")
17915 (set_attr "length" "2")])
17916
17917 (define_insn "*rdtsc_rex64"
17918 [(set (match_operand:DI 0 "register_operand" "=a")
17919 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17920 (set (match_operand:DI 1 "register_operand" "=d")
17921 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17922 "TARGET_64BIT"
17923 "rdtsc"
17924 [(set_attr "type" "other")
17925 (set_attr "length" "2")])
17926
17927 (define_expand "rdtscp"
17928 [(match_operand:DI 0 "register_operand")
17929 (match_operand:SI 1 "memory_operand")]
17930 ""
17931 {
17932 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17933 gen_rtvec (1, const0_rtx),
17934 UNSPECV_RDTSCP);
17935 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17936 gen_rtvec (1, const0_rtx),
17937 UNSPECV_RDTSCP);
17938 rtx reg = gen_reg_rtx (DImode);
17939 rtx tmp = gen_reg_rtx (SImode);
17940
17941 if (TARGET_64BIT)
17942 {
17943 rtvec vec = rtvec_alloc (3);
17944 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17945 rtx upper = gen_reg_rtx (DImode);
17946 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17947 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17948 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17949 emit_insn (load);
17950 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17951 NULL, 1, OPTAB_DIRECT);
17952 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17953 OPTAB_DIRECT);
17954 }
17955 else
17956 {
17957 rtvec vec = rtvec_alloc (2);
17958 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17959 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17960 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17961 emit_insn (load);
17962 }
17963 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17964 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17965 DONE;
17966 })
17967
17968 (define_insn "*rdtscp"
17969 [(set (match_operand:DI 0 "register_operand" "=A")
17970 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17971 (set (match_operand:SI 1 "register_operand" "=c")
17972 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17973 "!TARGET_64BIT"
17974 "rdtscp"
17975 [(set_attr "type" "other")
17976 (set_attr "length" "3")])
17977
17978 (define_insn "*rdtscp_rex64"
17979 [(set (match_operand:DI 0 "register_operand" "=a")
17980 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17981 (set (match_operand:DI 1 "register_operand" "=d")
17982 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17983 (set (match_operand:SI 2 "register_operand" "=c")
17984 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17985 "TARGET_64BIT"
17986 "rdtscp"
17987 [(set_attr "type" "other")
17988 (set_attr "length" "3")])
17989
17990 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17991 ;;
17992 ;; LWP instructions
17993 ;;
17994 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17995
17996 (define_expand "lwp_llwpcb"
17997 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17998 UNSPECV_LLWP_INTRINSIC)]
17999 "TARGET_LWP")
18000
18001 (define_insn "*lwp_llwpcb<mode>1"
18002 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18003 UNSPECV_LLWP_INTRINSIC)]
18004 "TARGET_LWP"
18005 "llwpcb\t%0"
18006 [(set_attr "type" "lwp")
18007 (set_attr "mode" "<MODE>")
18008 (set_attr "length" "5")])
18009
18010 (define_expand "lwp_slwpcb"
18011 [(set (match_operand 0 "register_operand" "=r")
18012 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18013 "TARGET_LWP"
18014 {
18015 rtx (*insn)(rtx);
18016
18017 insn = (Pmode == DImode
18018 ? gen_lwp_slwpcbdi
18019 : gen_lwp_slwpcbsi);
18020
18021 emit_insn (insn (operands[0]));
18022 DONE;
18023 })
18024
18025 (define_insn "lwp_slwpcb<mode>"
18026 [(set (match_operand:P 0 "register_operand" "=r")
18027 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18028 "TARGET_LWP"
18029 "slwpcb\t%0"
18030 [(set_attr "type" "lwp")
18031 (set_attr "mode" "<MODE>")
18032 (set_attr "length" "5")])
18033
18034 (define_expand "lwp_lwpval<mode>3"
18035 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18036 (match_operand:SI 2 "nonimmediate_operand" "rm")
18037 (match_operand:SI 3 "const_int_operand" "i")]
18038 UNSPECV_LWPVAL_INTRINSIC)]
18039 "TARGET_LWP"
18040 ;; Avoid unused variable warning.
18041 "(void) operands[0];")
18042
18043 (define_insn "*lwp_lwpval<mode>3_1"
18044 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18045 (match_operand:SI 1 "nonimmediate_operand" "rm")
18046 (match_operand:SI 2 "const_int_operand" "i")]
18047 UNSPECV_LWPVAL_INTRINSIC)]
18048 "TARGET_LWP"
18049 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18050 [(set_attr "type" "lwp")
18051 (set_attr "mode" "<MODE>")
18052 (set (attr "length")
18053 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18054
18055 (define_expand "lwp_lwpins<mode>3"
18056 [(set (reg:CCC FLAGS_REG)
18057 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18058 (match_operand:SI 2 "nonimmediate_operand" "rm")
18059 (match_operand:SI 3 "const_int_operand" "i")]
18060 UNSPECV_LWPINS_INTRINSIC))
18061 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18062 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18063 "TARGET_LWP")
18064
18065 (define_insn "*lwp_lwpins<mode>3_1"
18066 [(set (reg:CCC FLAGS_REG)
18067 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18068 (match_operand:SI 1 "nonimmediate_operand" "rm")
18069 (match_operand:SI 2 "const_int_operand" "i")]
18070 UNSPECV_LWPINS_INTRINSIC))]
18071 "TARGET_LWP"
18072 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18073 [(set_attr "type" "lwp")
18074 (set_attr "mode" "<MODE>")
18075 (set (attr "length")
18076 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18077
18078 (define_int_iterator RDFSGSBASE
18079 [UNSPECV_RDFSBASE
18080 UNSPECV_RDGSBASE])
18081
18082 (define_int_iterator WRFSGSBASE
18083 [UNSPECV_WRFSBASE
18084 UNSPECV_WRGSBASE])
18085
18086 (define_int_attr fsgs
18087 [(UNSPECV_RDFSBASE "fs")
18088 (UNSPECV_RDGSBASE "gs")
18089 (UNSPECV_WRFSBASE "fs")
18090 (UNSPECV_WRGSBASE "gs")])
18091
18092 (define_insn "rd<fsgs>base<mode>"
18093 [(set (match_operand:SWI48 0 "register_operand" "=r")
18094 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18095 "TARGET_64BIT && TARGET_FSGSBASE"
18096 "rd<fsgs>base\t%0"
18097 [(set_attr "type" "other")
18098 (set_attr "prefix_extra" "2")])
18099
18100 (define_insn "wr<fsgs>base<mode>"
18101 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18102 WRFSGSBASE)]
18103 "TARGET_64BIT && TARGET_FSGSBASE"
18104 "wr<fsgs>base\t%0"
18105 [(set_attr "type" "other")
18106 (set_attr "prefix_extra" "2")])
18107
18108 (define_insn "rdrand<mode>_1"
18109 [(set (match_operand:SWI248 0 "register_operand" "=r")
18110 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18111 (set (reg:CCC FLAGS_REG)
18112 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18113 "TARGET_RDRND"
18114 "rdrand\t%0"
18115 [(set_attr "type" "other")
18116 (set_attr "prefix_extra" "1")])
18117
18118 (define_expand "pause"
18119 [(set (match_dup 0)
18120 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18121 ""
18122 {
18123 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18124 MEM_VOLATILE_P (operands[0]) = 1;
18125 })
18126
18127 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18128 ;; They have the same encoding.
18129 (define_insn "*pause"
18130 [(set (match_operand:BLK 0)
18131 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18132 ""
18133 "rep; nop"
18134 [(set_attr "length" "2")
18135 (set_attr "memory" "unknown")])
18136
18137 (define_expand "xbegin"
18138 [(set (match_operand:SI 0 "register_operand")
18139 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18140 "TARGET_RTM"
18141 {
18142 rtx label = gen_label_rtx ();
18143
18144 operands[1] = force_reg (SImode, constm1_rtx);
18145
18146 emit_jump_insn (gen_xbegin_1 (operands[1], label));
18147
18148 emit_label (label);
18149 LABEL_NUSES (label) = 1;
18150
18151 emit_move_insn (operands[0], operands[1]);
18152
18153 DONE;
18154 })
18155
18156 (define_insn "xbegin_1"
18157 [(set (pc)
18158 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18159 (const_int 0))
18160 (label_ref (match_operand 1))
18161 (pc)))
18162 (set (match_operand:SI 0 "register_operand" "+a")
18163 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18164 "TARGET_RTM"
18165 "xbegin\t%l1"
18166 [(set_attr "type" "other")
18167 (set_attr "length" "6")])
18168
18169 (define_insn "xend"
18170 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18171 "TARGET_RTM"
18172 "xend"
18173 [(set_attr "type" "other")
18174 (set_attr "length" "3")])
18175
18176 (define_insn "xabort"
18177 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18178 UNSPECV_XABORT)]
18179 "TARGET_RTM"
18180 "xabort\t%0"
18181 [(set_attr "type" "other")
18182 (set_attr "length" "3")])
18183
18184 (define_expand "xtest"
18185 [(set (match_operand:QI 0 "register_operand")
18186 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18187 "TARGET_RTM"
18188 {
18189 emit_insn (gen_xtest_1 ());
18190
18191 ix86_expand_setcc (operands[0], NE,
18192 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18193 DONE;
18194 })
18195
18196 (define_insn "xtest_1"
18197 [(set (reg:CCZ FLAGS_REG)
18198 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18199 "TARGET_RTM"
18200 "xtest"
18201 [(set_attr "type" "other")
18202 (set_attr "length" "3")])
18203
18204 (include "mmx.md")
18205 (include "sse.md")
18206 (include "sync.md")