da2f4b273483540c93b60d2beb1156cf5a732518
[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_REG_SAVE
88 UNSPEC_DEF_CFA
89 UNSPEC_SET_RIP
90 UNSPEC_SET_GOT_OFFSET
91 UNSPEC_MEMORY_BLOCKAGE
92 UNSPEC_STACK_CHECK
93
94 ;; TLS support
95 UNSPEC_TP
96 UNSPEC_TLS_GD
97 UNSPEC_TLS_LD_BASE
98 UNSPEC_TLSDESC
99 UNSPEC_TLS_IE_SUN
100
101 ;; Other random patterns
102 UNSPEC_SCAS
103 UNSPEC_FNSTSW
104 UNSPEC_SAHF
105 UNSPEC_PARITY
106 UNSPEC_FSTCW
107 UNSPEC_ADD_CARRY
108 UNSPEC_FLDCW
109 UNSPEC_REP
110 UNSPEC_LD_MPIC ; load_macho_picbase
111 UNSPEC_TRUNC_NOOP
112 UNSPEC_DIV_ALREADY_SPLIT
113 UNSPEC_MS_TO_SYSV_CALL
114 UNSPEC_CALL_NEEDS_VZEROUPPER
115 UNSPEC_PAUSE
116 UNSPEC_LEA_ADDR
117 UNSPEC_XBEGIN_ABORT
118
119 ;; For SSE/MMX support:
120 UNSPEC_FIX_NOTRUNC
121 UNSPEC_MASKMOV
122 UNSPEC_MOVMSK
123 UNSPEC_RCP
124 UNSPEC_RSQRT
125 UNSPEC_PSADBW
126
127 ;; Generic math support
128 UNSPEC_COPYSIGN
129 UNSPEC_IEEE_MIN ; not commutative
130 UNSPEC_IEEE_MAX ; not commutative
131
132 ;; x87 Floating point
133 UNSPEC_SIN
134 UNSPEC_COS
135 UNSPEC_FPATAN
136 UNSPEC_FYL2X
137 UNSPEC_FYL2XP1
138 UNSPEC_FRNDINT
139 UNSPEC_FIST
140 UNSPEC_F2XM1
141 UNSPEC_TAN
142 UNSPEC_FXAM
143
144 ;; x87 Rounding
145 UNSPEC_FRNDINT_FLOOR
146 UNSPEC_FRNDINT_CEIL
147 UNSPEC_FRNDINT_TRUNC
148 UNSPEC_FRNDINT_MASK_PM
149 UNSPEC_FIST_FLOOR
150 UNSPEC_FIST_CEIL
151
152 ;; x87 Double output FP
153 UNSPEC_SINCOS_COS
154 UNSPEC_SINCOS_SIN
155 UNSPEC_XTRACT_FRACT
156 UNSPEC_XTRACT_EXP
157 UNSPEC_FSCALE_FRACT
158 UNSPEC_FSCALE_EXP
159 UNSPEC_FPREM_F
160 UNSPEC_FPREM_U
161 UNSPEC_FPREM1_F
162 UNSPEC_FPREM1_U
163
164 UNSPEC_C2_FLAG
165 UNSPEC_FXAM_MEM
166
167 ;; SSP patterns
168 UNSPEC_SP_SET
169 UNSPEC_SP_TEST
170 UNSPEC_SP_TLS_SET
171 UNSPEC_SP_TLS_TEST
172
173 ;; For ROUND support
174 UNSPEC_ROUND
175
176 ;; For CRC32 support
177 UNSPEC_CRC32
178
179 ;; For BMI support
180 UNSPEC_BEXTR
181
182 ;; For BMI2 support
183 UNSPEC_PDEP
184 UNSPEC_PEXT
185 ])
186
187 (define_c_enum "unspecv" [
188 UNSPECV_BLOCKAGE
189 UNSPECV_STACK_PROBE
190 UNSPECV_PROBE_STACK_RANGE
191 UNSPECV_ALIGN
192 UNSPECV_PROLOGUE_USE
193 UNSPECV_SPLIT_STACK_RETURN
194 UNSPECV_CLD
195 UNSPECV_NOPS
196 UNSPECV_RDTSC
197 UNSPECV_RDTSCP
198 UNSPECV_RDPMC
199 UNSPECV_LLWP_INTRINSIC
200 UNSPECV_SLWP_INTRINSIC
201 UNSPECV_LWPVAL_INTRINSIC
202 UNSPECV_LWPINS_INTRINSIC
203 UNSPECV_RDFSBASE
204 UNSPECV_RDGSBASE
205 UNSPECV_WRFSBASE
206 UNSPECV_WRGSBASE
207
208 ;; For RDRAND support
209 UNSPECV_RDRAND
210
211 ;; For RTM support
212 UNSPECV_XBEGIN
213 UNSPECV_XEND
214 UNSPECV_XABORT
215 UNSPECV_XTEST
216 ])
217
218 ;; Constants to represent rounding modes in the ROUND instruction
219 (define_constants
220 [(ROUND_FLOOR 0x1)
221 (ROUND_CEIL 0x2)
222 (ROUND_TRUNC 0x3)
223 (ROUND_MXCSR 0x4)
224 (ROUND_NO_EXC 0x8)
225 ])
226
227 ;; Constants to represent pcomtrue/pcomfalse variants
228 (define_constants
229 [(PCOM_FALSE 0)
230 (PCOM_TRUE 1)
231 (COM_FALSE_S 2)
232 (COM_FALSE_P 3)
233 (COM_TRUE_S 4)
234 (COM_TRUE_P 5)
235 ])
236
237 ;; Constants used in the XOP pperm instruction
238 (define_constants
239 [(PPERM_SRC 0x00) /* copy source */
240 (PPERM_INVERT 0x20) /* invert source */
241 (PPERM_REVERSE 0x40) /* bit reverse source */
242 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
243 (PPERM_ZERO 0x80) /* all 0's */
244 (PPERM_ONES 0xa0) /* all 1's */
245 (PPERM_SIGN 0xc0) /* propagate sign bit */
246 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
247 (PPERM_SRC1 0x00) /* use first source byte */
248 (PPERM_SRC2 0x10) /* use second source byte */
249 ])
250
251 ;; Registers by name.
252 (define_constants
253 [(AX_REG 0)
254 (DX_REG 1)
255 (CX_REG 2)
256 (BX_REG 3)
257 (SI_REG 4)
258 (DI_REG 5)
259 (BP_REG 6)
260 (SP_REG 7)
261 (ST0_REG 8)
262 (ST1_REG 9)
263 (ST2_REG 10)
264 (ST3_REG 11)
265 (ST4_REG 12)
266 (ST5_REG 13)
267 (ST6_REG 14)
268 (ST7_REG 15)
269 (FLAGS_REG 17)
270 (FPSR_REG 18)
271 (FPCR_REG 19)
272 (XMM0_REG 21)
273 (XMM1_REG 22)
274 (XMM2_REG 23)
275 (XMM3_REG 24)
276 (XMM4_REG 25)
277 (XMM5_REG 26)
278 (XMM6_REG 27)
279 (XMM7_REG 28)
280 (MM0_REG 29)
281 (MM1_REG 30)
282 (MM2_REG 31)
283 (MM3_REG 32)
284 (MM4_REG 33)
285 (MM5_REG 34)
286 (MM6_REG 35)
287 (MM7_REG 36)
288 (R8_REG 37)
289 (R9_REG 38)
290 (R10_REG 39)
291 (R11_REG 40)
292 (R12_REG 41)
293 (R13_REG 42)
294 (XMM8_REG 45)
295 (XMM9_REG 46)
296 (XMM10_REG 47)
297 (XMM11_REG 48)
298 (XMM12_REG 49)
299 (XMM13_REG 50)
300 (XMM14_REG 51)
301 (XMM15_REG 52)
302 ])
303
304 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
305 ;; from i386.c.
306
307 ;; In C guard expressions, put expressions which may be compile-time
308 ;; constants first. This allows for better optimization. For
309 ;; example, write "TARGET_64BIT && reload_completed", not
310 ;; "reload_completed && TARGET_64BIT".
311
312 \f
313 ;; Processor type.
314 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
315 atom,generic64,amdfam10,bdver1,bdver2,btver1"
316 (const (symbol_ref "ix86_schedule")))
317
318 ;; A basic instruction type. Refinements due to arguments to be
319 ;; provided in other attributes.
320 (define_attr "type"
321 "other,multi,
322 alu,alu1,negnot,imov,imovx,lea,
323 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
324 icmp,test,ibr,setcc,icmov,
325 push,pop,call,callv,leave,
326 str,bitmanip,
327 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
328 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
329 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
330 ssemuladd,sse4arg,lwp,
331 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
332 (const_string "other"))
333
334 ;; Main data type used by the insn
335 (define_attr "mode"
336 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
337 (const_string "unknown"))
338
339 ;; The CPU unit operations uses.
340 (define_attr "unit" "integer,i387,sse,mmx,unknown"
341 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
342 (const_string "i387")
343 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
344 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
345 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
346 (const_string "sse")
347 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
348 (const_string "mmx")
349 (eq_attr "type" "other")
350 (const_string "unknown")]
351 (const_string "integer")))
352
353 ;; The (bounding maximum) length of an instruction immediate.
354 (define_attr "length_immediate" ""
355 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
356 bitmanip,imulx")
357 (const_int 0)
358 (eq_attr "unit" "i387,sse,mmx")
359 (const_int 0)
360 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
361 rotate,rotatex,rotate1,imul,icmp,push,pop")
362 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
363 (eq_attr "type" "imov,test")
364 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
365 (eq_attr "type" "call")
366 (if_then_else (match_operand 0 "constant_call_address_operand")
367 (const_int 4)
368 (const_int 0))
369 (eq_attr "type" "callv")
370 (if_then_else (match_operand 1 "constant_call_address_operand")
371 (const_int 4)
372 (const_int 0))
373 ;; We don't know the size before shorten_branches. Expect
374 ;; the instruction to fit for better scheduling.
375 (eq_attr "type" "ibr")
376 (const_int 1)
377 ]
378 (symbol_ref "/* Update immediate_length and other attributes! */
379 gcc_unreachable (),1")))
380
381 ;; The (bounding maximum) length of an instruction address.
382 (define_attr "length_address" ""
383 (cond [(eq_attr "type" "str,other,multi,fxch")
384 (const_int 0)
385 (and (eq_attr "type" "call")
386 (match_operand 0 "constant_call_address_operand"))
387 (const_int 0)
388 (and (eq_attr "type" "callv")
389 (match_operand 1 "constant_call_address_operand"))
390 (const_int 0)
391 ]
392 (symbol_ref "ix86_attr_length_address_default (insn)")))
393
394 ;; Set when length prefix is used.
395 (define_attr "prefix_data16" ""
396 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
397 (const_int 0)
398 (eq_attr "mode" "HI")
399 (const_int 1)
400 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
401 (const_int 1)
402 ]
403 (const_int 0)))
404
405 ;; Set when string REP prefix is used.
406 (define_attr "prefix_rep" ""
407 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
408 (const_int 0)
409 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
410 (const_int 1)
411 ]
412 (const_int 0)))
413
414 ;; Set when 0f opcode prefix is used.
415 (define_attr "prefix_0f" ""
416 (if_then_else
417 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
418 (eq_attr "unit" "sse,mmx"))
419 (const_int 1)
420 (const_int 0)))
421
422 ;; Set when REX opcode prefix is used.
423 (define_attr "prefix_rex" ""
424 (cond [(not (match_test "TARGET_64BIT"))
425 (const_int 0)
426 (and (eq_attr "mode" "DI")
427 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
428 (eq_attr "unit" "!mmx")))
429 (const_int 1)
430 (and (eq_attr "mode" "QI")
431 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
432 (const_int 1)
433 (match_test "x86_extended_reg_mentioned_p (insn)")
434 (const_int 1)
435 (and (eq_attr "type" "imovx")
436 (match_operand:QI 1 "ext_QIreg_operand"))
437 (const_int 1)
438 ]
439 (const_int 0)))
440
441 ;; There are also additional prefixes in 3DNOW, SSSE3.
442 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
443 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
444 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
445 (define_attr "prefix_extra" ""
446 (cond [(eq_attr "type" "ssemuladd,sse4arg")
447 (const_int 2)
448 (eq_attr "type" "sseiadd1,ssecvt1")
449 (const_int 1)
450 ]
451 (const_int 0)))
452
453 ;; Prefix used: original, VEX or maybe VEX.
454 (define_attr "prefix" "orig,vex,maybe_vex"
455 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
456 (const_string "vex")
457 (const_string "orig")))
458
459 ;; VEX W bit is used.
460 (define_attr "prefix_vex_w" "" (const_int 0))
461
462 ;; The length of VEX prefix
463 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
464 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
465 ;; still prefix_0f 1, with prefix_extra 1.
466 (define_attr "length_vex" ""
467 (if_then_else (and (eq_attr "prefix_0f" "1")
468 (eq_attr "prefix_extra" "0"))
469 (if_then_else (eq_attr "prefix_vex_w" "1")
470 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
471 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
472 (if_then_else (eq_attr "prefix_vex_w" "1")
473 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
474 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
475
476 ;; Set when modrm byte is used.
477 (define_attr "modrm" ""
478 (cond [(eq_attr "type" "str,leave")
479 (const_int 0)
480 (eq_attr "unit" "i387")
481 (const_int 0)
482 (and (eq_attr "type" "incdec")
483 (and (not (match_test "TARGET_64BIT"))
484 (ior (match_operand:SI 1 "register_operand")
485 (match_operand:HI 1 "register_operand"))))
486 (const_int 0)
487 (and (eq_attr "type" "push")
488 (not (match_operand 1 "memory_operand")))
489 (const_int 0)
490 (and (eq_attr "type" "pop")
491 (not (match_operand 0 "memory_operand")))
492 (const_int 0)
493 (and (eq_attr "type" "imov")
494 (and (not (eq_attr "mode" "DI"))
495 (ior (and (match_operand 0 "register_operand")
496 (match_operand 1 "immediate_operand"))
497 (ior (and (match_operand 0 "ax_reg_operand")
498 (match_operand 1 "memory_displacement_only_operand"))
499 (and (match_operand 0 "memory_displacement_only_operand")
500 (match_operand 1 "ax_reg_operand"))))))
501 (const_int 0)
502 (and (eq_attr "type" "call")
503 (match_operand 0 "constant_call_address_operand"))
504 (const_int 0)
505 (and (eq_attr "type" "callv")
506 (match_operand 1 "constant_call_address_operand"))
507 (const_int 0)
508 (and (eq_attr "type" "alu,alu1,icmp,test")
509 (match_operand 0 "ax_reg_operand"))
510 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
511 ]
512 (const_int 1)))
513
514 ;; The (bounding maximum) length of an instruction in bytes.
515 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
516 ;; Later we may want to split them and compute proper length as for
517 ;; other insns.
518 (define_attr "length" ""
519 (cond [(eq_attr "type" "other,multi,fistp,frndint")
520 (const_int 16)
521 (eq_attr "type" "fcmp")
522 (const_int 4)
523 (eq_attr "unit" "i387")
524 (plus (const_int 2)
525 (plus (attr "prefix_data16")
526 (attr "length_address")))
527 (ior (eq_attr "prefix" "vex")
528 (and (eq_attr "prefix" "maybe_vex")
529 (match_test "TARGET_AVX")))
530 (plus (attr "length_vex")
531 (plus (attr "length_immediate")
532 (plus (attr "modrm")
533 (attr "length_address"))))]
534 (plus (plus (attr "modrm")
535 (plus (attr "prefix_0f")
536 (plus (attr "prefix_rex")
537 (plus (attr "prefix_extra")
538 (const_int 1)))))
539 (plus (attr "prefix_rep")
540 (plus (attr "prefix_data16")
541 (plus (attr "length_immediate")
542 (attr "length_address")))))))
543
544 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
545 ;; `store' if there is a simple memory reference therein, or `unknown'
546 ;; if the instruction is complex.
547
548 (define_attr "memory" "none,load,store,both,unknown"
549 (cond [(eq_attr "type" "other,multi,str,lwp")
550 (const_string "unknown")
551 (eq_attr "type" "lea,fcmov,fpspc")
552 (const_string "none")
553 (eq_attr "type" "fistp,leave")
554 (const_string "both")
555 (eq_attr "type" "frndint")
556 (const_string "load")
557 (eq_attr "type" "push")
558 (if_then_else (match_operand 1 "memory_operand")
559 (const_string "both")
560 (const_string "store"))
561 (eq_attr "type" "pop")
562 (if_then_else (match_operand 0 "memory_operand")
563 (const_string "both")
564 (const_string "load"))
565 (eq_attr "type" "setcc")
566 (if_then_else (match_operand 0 "memory_operand")
567 (const_string "store")
568 (const_string "none"))
569 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
570 (if_then_else (ior (match_operand 0 "memory_operand")
571 (match_operand 1 "memory_operand"))
572 (const_string "load")
573 (const_string "none"))
574 (eq_attr "type" "ibr")
575 (if_then_else (match_operand 0 "memory_operand")
576 (const_string "load")
577 (const_string "none"))
578 (eq_attr "type" "call")
579 (if_then_else (match_operand 0 "constant_call_address_operand")
580 (const_string "none")
581 (const_string "load"))
582 (eq_attr "type" "callv")
583 (if_then_else (match_operand 1 "constant_call_address_operand")
584 (const_string "none")
585 (const_string "load"))
586 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
587 (match_operand 1 "memory_operand"))
588 (const_string "both")
589 (and (match_operand 0 "memory_operand")
590 (match_operand 1 "memory_operand"))
591 (const_string "both")
592 (match_operand 0 "memory_operand")
593 (const_string "store")
594 (match_operand 1 "memory_operand")
595 (const_string "load")
596 (and (eq_attr "type"
597 "!alu1,negnot,ishift1,
598 imov,imovx,icmp,test,bitmanip,
599 fmov,fcmp,fsgn,
600 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
601 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
602 (match_operand 2 "memory_operand"))
603 (const_string "load")
604 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
605 (match_operand 3 "memory_operand"))
606 (const_string "load")
607 ]
608 (const_string "none")))
609
610 ;; Indicates if an instruction has both an immediate and a displacement.
611
612 (define_attr "imm_disp" "false,true,unknown"
613 (cond [(eq_attr "type" "other,multi")
614 (const_string "unknown")
615 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
616 (and (match_operand 0 "memory_displacement_operand")
617 (match_operand 1 "immediate_operand")))
618 (const_string "true")
619 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
620 (and (match_operand 0 "memory_displacement_operand")
621 (match_operand 2 "immediate_operand")))
622 (const_string "true")
623 ]
624 (const_string "false")))
625
626 ;; Indicates if an FP operation has an integer source.
627
628 (define_attr "fp_int_src" "false,true"
629 (const_string "false"))
630
631 ;; Defines rounding mode of an FP operation.
632
633 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
634 (const_string "any"))
635
636 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
637 (define_attr "use_carry" "0,1" (const_string "0"))
638
639 ;; Define attribute to indicate unaligned ssemov insns
640 (define_attr "movu" "0,1" (const_string "0"))
641
642 ;; Used to control the "enabled" attribute on a per-instruction basis.
643 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,avx2,noavx2,bmi2"
644 (const_string "base"))
645
646 (define_attr "enabled" ""
647 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
648 (eq_attr "isa" "sse2_noavx")
649 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
650 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
651 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
652 (eq_attr "isa" "sse4_noavx")
653 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
654 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
655 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
656 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
657 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
658 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
659 ]
660 (const_int 1)))
661
662 ;; Describe a user's asm statement.
663 (define_asm_attributes
664 [(set_attr "length" "128")
665 (set_attr "type" "multi")])
666
667 (define_code_iterator plusminus [plus minus])
668
669 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
670
671 ;; Base name for define_insn
672 (define_code_attr plusminus_insn
673 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
674 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
675
676 ;; Base name for insn mnemonic.
677 (define_code_attr plusminus_mnemonic
678 [(plus "add") (ss_plus "adds") (us_plus "addus")
679 (minus "sub") (ss_minus "subs") (us_minus "subus")])
680 (define_code_attr plusminus_carry_mnemonic
681 [(plus "adc") (minus "sbb")])
682
683 ;; Mark commutative operators as such in constraints.
684 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
685 (minus "") (ss_minus "") (us_minus "")])
686
687 ;; Mapping of max and min
688 (define_code_iterator maxmin [smax smin umax umin])
689
690 ;; Mapping of signed max and min
691 (define_code_iterator smaxmin [smax smin])
692
693 ;; Mapping of unsigned max and min
694 (define_code_iterator umaxmin [umax umin])
695
696 ;; Base name for integer and FP insn mnemonic
697 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
698 (umax "maxu") (umin "minu")])
699 (define_code_attr maxmin_float [(smax "max") (smin "min")])
700
701 ;; Mapping of logic operators
702 (define_code_iterator any_logic [and ior xor])
703 (define_code_iterator any_or [ior xor])
704
705 ;; Base name for insn mnemonic.
706 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
707
708 ;; Mapping of logic-shift operators
709 (define_code_iterator any_lshift [ashift lshiftrt])
710
711 ;; Mapping of shift-right operators
712 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
713
714 ;; Mapping of all shift operators
715 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
716
717 ;; Base name for define_insn
718 (define_code_attr shift_insn
719 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
720
721 ;; Base name for insn mnemonic.
722 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
723 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
724
725 ;; Mapping of rotate operators
726 (define_code_iterator any_rotate [rotate rotatert])
727
728 ;; Base name for define_insn
729 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
730
731 ;; Base name for insn mnemonic.
732 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
733
734 ;; Mapping of abs neg operators
735 (define_code_iterator absneg [abs neg])
736
737 ;; Base name for x87 insn mnemonic.
738 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
739
740 ;; Used in signed and unsigned widening multiplications.
741 (define_code_iterator any_extend [sign_extend zero_extend])
742
743 ;; Prefix for insn menmonic.
744 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
745
746 ;; Prefix for define_insn
747 (define_code_attr u [(sign_extend "") (zero_extend "u")])
748 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
749
750 ;; All integer modes.
751 (define_mode_iterator SWI1248x [QI HI SI DI])
752
753 ;; All integer modes without QImode.
754 (define_mode_iterator SWI248x [HI SI DI])
755
756 ;; All integer modes without QImode and HImode.
757 (define_mode_iterator SWI48x [SI DI])
758
759 ;; All integer modes without SImode and DImode.
760 (define_mode_iterator SWI12 [QI HI])
761
762 ;; All integer modes without DImode.
763 (define_mode_iterator SWI124 [QI HI SI])
764
765 ;; All integer modes without QImode and DImode.
766 (define_mode_iterator SWI24 [HI SI])
767
768 ;; Single word integer modes.
769 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
770
771 ;; Single word integer modes without QImode.
772 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
773
774 ;; Single word integer modes without QImode and HImode.
775 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
776
777 ;; All math-dependant single and double word integer modes.
778 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
779 (HI "TARGET_HIMODE_MATH")
780 SI DI (TI "TARGET_64BIT")])
781
782 ;; Math-dependant single word integer modes.
783 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
784 (HI "TARGET_HIMODE_MATH")
785 SI (DI "TARGET_64BIT")])
786
787 ;; Math-dependant integer modes without DImode.
788 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
789 (HI "TARGET_HIMODE_MATH")
790 SI])
791
792 ;; Math-dependant single word integer modes without QImode.
793 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
794 SI (DI "TARGET_64BIT")])
795
796 ;; Double word integer modes.
797 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
798 (TI "TARGET_64BIT")])
799
800 ;; Double word integer modes as mode attribute.
801 (define_mode_attr DWI [(SI "DI") (DI "TI")])
802 (define_mode_attr dwi [(SI "di") (DI "ti")])
803
804 ;; Half mode for double word integer modes.
805 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
806 (DI "TARGET_64BIT")])
807
808 ;; Instruction suffix for integer modes.
809 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
810
811 ;; Pointer size prefix for integer modes (Intel asm dialect)
812 (define_mode_attr iptrsize [(QI "BYTE")
813 (HI "WORD")
814 (SI "DWORD")
815 (DI "QWORD")])
816
817 ;; Register class for integer modes.
818 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
819
820 ;; Immediate operand constraint for integer modes.
821 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
822
823 ;; General operand constraint for word modes.
824 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
825
826 ;; Immediate operand constraint for double integer modes.
827 (define_mode_attr di [(SI "nF") (DI "e")])
828
829 ;; Immediate operand constraint for shifts.
830 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
831
832 ;; General operand predicate for integer modes.
833 (define_mode_attr general_operand
834 [(QI "general_operand")
835 (HI "general_operand")
836 (SI "x86_64_general_operand")
837 (DI "x86_64_general_operand")
838 (TI "x86_64_general_operand")])
839
840 ;; General sign/zero extend operand predicate for integer modes.
841 (define_mode_attr general_szext_operand
842 [(QI "general_operand")
843 (HI "general_operand")
844 (SI "x86_64_szext_general_operand")
845 (DI "x86_64_szext_general_operand")])
846
847 ;; Immediate operand predicate for integer modes.
848 (define_mode_attr immediate_operand
849 [(QI "immediate_operand")
850 (HI "immediate_operand")
851 (SI "x86_64_immediate_operand")
852 (DI "x86_64_immediate_operand")])
853
854 ;; Nonmemory operand predicate for integer modes.
855 (define_mode_attr nonmemory_operand
856 [(QI "nonmemory_operand")
857 (HI "nonmemory_operand")
858 (SI "x86_64_nonmemory_operand")
859 (DI "x86_64_nonmemory_operand")])
860
861 ;; Operand predicate for shifts.
862 (define_mode_attr shift_operand
863 [(QI "nonimmediate_operand")
864 (HI "nonimmediate_operand")
865 (SI "nonimmediate_operand")
866 (DI "shiftdi_operand")
867 (TI "register_operand")])
868
869 ;; Operand predicate for shift argument.
870 (define_mode_attr shift_immediate_operand
871 [(QI "const_1_to_31_operand")
872 (HI "const_1_to_31_operand")
873 (SI "const_1_to_31_operand")
874 (DI "const_1_to_63_operand")])
875
876 ;; Input operand predicate for arithmetic left shifts.
877 (define_mode_attr ashl_input_operand
878 [(QI "nonimmediate_operand")
879 (HI "nonimmediate_operand")
880 (SI "nonimmediate_operand")
881 (DI "ashldi_input_operand")
882 (TI "reg_or_pm1_operand")])
883
884 ;; SSE and x87 SFmode and DFmode floating point modes
885 (define_mode_iterator MODEF [SF DF])
886
887 ;; All x87 floating point modes
888 (define_mode_iterator X87MODEF [SF DF XF])
889
890 ;; SSE instruction suffix for various modes
891 (define_mode_attr ssemodesuffix
892 [(SF "ss") (DF "sd")
893 (V8SF "ps") (V4DF "pd")
894 (V4SF "ps") (V2DF "pd")
895 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
896 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
897
898 ;; SSE vector suffix for floating point modes
899 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
900
901 ;; SSE vector mode corresponding to a scalar mode
902 (define_mode_attr ssevecmode
903 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
904
905 ;; Instruction suffix for REX 64bit operators.
906 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
907
908 ;; This mode iterator allows :P to be used for patterns that operate on
909 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
910 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
911
912 ;; This mode iterator allows :W to be used for patterns that operate on
913 ;; word_mode sized quantities.
914 (define_mode_iterator W
915 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
916
917 ;; This mode iterator allows :PTR to be used for patterns that operate on
918 ;; ptr_mode sized quantities.
919 (define_mode_iterator PTR
920 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
921 \f
922 ;; Scheduling descriptions
923
924 (include "pentium.md")
925 (include "ppro.md")
926 (include "k6.md")
927 (include "athlon.md")
928 (include "bdver1.md")
929 (include "geode.md")
930 (include "atom.md")
931 (include "core2.md")
932
933 \f
934 ;; Operand and operator predicates and constraints
935
936 (include "predicates.md")
937 (include "constraints.md")
938
939 \f
940 ;; Compare and branch/compare and store instructions.
941
942 (define_expand "cbranch<mode>4"
943 [(set (reg:CC FLAGS_REG)
944 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
945 (match_operand:SDWIM 2 "<general_operand>")))
946 (set (pc) (if_then_else
947 (match_operator 0 "ordered_comparison_operator"
948 [(reg:CC FLAGS_REG) (const_int 0)])
949 (label_ref (match_operand 3))
950 (pc)))]
951 ""
952 {
953 if (MEM_P (operands[1]) && MEM_P (operands[2]))
954 operands[1] = force_reg (<MODE>mode, operands[1]);
955 ix86_expand_branch (GET_CODE (operands[0]),
956 operands[1], operands[2], operands[3]);
957 DONE;
958 })
959
960 (define_expand "cstore<mode>4"
961 [(set (reg:CC FLAGS_REG)
962 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
963 (match_operand:SWIM 3 "<general_operand>")))
964 (set (match_operand:QI 0 "register_operand")
965 (match_operator 1 "ordered_comparison_operator"
966 [(reg:CC FLAGS_REG) (const_int 0)]))]
967 ""
968 {
969 if (MEM_P (operands[2]) && MEM_P (operands[3]))
970 operands[2] = force_reg (<MODE>mode, operands[2]);
971 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
972 operands[2], operands[3]);
973 DONE;
974 })
975
976 (define_expand "cmp<mode>_1"
977 [(set (reg:CC FLAGS_REG)
978 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
979 (match_operand:SWI48 1 "<general_operand>")))])
980
981 (define_insn "*cmp<mode>_ccno_1"
982 [(set (reg FLAGS_REG)
983 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
984 (match_operand:SWI 1 "const0_operand")))]
985 "ix86_match_ccmode (insn, CCNOmode)"
986 "@
987 test{<imodesuffix>}\t%0, %0
988 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
989 [(set_attr "type" "test,icmp")
990 (set_attr "length_immediate" "0,1")
991 (set_attr "mode" "<MODE>")])
992
993 (define_insn "*cmp<mode>_1"
994 [(set (reg FLAGS_REG)
995 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
996 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
997 "ix86_match_ccmode (insn, CCmode)"
998 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
999 [(set_attr "type" "icmp")
1000 (set_attr "mode" "<MODE>")])
1001
1002 (define_insn "*cmp<mode>_minus_1"
1003 [(set (reg FLAGS_REG)
1004 (compare
1005 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1006 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1007 (const_int 0)))]
1008 "ix86_match_ccmode (insn, CCGOCmode)"
1009 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1010 [(set_attr "type" "icmp")
1011 (set_attr "mode" "<MODE>")])
1012
1013 (define_insn "*cmpqi_ext_1"
1014 [(set (reg FLAGS_REG)
1015 (compare
1016 (match_operand:QI 0 "general_operand" "Qm")
1017 (subreg:QI
1018 (zero_extract:SI
1019 (match_operand 1 "ext_register_operand" "Q")
1020 (const_int 8)
1021 (const_int 8)) 0)))]
1022 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1023 "cmp{b}\t{%h1, %0|%0, %h1}"
1024 [(set_attr "type" "icmp")
1025 (set_attr "mode" "QI")])
1026
1027 (define_insn "*cmpqi_ext_1_rex64"
1028 [(set (reg FLAGS_REG)
1029 (compare
1030 (match_operand:QI 0 "register_operand" "Q")
1031 (subreg:QI
1032 (zero_extract:SI
1033 (match_operand 1 "ext_register_operand" "Q")
1034 (const_int 8)
1035 (const_int 8)) 0)))]
1036 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1037 "cmp{b}\t{%h1, %0|%0, %h1}"
1038 [(set_attr "type" "icmp")
1039 (set_attr "mode" "QI")])
1040
1041 (define_insn "*cmpqi_ext_2"
1042 [(set (reg FLAGS_REG)
1043 (compare
1044 (subreg:QI
1045 (zero_extract:SI
1046 (match_operand 0 "ext_register_operand" "Q")
1047 (const_int 8)
1048 (const_int 8)) 0)
1049 (match_operand:QI 1 "const0_operand")))]
1050 "ix86_match_ccmode (insn, CCNOmode)"
1051 "test{b}\t%h0, %h0"
1052 [(set_attr "type" "test")
1053 (set_attr "length_immediate" "0")
1054 (set_attr "mode" "QI")])
1055
1056 (define_expand "cmpqi_ext_3"
1057 [(set (reg:CC FLAGS_REG)
1058 (compare:CC
1059 (subreg:QI
1060 (zero_extract:SI
1061 (match_operand 0 "ext_register_operand")
1062 (const_int 8)
1063 (const_int 8)) 0)
1064 (match_operand:QI 1 "immediate_operand")))])
1065
1066 (define_insn "*cmpqi_ext_3_insn"
1067 [(set (reg FLAGS_REG)
1068 (compare
1069 (subreg:QI
1070 (zero_extract:SI
1071 (match_operand 0 "ext_register_operand" "Q")
1072 (const_int 8)
1073 (const_int 8)) 0)
1074 (match_operand:QI 1 "general_operand" "Qmn")))]
1075 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076 "cmp{b}\t{%1, %h0|%h0, %1}"
1077 [(set_attr "type" "icmp")
1078 (set_attr "modrm" "1")
1079 (set_attr "mode" "QI")])
1080
1081 (define_insn "*cmpqi_ext_3_insn_rex64"
1082 [(set (reg FLAGS_REG)
1083 (compare
1084 (subreg:QI
1085 (zero_extract:SI
1086 (match_operand 0 "ext_register_operand" "Q")
1087 (const_int 8)
1088 (const_int 8)) 0)
1089 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1090 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1091 "cmp{b}\t{%1, %h0|%h0, %1}"
1092 [(set_attr "type" "icmp")
1093 (set_attr "modrm" "1")
1094 (set_attr "mode" "QI")])
1095
1096 (define_insn "*cmpqi_ext_4"
1097 [(set (reg FLAGS_REG)
1098 (compare
1099 (subreg:QI
1100 (zero_extract:SI
1101 (match_operand 0 "ext_register_operand" "Q")
1102 (const_int 8)
1103 (const_int 8)) 0)
1104 (subreg:QI
1105 (zero_extract:SI
1106 (match_operand 1 "ext_register_operand" "Q")
1107 (const_int 8)
1108 (const_int 8)) 0)))]
1109 "ix86_match_ccmode (insn, CCmode)"
1110 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1111 [(set_attr "type" "icmp")
1112 (set_attr "mode" "QI")])
1113
1114 ;; These implement float point compares.
1115 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1116 ;; which would allow mix and match FP modes on the compares. Which is what
1117 ;; the old patterns did, but with many more of them.
1118
1119 (define_expand "cbranchxf4"
1120 [(set (reg:CC FLAGS_REG)
1121 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1122 (match_operand:XF 2 "nonmemory_operand")))
1123 (set (pc) (if_then_else
1124 (match_operator 0 "ix86_fp_comparison_operator"
1125 [(reg:CC FLAGS_REG)
1126 (const_int 0)])
1127 (label_ref (match_operand 3))
1128 (pc)))]
1129 "TARGET_80387"
1130 {
1131 ix86_expand_branch (GET_CODE (operands[0]),
1132 operands[1], operands[2], operands[3]);
1133 DONE;
1134 })
1135
1136 (define_expand "cstorexf4"
1137 [(set (reg:CC FLAGS_REG)
1138 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1139 (match_operand:XF 3 "nonmemory_operand")))
1140 (set (match_operand:QI 0 "register_operand")
1141 (match_operator 1 "ix86_fp_comparison_operator"
1142 [(reg:CC FLAGS_REG)
1143 (const_int 0)]))]
1144 "TARGET_80387"
1145 {
1146 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1147 operands[2], operands[3]);
1148 DONE;
1149 })
1150
1151 (define_expand "cbranch<mode>4"
1152 [(set (reg:CC FLAGS_REG)
1153 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1154 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1155 (set (pc) (if_then_else
1156 (match_operator 0 "ix86_fp_comparison_operator"
1157 [(reg:CC FLAGS_REG)
1158 (const_int 0)])
1159 (label_ref (match_operand 3))
1160 (pc)))]
1161 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1162 {
1163 ix86_expand_branch (GET_CODE (operands[0]),
1164 operands[1], operands[2], operands[3]);
1165 DONE;
1166 })
1167
1168 (define_expand "cstore<mode>4"
1169 [(set (reg:CC FLAGS_REG)
1170 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1171 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1172 (set (match_operand:QI 0 "register_operand")
1173 (match_operator 1 "ix86_fp_comparison_operator"
1174 [(reg:CC FLAGS_REG)
1175 (const_int 0)]))]
1176 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1177 {
1178 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1179 operands[2], operands[3]);
1180 DONE;
1181 })
1182
1183 (define_expand "cbranchcc4"
1184 [(set (pc) (if_then_else
1185 (match_operator 0 "comparison_operator"
1186 [(match_operand 1 "flags_reg_operand")
1187 (match_operand 2 "const0_operand")])
1188 (label_ref (match_operand 3))
1189 (pc)))]
1190 ""
1191 {
1192 ix86_expand_branch (GET_CODE (operands[0]),
1193 operands[1], operands[2], operands[3]);
1194 DONE;
1195 })
1196
1197 (define_expand "cstorecc4"
1198 [(set (match_operand:QI 0 "register_operand")
1199 (match_operator 1 "comparison_operator"
1200 [(match_operand 2 "flags_reg_operand")
1201 (match_operand 3 "const0_operand")]))]
1202 ""
1203 {
1204 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1205 operands[2], operands[3]);
1206 DONE;
1207 })
1208
1209
1210 ;; FP compares, step 1:
1211 ;; Set the FP condition codes.
1212 ;;
1213 ;; CCFPmode compare with exceptions
1214 ;; CCFPUmode compare with no exceptions
1215
1216 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1217 ;; used to manage the reg stack popping would not be preserved.
1218
1219 (define_insn "*cmpfp_0"
1220 [(set (match_operand:HI 0 "register_operand" "=a")
1221 (unspec:HI
1222 [(compare:CCFP
1223 (match_operand 1 "register_operand" "f")
1224 (match_operand 2 "const0_operand"))]
1225 UNSPEC_FNSTSW))]
1226 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1227 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1228 "* return output_fp_compare (insn, operands, false, false);"
1229 [(set_attr "type" "multi")
1230 (set_attr "unit" "i387")
1231 (set (attr "mode")
1232 (cond [(match_operand:SF 1)
1233 (const_string "SF")
1234 (match_operand:DF 1)
1235 (const_string "DF")
1236 ]
1237 (const_string "XF")))])
1238
1239 (define_insn_and_split "*cmpfp_0_cc"
1240 [(set (reg:CCFP FLAGS_REG)
1241 (compare:CCFP
1242 (match_operand 1 "register_operand" "f")
1243 (match_operand 2 "const0_operand")))
1244 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1245 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1246 && TARGET_SAHF && !TARGET_CMOVE
1247 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1248 "#"
1249 "&& reload_completed"
1250 [(set (match_dup 0)
1251 (unspec:HI
1252 [(compare:CCFP (match_dup 1)(match_dup 2))]
1253 UNSPEC_FNSTSW))
1254 (set (reg:CC FLAGS_REG)
1255 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1256 ""
1257 [(set_attr "type" "multi")
1258 (set_attr "unit" "i387")
1259 (set (attr "mode")
1260 (cond [(match_operand:SF 1)
1261 (const_string "SF")
1262 (match_operand:DF 1)
1263 (const_string "DF")
1264 ]
1265 (const_string "XF")))])
1266
1267 (define_insn "*cmpfp_xf"
1268 [(set (match_operand:HI 0 "register_operand" "=a")
1269 (unspec:HI
1270 [(compare:CCFP
1271 (match_operand:XF 1 "register_operand" "f")
1272 (match_operand:XF 2 "register_operand" "f"))]
1273 UNSPEC_FNSTSW))]
1274 "TARGET_80387"
1275 "* return output_fp_compare (insn, operands, false, false);"
1276 [(set_attr "type" "multi")
1277 (set_attr "unit" "i387")
1278 (set_attr "mode" "XF")])
1279
1280 (define_insn_and_split "*cmpfp_xf_cc"
1281 [(set (reg:CCFP FLAGS_REG)
1282 (compare:CCFP
1283 (match_operand:XF 1 "register_operand" "f")
1284 (match_operand:XF 2 "register_operand" "f")))
1285 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1286 "TARGET_80387
1287 && TARGET_SAHF && !TARGET_CMOVE"
1288 "#"
1289 "&& reload_completed"
1290 [(set (match_dup 0)
1291 (unspec:HI
1292 [(compare:CCFP (match_dup 1)(match_dup 2))]
1293 UNSPEC_FNSTSW))
1294 (set (reg:CC FLAGS_REG)
1295 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1296 ""
1297 [(set_attr "type" "multi")
1298 (set_attr "unit" "i387")
1299 (set_attr "mode" "XF")])
1300
1301 (define_insn "*cmpfp_<mode>"
1302 [(set (match_operand:HI 0 "register_operand" "=a")
1303 (unspec:HI
1304 [(compare:CCFP
1305 (match_operand:MODEF 1 "register_operand" "f")
1306 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1307 UNSPEC_FNSTSW))]
1308 "TARGET_80387"
1309 "* return output_fp_compare (insn, operands, false, false);"
1310 [(set_attr "type" "multi")
1311 (set_attr "unit" "i387")
1312 (set_attr "mode" "<MODE>")])
1313
1314 (define_insn_and_split "*cmpfp_<mode>_cc"
1315 [(set (reg:CCFP FLAGS_REG)
1316 (compare:CCFP
1317 (match_operand:MODEF 1 "register_operand" "f")
1318 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1319 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1320 "TARGET_80387
1321 && TARGET_SAHF && !TARGET_CMOVE"
1322 "#"
1323 "&& reload_completed"
1324 [(set (match_dup 0)
1325 (unspec:HI
1326 [(compare:CCFP (match_dup 1)(match_dup 2))]
1327 UNSPEC_FNSTSW))
1328 (set (reg:CC FLAGS_REG)
1329 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1330 ""
1331 [(set_attr "type" "multi")
1332 (set_attr "unit" "i387")
1333 (set_attr "mode" "<MODE>")])
1334
1335 (define_insn "*cmpfp_u"
1336 [(set (match_operand:HI 0 "register_operand" "=a")
1337 (unspec:HI
1338 [(compare:CCFPU
1339 (match_operand 1 "register_operand" "f")
1340 (match_operand 2 "register_operand" "f"))]
1341 UNSPEC_FNSTSW))]
1342 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1343 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1344 "* return output_fp_compare (insn, operands, false, true);"
1345 [(set_attr "type" "multi")
1346 (set_attr "unit" "i387")
1347 (set (attr "mode")
1348 (cond [(match_operand:SF 1)
1349 (const_string "SF")
1350 (match_operand:DF 1)
1351 (const_string "DF")
1352 ]
1353 (const_string "XF")))])
1354
1355 (define_insn_and_split "*cmpfp_u_cc"
1356 [(set (reg:CCFPU FLAGS_REG)
1357 (compare:CCFPU
1358 (match_operand 1 "register_operand" "f")
1359 (match_operand 2 "register_operand" "f")))
1360 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1361 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1362 && TARGET_SAHF && !TARGET_CMOVE
1363 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1364 "#"
1365 "&& reload_completed"
1366 [(set (match_dup 0)
1367 (unspec:HI
1368 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1369 UNSPEC_FNSTSW))
1370 (set (reg:CC FLAGS_REG)
1371 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1372 ""
1373 [(set_attr "type" "multi")
1374 (set_attr "unit" "i387")
1375 (set (attr "mode")
1376 (cond [(match_operand:SF 1)
1377 (const_string "SF")
1378 (match_operand:DF 1)
1379 (const_string "DF")
1380 ]
1381 (const_string "XF")))])
1382
1383 (define_insn "*cmpfp_<mode>"
1384 [(set (match_operand:HI 0 "register_operand" "=a")
1385 (unspec:HI
1386 [(compare:CCFP
1387 (match_operand 1 "register_operand" "f")
1388 (match_operator 3 "float_operator"
1389 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1390 UNSPEC_FNSTSW))]
1391 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1392 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1393 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1394 "* return output_fp_compare (insn, operands, false, false);"
1395 [(set_attr "type" "multi")
1396 (set_attr "unit" "i387")
1397 (set_attr "fp_int_src" "true")
1398 (set_attr "mode" "<MODE>")])
1399
1400 (define_insn_and_split "*cmpfp_<mode>_cc"
1401 [(set (reg:CCFP FLAGS_REG)
1402 (compare:CCFP
1403 (match_operand 1 "register_operand" "f")
1404 (match_operator 3 "float_operator"
1405 [(match_operand:SWI24 2 "memory_operand" "m")])))
1406 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1407 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1408 && TARGET_SAHF && !TARGET_CMOVE
1409 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1410 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1411 "#"
1412 "&& reload_completed"
1413 [(set (match_dup 0)
1414 (unspec:HI
1415 [(compare:CCFP
1416 (match_dup 1)
1417 (match_op_dup 3 [(match_dup 2)]))]
1418 UNSPEC_FNSTSW))
1419 (set (reg:CC FLAGS_REG)
1420 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1421 ""
1422 [(set_attr "type" "multi")
1423 (set_attr "unit" "i387")
1424 (set_attr "fp_int_src" "true")
1425 (set_attr "mode" "<MODE>")])
1426
1427 ;; FP compares, step 2
1428 ;; Move the fpsw to ax.
1429
1430 (define_insn "x86_fnstsw_1"
1431 [(set (match_operand:HI 0 "register_operand" "=a")
1432 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1433 "TARGET_80387"
1434 "fnstsw\t%0"
1435 [(set (attr "length")
1436 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1437 (set_attr "mode" "SI")
1438 (set_attr "unit" "i387")])
1439
1440 ;; FP compares, step 3
1441 ;; Get ax into flags, general case.
1442
1443 (define_insn "x86_sahf_1"
1444 [(set (reg:CC FLAGS_REG)
1445 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1446 UNSPEC_SAHF))]
1447 "TARGET_SAHF"
1448 {
1449 #ifndef HAVE_AS_IX86_SAHF
1450 if (TARGET_64BIT)
1451 return ASM_BYTE "0x9e";
1452 else
1453 #endif
1454 return "sahf";
1455 }
1456 [(set_attr "length" "1")
1457 (set_attr "athlon_decode" "vector")
1458 (set_attr "amdfam10_decode" "direct")
1459 (set_attr "bdver1_decode" "direct")
1460 (set_attr "mode" "SI")])
1461
1462 ;; Pentium Pro can do steps 1 through 3 in one go.
1463 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1464 ;; (these i387 instructions set flags directly)
1465 (define_insn "*cmpfp_i_mixed"
1466 [(set (reg:CCFP FLAGS_REG)
1467 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1468 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1469 "TARGET_MIX_SSE_I387
1470 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1471 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1472 "* return output_fp_compare (insn, operands, true, false);"
1473 [(set_attr "type" "fcmp,ssecomi")
1474 (set_attr "prefix" "orig,maybe_vex")
1475 (set (attr "mode")
1476 (if_then_else (match_operand:SF 1)
1477 (const_string "SF")
1478 (const_string "DF")))
1479 (set (attr "prefix_rep")
1480 (if_then_else (eq_attr "type" "ssecomi")
1481 (const_string "0")
1482 (const_string "*")))
1483 (set (attr "prefix_data16")
1484 (cond [(eq_attr "type" "fcmp")
1485 (const_string "*")
1486 (eq_attr "mode" "DF")
1487 (const_string "1")
1488 ]
1489 (const_string "0")))
1490 (set_attr "athlon_decode" "vector")
1491 (set_attr "amdfam10_decode" "direct")
1492 (set_attr "bdver1_decode" "double")])
1493
1494 (define_insn "*cmpfp_i_sse"
1495 [(set (reg:CCFP FLAGS_REG)
1496 (compare:CCFP (match_operand 0 "register_operand" "x")
1497 (match_operand 1 "nonimmediate_operand" "xm")))]
1498 "TARGET_SSE_MATH
1499 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1500 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1501 "* return output_fp_compare (insn, operands, true, false);"
1502 [(set_attr "type" "ssecomi")
1503 (set_attr "prefix" "maybe_vex")
1504 (set (attr "mode")
1505 (if_then_else (match_operand:SF 1)
1506 (const_string "SF")
1507 (const_string "DF")))
1508 (set_attr "prefix_rep" "0")
1509 (set (attr "prefix_data16")
1510 (if_then_else (eq_attr "mode" "DF")
1511 (const_string "1")
1512 (const_string "0")))
1513 (set_attr "athlon_decode" "vector")
1514 (set_attr "amdfam10_decode" "direct")
1515 (set_attr "bdver1_decode" "double")])
1516
1517 (define_insn "*cmpfp_i_i387"
1518 [(set (reg:CCFP FLAGS_REG)
1519 (compare:CCFP (match_operand 0 "register_operand" "f")
1520 (match_operand 1 "register_operand" "f")))]
1521 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1522 && TARGET_CMOVE
1523 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1524 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1525 "* return output_fp_compare (insn, operands, true, false);"
1526 [(set_attr "type" "fcmp")
1527 (set (attr "mode")
1528 (cond [(match_operand:SF 1)
1529 (const_string "SF")
1530 (match_operand:DF 1)
1531 (const_string "DF")
1532 ]
1533 (const_string "XF")))
1534 (set_attr "athlon_decode" "vector")
1535 (set_attr "amdfam10_decode" "direct")
1536 (set_attr "bdver1_decode" "double")])
1537
1538 (define_insn "*cmpfp_iu_mixed"
1539 [(set (reg:CCFPU FLAGS_REG)
1540 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1541 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1542 "TARGET_MIX_SSE_I387
1543 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1544 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1545 "* return output_fp_compare (insn, operands, true, true);"
1546 [(set_attr "type" "fcmp,ssecomi")
1547 (set_attr "prefix" "orig,maybe_vex")
1548 (set (attr "mode")
1549 (if_then_else (match_operand:SF 1)
1550 (const_string "SF")
1551 (const_string "DF")))
1552 (set (attr "prefix_rep")
1553 (if_then_else (eq_attr "type" "ssecomi")
1554 (const_string "0")
1555 (const_string "*")))
1556 (set (attr "prefix_data16")
1557 (cond [(eq_attr "type" "fcmp")
1558 (const_string "*")
1559 (eq_attr "mode" "DF")
1560 (const_string "1")
1561 ]
1562 (const_string "0")))
1563 (set_attr "athlon_decode" "vector")
1564 (set_attr "amdfam10_decode" "direct")
1565 (set_attr "bdver1_decode" "double")])
1566
1567 (define_insn "*cmpfp_iu_sse"
1568 [(set (reg:CCFPU FLAGS_REG)
1569 (compare:CCFPU (match_operand 0 "register_operand" "x")
1570 (match_operand 1 "nonimmediate_operand" "xm")))]
1571 "TARGET_SSE_MATH
1572 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1573 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1574 "* return output_fp_compare (insn, operands, true, true);"
1575 [(set_attr "type" "ssecomi")
1576 (set_attr "prefix" "maybe_vex")
1577 (set (attr "mode")
1578 (if_then_else (match_operand:SF 1)
1579 (const_string "SF")
1580 (const_string "DF")))
1581 (set_attr "prefix_rep" "0")
1582 (set (attr "prefix_data16")
1583 (if_then_else (eq_attr "mode" "DF")
1584 (const_string "1")
1585 (const_string "0")))
1586 (set_attr "athlon_decode" "vector")
1587 (set_attr "amdfam10_decode" "direct")
1588 (set_attr "bdver1_decode" "double")])
1589
1590 (define_insn "*cmpfp_iu_387"
1591 [(set (reg:CCFPU FLAGS_REG)
1592 (compare:CCFPU (match_operand 0 "register_operand" "f")
1593 (match_operand 1 "register_operand" "f")))]
1594 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1595 && TARGET_CMOVE
1596 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1597 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1598 "* return output_fp_compare (insn, operands, true, true);"
1599 [(set_attr "type" "fcmp")
1600 (set (attr "mode")
1601 (cond [(match_operand:SF 1)
1602 (const_string "SF")
1603 (match_operand:DF 1)
1604 (const_string "DF")
1605 ]
1606 (const_string "XF")))
1607 (set_attr "athlon_decode" "vector")
1608 (set_attr "amdfam10_decode" "direct")
1609 (set_attr "bdver1_decode" "direct")])
1610 \f
1611 ;; Push/pop instructions.
1612
1613 (define_insn "*push<mode>2"
1614 [(set (match_operand:DWI 0 "push_operand" "=<")
1615 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1616 ""
1617 "#"
1618 [(set_attr "type" "multi")
1619 (set_attr "mode" "<MODE>")])
1620
1621 (define_split
1622 [(set (match_operand:TI 0 "push_operand")
1623 (match_operand:TI 1 "general_operand"))]
1624 "TARGET_64BIT && reload_completed
1625 && !SSE_REG_P (operands[1])"
1626 [(const_int 0)]
1627 "ix86_split_long_move (operands); DONE;")
1628
1629 (define_insn "*pushdi2_rex64"
1630 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1631 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1632 "TARGET_64BIT"
1633 "@
1634 push{q}\t%1
1635 #"
1636 [(set_attr "type" "push,multi")
1637 (set_attr "mode" "DI")])
1638
1639 ;; Convert impossible pushes of immediate to existing instructions.
1640 ;; First try to get scratch register and go through it. In case this
1641 ;; fails, push sign extended lower part first and then overwrite
1642 ;; upper part by 32bit move.
1643 (define_peephole2
1644 [(match_scratch:DI 2 "r")
1645 (set (match_operand:DI 0 "push_operand")
1646 (match_operand:DI 1 "immediate_operand"))]
1647 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1648 && !x86_64_immediate_operand (operands[1], DImode)"
1649 [(set (match_dup 2) (match_dup 1))
1650 (set (match_dup 0) (match_dup 2))])
1651
1652 ;; We need to define this as both peepholer and splitter for case
1653 ;; peephole2 pass is not run.
1654 ;; "&& 1" is needed to keep it from matching the previous pattern.
1655 (define_peephole2
1656 [(set (match_operand:DI 0 "push_operand")
1657 (match_operand:DI 1 "immediate_operand"))]
1658 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1659 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1660 [(set (match_dup 0) (match_dup 1))
1661 (set (match_dup 2) (match_dup 3))]
1662 {
1663 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1664
1665 operands[1] = gen_lowpart (DImode, operands[2]);
1666 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1667 GEN_INT (4)));
1668 })
1669
1670 (define_split
1671 [(set (match_operand:DI 0 "push_operand")
1672 (match_operand:DI 1 "immediate_operand"))]
1673 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1674 ? epilogue_completed : reload_completed)
1675 && !symbolic_operand (operands[1], DImode)
1676 && !x86_64_immediate_operand (operands[1], DImode)"
1677 [(set (match_dup 0) (match_dup 1))
1678 (set (match_dup 2) (match_dup 3))]
1679 {
1680 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1681
1682 operands[1] = gen_lowpart (DImode, operands[2]);
1683 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1684 GEN_INT (4)));
1685 })
1686
1687 (define_split
1688 [(set (match_operand:DI 0 "push_operand")
1689 (match_operand:DI 1 "general_operand"))]
1690 "!TARGET_64BIT && reload_completed
1691 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1692 [(const_int 0)]
1693 "ix86_split_long_move (operands); DONE;")
1694
1695 (define_insn "*pushsi2"
1696 [(set (match_operand:SI 0 "push_operand" "=<")
1697 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1698 "!TARGET_64BIT"
1699 "push{l}\t%1"
1700 [(set_attr "type" "push")
1701 (set_attr "mode" "SI")])
1702
1703 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1704 ;; "push a byte/word". But actually we use pushl, which has the effect
1705 ;; of rounding the amount pushed up to a word.
1706
1707 ;; For TARGET_64BIT we always round up to 8 bytes.
1708 (define_insn "*push<mode>2_rex64"
1709 [(set (match_operand:SWI124 0 "push_operand" "=X")
1710 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1711 "TARGET_64BIT"
1712 "push{q}\t%q1"
1713 [(set_attr "type" "push")
1714 (set_attr "mode" "DI")])
1715
1716 (define_insn "*push<mode>2"
1717 [(set (match_operand:SWI12 0 "push_operand" "=X")
1718 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1719 "!TARGET_64BIT"
1720 "push{l}\t%k1"
1721 [(set_attr "type" "push")
1722 (set_attr "mode" "SI")])
1723
1724 (define_insn "*push<mode>2_prologue"
1725 [(set (match_operand:W 0 "push_operand" "=<")
1726 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1727 (clobber (mem:BLK (scratch)))]
1728 ""
1729 "push{<imodesuffix>}\t%1"
1730 [(set_attr "type" "push")
1731 (set_attr "mode" "<MODE>")])
1732
1733 (define_insn "*pop<mode>1"
1734 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1735 (match_operand:W 1 "pop_operand" ">"))]
1736 ""
1737 "pop{<imodesuffix>}\t%0"
1738 [(set_attr "type" "pop")
1739 (set_attr "mode" "<MODE>")])
1740
1741 (define_insn "*pop<mode>1_epilogue"
1742 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1743 (match_operand:W 1 "pop_operand" ">"))
1744 (clobber (mem:BLK (scratch)))]
1745 ""
1746 "pop{<imodesuffix>}\t%0"
1747 [(set_attr "type" "pop")
1748 (set_attr "mode" "<MODE>")])
1749 \f
1750 ;; Move instructions.
1751
1752 (define_expand "movoi"
1753 [(set (match_operand:OI 0 "nonimmediate_operand")
1754 (match_operand:OI 1 "general_operand"))]
1755 "TARGET_AVX"
1756 "ix86_expand_move (OImode, operands); DONE;")
1757
1758 (define_expand "movti"
1759 [(set (match_operand:TI 0 "nonimmediate_operand")
1760 (match_operand:TI 1 "nonimmediate_operand"))]
1761 "TARGET_64BIT || TARGET_SSE"
1762 {
1763 if (TARGET_64BIT)
1764 ix86_expand_move (TImode, operands);
1765 else if (push_operand (operands[0], TImode))
1766 ix86_expand_push (TImode, operands[1]);
1767 else
1768 ix86_expand_vector_move (TImode, operands);
1769 DONE;
1770 })
1771
1772 ;; This expands to what emit_move_complex would generate if we didn't
1773 ;; have a movti pattern. Having this avoids problems with reload on
1774 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1775 ;; to have around all the time.
1776 (define_expand "movcdi"
1777 [(set (match_operand:CDI 0 "nonimmediate_operand")
1778 (match_operand:CDI 1 "general_operand"))]
1779 ""
1780 {
1781 if (push_operand (operands[0], CDImode))
1782 emit_move_complex_push (CDImode, operands[0], operands[1]);
1783 else
1784 emit_move_complex_parts (operands[0], operands[1]);
1785 DONE;
1786 })
1787
1788 (define_expand "mov<mode>"
1789 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1790 (match_operand:SWI1248x 1 "general_operand"))]
1791 ""
1792 "ix86_expand_move (<MODE>mode, operands); DONE;")
1793
1794 (define_insn "*mov<mode>_xor"
1795 [(set (match_operand:SWI48 0 "register_operand" "=r")
1796 (match_operand:SWI48 1 "const0_operand"))
1797 (clobber (reg:CC FLAGS_REG))]
1798 "reload_completed"
1799 "xor{l}\t%k0, %k0"
1800 [(set_attr "type" "alu1")
1801 (set_attr "mode" "SI")
1802 (set_attr "length_immediate" "0")])
1803
1804 (define_insn "*mov<mode>_or"
1805 [(set (match_operand:SWI48 0 "register_operand" "=r")
1806 (match_operand:SWI48 1 "const_int_operand"))
1807 (clobber (reg:CC FLAGS_REG))]
1808 "reload_completed
1809 && operands[1] == constm1_rtx"
1810 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1811 [(set_attr "type" "alu1")
1812 (set_attr "mode" "<MODE>")
1813 (set_attr "length_immediate" "1")])
1814
1815 (define_insn "*movoi_internal_avx"
1816 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1817 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1818 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1819 {
1820 switch (which_alternative)
1821 {
1822 case 0:
1823 return standard_sse_constant_opcode (insn, operands[1]);
1824 case 1:
1825 case 2:
1826 if (misaligned_operand (operands[0], OImode)
1827 || misaligned_operand (operands[1], OImode))
1828 {
1829 if (get_attr_mode (insn) == MODE_V8SF)
1830 return "vmovups\t{%1, %0|%0, %1}";
1831 else
1832 return "vmovdqu\t{%1, %0|%0, %1}";
1833 }
1834 else
1835 {
1836 if (get_attr_mode (insn) == MODE_V8SF)
1837 return "vmovaps\t{%1, %0|%0, %1}";
1838 else
1839 return "vmovdqa\t{%1, %0|%0, %1}";
1840 }
1841 default:
1842 gcc_unreachable ();
1843 }
1844 }
1845 [(set_attr "type" "sselog1,ssemov,ssemov")
1846 (set_attr "prefix" "vex")
1847 (set (attr "mode")
1848 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1849 (const_string "V8SF")
1850 (and (eq_attr "alternative" "2")
1851 (match_test "TARGET_SSE_TYPELESS_STORES"))
1852 (const_string "V8SF")
1853 ]
1854 (const_string "OI")))])
1855
1856 (define_insn "*movti_internal_rex64"
1857 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1858 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1859 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1860 {
1861 switch (which_alternative)
1862 {
1863 case 0:
1864 case 1:
1865 return "#";
1866 case 2:
1867 return standard_sse_constant_opcode (insn, operands[1]);
1868 case 3:
1869 case 4:
1870 /* TDmode values are passed as TImode on the stack. Moving them
1871 to stack may result in unaligned memory access. */
1872 if (misaligned_operand (operands[0], TImode)
1873 || misaligned_operand (operands[1], TImode))
1874 {
1875 if (get_attr_mode (insn) == MODE_V4SF)
1876 return "%vmovups\t{%1, %0|%0, %1}";
1877 else
1878 return "%vmovdqu\t{%1, %0|%0, %1}";
1879 }
1880 else
1881 {
1882 if (get_attr_mode (insn) == MODE_V4SF)
1883 return "%vmovaps\t{%1, %0|%0, %1}";
1884 else
1885 return "%vmovdqa\t{%1, %0|%0, %1}";
1886 }
1887 default:
1888 gcc_unreachable ();
1889 }
1890 }
1891 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1892 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1893 (set (attr "mode")
1894 (cond [(eq_attr "alternative" "0,1")
1895 (const_string "DI")
1896 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1897 (const_string "V4SF")
1898 (and (eq_attr "alternative" "4")
1899 (match_test "TARGET_SSE_TYPELESS_STORES"))
1900 (const_string "V4SF")
1901 (match_test "TARGET_AVX")
1902 (const_string "TI")
1903 (match_test "optimize_function_for_size_p (cfun)")
1904 (const_string "V4SF")
1905 ]
1906 (const_string "TI")))])
1907
1908 (define_split
1909 [(set (match_operand:TI 0 "nonimmediate_operand")
1910 (match_operand:TI 1 "general_operand"))]
1911 "reload_completed
1912 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1913 [(const_int 0)]
1914 "ix86_split_long_move (operands); DONE;")
1915
1916 (define_insn "*movti_internal_sse"
1917 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1918 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1919 "TARGET_SSE && !TARGET_64BIT
1920 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1921 {
1922 switch (which_alternative)
1923 {
1924 case 0:
1925 return standard_sse_constant_opcode (insn, operands[1]);
1926 case 1:
1927 case 2:
1928 /* TDmode values are passed as TImode on the stack. Moving them
1929 to stack may result in unaligned memory access. */
1930 if (misaligned_operand (operands[0], TImode)
1931 || misaligned_operand (operands[1], TImode))
1932 {
1933 if (get_attr_mode (insn) == MODE_V4SF)
1934 return "%vmovups\t{%1, %0|%0, %1}";
1935 else
1936 return "%vmovdqu\t{%1, %0|%0, %1}";
1937 }
1938 else
1939 {
1940 if (get_attr_mode (insn) == MODE_V4SF)
1941 return "%vmovaps\t{%1, %0|%0, %1}";
1942 else
1943 return "%vmovdqa\t{%1, %0|%0, %1}";
1944 }
1945 default:
1946 gcc_unreachable ();
1947 }
1948 }
1949 [(set_attr "type" "sselog1,ssemov,ssemov")
1950 (set_attr "prefix" "maybe_vex")
1951 (set (attr "mode")
1952 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1953 (const_string "V4SF")
1954 (and (eq_attr "alternative" "2")
1955 (match_test "TARGET_SSE_TYPELESS_STORES"))
1956 (const_string "V4SF")
1957 (match_test "TARGET_AVX")
1958 (const_string "TI")
1959 (ior (not (match_test "TARGET_SSE2"))
1960 (match_test "optimize_function_for_size_p (cfun)"))
1961 (const_string "V4SF")
1962 ]
1963 (const_string "TI")))])
1964
1965 (define_insn "*movdi_internal_rex64"
1966 [(set (match_operand:DI 0 "nonimmediate_operand"
1967 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1968 (match_operand:DI 1 "general_operand"
1969 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1970 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1971 {
1972 switch (get_attr_type (insn))
1973 {
1974 case TYPE_SSECVT:
1975 if (SSE_REG_P (operands[0]))
1976 return "movq2dq\t{%1, %0|%0, %1}";
1977 else
1978 return "movdq2q\t{%1, %0|%0, %1}";
1979
1980 case TYPE_SSEMOV:
1981 if (get_attr_mode (insn) == MODE_V4SF)
1982 return "%vmovaps\t{%1, %0|%0, %1}";
1983 else if (get_attr_mode (insn) == MODE_TI)
1984 return "%vmovdqa\t{%1, %0|%0, %1}";
1985
1986 /* Handle broken assemblers that require movd instead of movq. */
1987 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1988 return "%vmovd\t{%1, %0|%0, %1}";
1989 else
1990 return "%vmovq\t{%1, %0|%0, %1}";
1991
1992 case TYPE_MMXMOV:
1993 /* Handle broken assemblers that require movd instead of movq. */
1994 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1995 return "movd\t{%1, %0|%0, %1}";
1996 else
1997 return "movq\t{%1, %0|%0, %1}";
1998
1999 case TYPE_SSELOG1:
2000 return standard_sse_constant_opcode (insn, operands[1]);
2001
2002 case TYPE_MMX:
2003 return "pxor\t%0, %0";
2004
2005 case TYPE_MULTI:
2006 return "#";
2007
2008 case TYPE_LEA:
2009 return "lea{q}\t{%E1, %0|%0, %E1}";
2010
2011 default:
2012 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2013 if (get_attr_mode (insn) == MODE_SI)
2014 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2015 else if (which_alternative == 2)
2016 return "movabs{q}\t{%1, %0|%0, %1}";
2017 else if (ix86_use_lea_for_mov (insn, operands))
2018 return "lea{q}\t{%E1, %0|%0, %E1}";
2019 else
2020 return "mov{q}\t{%1, %0|%0, %1}";
2021 }
2022 }
2023 [(set (attr "type")
2024 (cond [(eq_attr "alternative" "4")
2025 (const_string "multi")
2026 (eq_attr "alternative" "5")
2027 (const_string "mmx")
2028 (eq_attr "alternative" "6,7,8,9")
2029 (const_string "mmxmov")
2030 (eq_attr "alternative" "10")
2031 (const_string "sselog1")
2032 (eq_attr "alternative" "11,12,13,14,15")
2033 (const_string "ssemov")
2034 (eq_attr "alternative" "16,17")
2035 (const_string "ssecvt")
2036 (match_operand 1 "pic_32bit_operand")
2037 (const_string "lea")
2038 ]
2039 (const_string "imov")))
2040 (set (attr "modrm")
2041 (if_then_else
2042 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2043 (const_string "0")
2044 (const_string "*")))
2045 (set (attr "length_immediate")
2046 (if_then_else
2047 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2048 (const_string "8")
2049 (const_string "*")))
2050 (set (attr "prefix_rex")
2051 (if_then_else (eq_attr "alternative" "8,9")
2052 (const_string "1")
2053 (const_string "*")))
2054 (set (attr "prefix_data16")
2055 (if_then_else (eq_attr "alternative" "11")
2056 (const_string "1")
2057 (const_string "*")))
2058 (set (attr "prefix")
2059 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2060 (const_string "maybe_vex")
2061 (const_string "orig")))
2062 (set (attr "mode")
2063 (cond [(eq_attr "alternative" "0,4")
2064 (const_string "SI")
2065 (eq_attr "alternative" "10,12")
2066 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2067 (const_string "V4SF")
2068 (match_test "TARGET_AVX")
2069 (const_string "TI")
2070 (match_test "optimize_function_for_size_p (cfun)")
2071 (const_string "V4SF")
2072 ]
2073 (const_string "TI"))
2074 ]
2075 (const_string "DI")))])
2076
2077 ;; Reload patterns to support multi-word load/store
2078 ;; with non-offsetable address.
2079 (define_expand "reload_noff_store"
2080 [(parallel [(match_operand 0 "memory_operand" "=m")
2081 (match_operand 1 "register_operand" "r")
2082 (match_operand:DI 2 "register_operand" "=&r")])]
2083 "TARGET_64BIT"
2084 {
2085 rtx mem = operands[0];
2086 rtx addr = XEXP (mem, 0);
2087
2088 emit_move_insn (operands[2], addr);
2089 mem = replace_equiv_address_nv (mem, operands[2]);
2090
2091 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2092 DONE;
2093 })
2094
2095 (define_expand "reload_noff_load"
2096 [(parallel [(match_operand 0 "register_operand" "=r")
2097 (match_operand 1 "memory_operand" "m")
2098 (match_operand:DI 2 "register_operand" "=r")])]
2099 "TARGET_64BIT"
2100 {
2101 rtx mem = operands[1];
2102 rtx addr = XEXP (mem, 0);
2103
2104 emit_move_insn (operands[2], addr);
2105 mem = replace_equiv_address_nv (mem, operands[2]);
2106
2107 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2108 DONE;
2109 })
2110
2111 ;; Convert impossible stores of immediate to existing instructions.
2112 ;; First try to get scratch register and go through it. In case this
2113 ;; fails, move by 32bit parts.
2114 (define_peephole2
2115 [(match_scratch:DI 2 "r")
2116 (set (match_operand:DI 0 "memory_operand")
2117 (match_operand:DI 1 "immediate_operand"))]
2118 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2119 && !x86_64_immediate_operand (operands[1], DImode)"
2120 [(set (match_dup 2) (match_dup 1))
2121 (set (match_dup 0) (match_dup 2))])
2122
2123 ;; We need to define this as both peepholer and splitter for case
2124 ;; peephole2 pass is not run.
2125 ;; "&& 1" is needed to keep it from matching the previous pattern.
2126 (define_peephole2
2127 [(set (match_operand:DI 0 "memory_operand")
2128 (match_operand:DI 1 "immediate_operand"))]
2129 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2131 [(set (match_dup 2) (match_dup 3))
2132 (set (match_dup 4) (match_dup 5))]
2133 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2134
2135 (define_split
2136 [(set (match_operand:DI 0 "memory_operand")
2137 (match_operand:DI 1 "immediate_operand"))]
2138 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2139 ? epilogue_completed : reload_completed)
2140 && !symbolic_operand (operands[1], DImode)
2141 && !x86_64_immediate_operand (operands[1], DImode)"
2142 [(set (match_dup 2) (match_dup 3))
2143 (set (match_dup 4) (match_dup 5))]
2144 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2145
2146 (define_insn "*movdi_internal"
2147 [(set (match_operand:DI 0 "nonimmediate_operand"
2148 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2149 (match_operand:DI 1 "general_operand"
2150 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2151 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2152 {
2153 switch (get_attr_type (insn))
2154 {
2155 case TYPE_SSECVT:
2156 if (SSE_REG_P (operands[0]))
2157 return "movq2dq\t{%1, %0|%0, %1}";
2158 else
2159 return "movdq2q\t{%1, %0|%0, %1}";
2160
2161 case TYPE_SSEMOV:
2162 switch (get_attr_mode (insn))
2163 {
2164 case MODE_TI:
2165 return "%vmovdqa\t{%1, %0|%0, %1}";
2166 case MODE_DI:
2167 return "%vmovq\t{%1, %0|%0, %1}";
2168 case MODE_V4SF:
2169 return "%vmovaps\t{%1, %0|%0, %1}";
2170 case MODE_V2SF:
2171 return "movlps\t{%1, %0|%0, %1}";
2172 default:
2173 gcc_unreachable ();
2174 }
2175
2176 case TYPE_MMXMOV:
2177 return "movq\t{%1, %0|%0, %1}";
2178
2179 case TYPE_SSELOG1:
2180 return standard_sse_constant_opcode (insn, operands[1]);
2181
2182 case TYPE_MMX:
2183 return "pxor\t%0, %0";
2184
2185 case TYPE_MULTI:
2186 return "#";
2187
2188 default:
2189 gcc_unreachable ();
2190 }
2191 }
2192 [(set (attr "isa")
2193 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2194 (const_string "sse2")
2195 (eq_attr "alternative" "9,10,11,12")
2196 (const_string "noavx")
2197 ]
2198 (const_string "*")))
2199 (set (attr "type")
2200 (cond [(eq_attr "alternative" "0,1")
2201 (const_string "multi")
2202 (eq_attr "alternative" "2")
2203 (const_string "mmx")
2204 (eq_attr "alternative" "3,4")
2205 (const_string "mmxmov")
2206 (eq_attr "alternative" "5,9")
2207 (const_string "sselog1")
2208 (eq_attr "alternative" "13,14")
2209 (const_string "ssecvt")
2210 ]
2211 (const_string "ssemov")))
2212 (set (attr "prefix")
2213 (if_then_else (eq_attr "alternative" "5,6,7,8")
2214 (const_string "maybe_vex")
2215 (const_string "orig")))
2216 (set (attr "mode")
2217 (cond [(eq_attr "alternative" "9,11")
2218 (const_string "V4SF")
2219 (eq_attr "alternative" "10,12")
2220 (const_string "V2SF")
2221 (eq_attr "alternative" "5,7")
2222 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2223 (const_string "V4SF")
2224 (match_test "TARGET_AVX")
2225 (const_string "TI")
2226 (match_test "optimize_function_for_size_p (cfun)")
2227 (const_string "V4SF")
2228 ]
2229 (const_string "TI"))
2230 ]
2231 (const_string "DI")))])
2232
2233 (define_split
2234 [(set (match_operand:DI 0 "nonimmediate_operand")
2235 (match_operand:DI 1 "general_operand"))]
2236 "!TARGET_64BIT && reload_completed
2237 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2238 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2239 [(const_int 0)]
2240 "ix86_split_long_move (operands); DONE;")
2241
2242 (define_insn "*movsi_internal"
2243 [(set (match_operand:SI 0 "nonimmediate_operand"
2244 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2245 (match_operand:SI 1 "general_operand"
2246 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2247 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2248 {
2249 switch (get_attr_type (insn))
2250 {
2251 case TYPE_SSELOG1:
2252 return standard_sse_constant_opcode (insn, operands[1]);
2253
2254 case TYPE_SSEMOV:
2255 switch (get_attr_mode (insn))
2256 {
2257 case MODE_TI:
2258 return "%vmovdqa\t{%1, %0|%0, %1}";
2259 case MODE_V4SF:
2260 return "%vmovaps\t{%1, %0|%0, %1}";
2261 case MODE_SI:
2262 return "%vmovd\t{%1, %0|%0, %1}";
2263 case MODE_SF:
2264 return "%vmovss\t{%1, %0|%0, %1}";
2265 default:
2266 gcc_unreachable ();
2267 }
2268
2269 case TYPE_MMX:
2270 return "pxor\t%0, %0";
2271
2272 case TYPE_MMXMOV:
2273 if (get_attr_mode (insn) == MODE_DI)
2274 return "movq\t{%1, %0|%0, %1}";
2275 return "movd\t{%1, %0|%0, %1}";
2276
2277 case TYPE_LEA:
2278 return "lea{l}\t{%E1, %0|%0, %E1}";
2279
2280 default:
2281 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2282 if (ix86_use_lea_for_mov (insn, operands))
2283 return "lea{l}\t{%E1, %0|%0, %E1}";
2284 else
2285 return "mov{l}\t{%1, %0|%0, %1}";
2286 }
2287 }
2288 [(set (attr "type")
2289 (cond [(eq_attr "alternative" "2")
2290 (const_string "mmx")
2291 (eq_attr "alternative" "3,4,5")
2292 (const_string "mmxmov")
2293 (eq_attr "alternative" "6")
2294 (const_string "sselog1")
2295 (eq_attr "alternative" "7,8,9,10,11")
2296 (const_string "ssemov")
2297 (match_operand 1 "pic_32bit_operand")
2298 (const_string "lea")
2299 ]
2300 (const_string "imov")))
2301 (set (attr "prefix")
2302 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2303 (const_string "orig")
2304 (const_string "maybe_vex")))
2305 (set (attr "prefix_data16")
2306 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2307 (const_string "1")
2308 (const_string "*")))
2309 (set (attr "mode")
2310 (cond [(eq_attr "alternative" "2,3")
2311 (const_string "DI")
2312 (eq_attr "alternative" "6,7")
2313 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2314 (const_string "V4SF")
2315 (match_test "TARGET_AVX")
2316 (const_string "TI")
2317 (ior (not (match_test "TARGET_SSE2"))
2318 (match_test "optimize_function_for_size_p (cfun)"))
2319 (const_string "V4SF")
2320 ]
2321 (const_string "TI"))
2322 (and (eq_attr "alternative" "8,9,10,11")
2323 (not (match_test "TARGET_SSE2")))
2324 (const_string "SF")
2325 ]
2326 (const_string "SI")))])
2327
2328 (define_insn "*movhi_internal"
2329 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2330 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2331 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2332 {
2333 switch (get_attr_type (insn))
2334 {
2335 case TYPE_IMOVX:
2336 /* movzwl is faster than movw on p2 due to partial word stalls,
2337 though not as fast as an aligned movl. */
2338 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2339 default:
2340 if (get_attr_mode (insn) == MODE_SI)
2341 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2342 else
2343 return "mov{w}\t{%1, %0|%0, %1}";
2344 }
2345 }
2346 [(set (attr "type")
2347 (cond [(match_test "optimize_function_for_size_p (cfun)")
2348 (const_string "imov")
2349 (and (eq_attr "alternative" "0")
2350 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2351 (not (match_test "TARGET_HIMODE_MATH"))))
2352 (const_string "imov")
2353 (and (eq_attr "alternative" "1,2")
2354 (match_operand:HI 1 "aligned_operand"))
2355 (const_string "imov")
2356 (and (match_test "TARGET_MOVX")
2357 (eq_attr "alternative" "0,2"))
2358 (const_string "imovx")
2359 ]
2360 (const_string "imov")))
2361 (set (attr "mode")
2362 (cond [(eq_attr "type" "imovx")
2363 (const_string "SI")
2364 (and (eq_attr "alternative" "1,2")
2365 (match_operand:HI 1 "aligned_operand"))
2366 (const_string "SI")
2367 (and (eq_attr "alternative" "0")
2368 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2369 (not (match_test "TARGET_HIMODE_MATH"))))
2370 (const_string "SI")
2371 ]
2372 (const_string "HI")))])
2373
2374 ;; Situation is quite tricky about when to choose full sized (SImode) move
2375 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2376 ;; partial register dependency machines (such as AMD Athlon), where QImode
2377 ;; moves issue extra dependency and for partial register stalls machines
2378 ;; that don't use QImode patterns (and QImode move cause stall on the next
2379 ;; instruction).
2380 ;;
2381 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2382 ;; register stall machines with, where we use QImode instructions, since
2383 ;; partial register stall can be caused there. Then we use movzx.
2384 (define_insn "*movqi_internal"
2385 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2386 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2387 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2388 {
2389 switch (get_attr_type (insn))
2390 {
2391 case TYPE_IMOVX:
2392 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2393 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2394 default:
2395 if (get_attr_mode (insn) == MODE_SI)
2396 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2397 else
2398 return "mov{b}\t{%1, %0|%0, %1}";
2399 }
2400 }
2401 [(set (attr "type")
2402 (cond [(and (eq_attr "alternative" "5")
2403 (not (match_operand:QI 1 "aligned_operand")))
2404 (const_string "imovx")
2405 (match_test "optimize_function_for_size_p (cfun)")
2406 (const_string "imov")
2407 (and (eq_attr "alternative" "3")
2408 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2409 (not (match_test "TARGET_QIMODE_MATH"))))
2410 (const_string "imov")
2411 (eq_attr "alternative" "3,5")
2412 (const_string "imovx")
2413 (and (match_test "TARGET_MOVX")
2414 (eq_attr "alternative" "2"))
2415 (const_string "imovx")
2416 ]
2417 (const_string "imov")))
2418 (set (attr "mode")
2419 (cond [(eq_attr "alternative" "3,4,5")
2420 (const_string "SI")
2421 (eq_attr "alternative" "6")
2422 (const_string "QI")
2423 (eq_attr "type" "imovx")
2424 (const_string "SI")
2425 (and (eq_attr "type" "imov")
2426 (and (eq_attr "alternative" "0,1")
2427 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2428 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2429 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2430 (const_string "SI")
2431 ;; Avoid partial register stalls when not using QImode arithmetic
2432 (and (eq_attr "type" "imov")
2433 (and (eq_attr "alternative" "0,1")
2434 (and (match_test "TARGET_PARTIAL_REG_STALL")
2435 (not (match_test "TARGET_QIMODE_MATH")))))
2436 (const_string "SI")
2437 ]
2438 (const_string "QI")))])
2439
2440 ;; Stores and loads of ax to arbitrary constant address.
2441 ;; We fake an second form of instruction to force reload to load address
2442 ;; into register when rax is not available
2443 (define_insn "*movabs<mode>_1"
2444 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2445 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2446 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2447 "@
2448 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2449 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2450 [(set_attr "type" "imov")
2451 (set_attr "modrm" "0,*")
2452 (set_attr "length_address" "8,0")
2453 (set_attr "length_immediate" "0,*")
2454 (set_attr "memory" "store")
2455 (set_attr "mode" "<MODE>")])
2456
2457 (define_insn "*movabs<mode>_2"
2458 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2459 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2460 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2461 "@
2462 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2463 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2464 [(set_attr "type" "imov")
2465 (set_attr "modrm" "0,*")
2466 (set_attr "length_address" "8,0")
2467 (set_attr "length_immediate" "0")
2468 (set_attr "memory" "load")
2469 (set_attr "mode" "<MODE>")])
2470
2471 (define_insn "swap<mode>"
2472 [(set (match_operand:SWI48 0 "register_operand" "+r")
2473 (match_operand:SWI48 1 "register_operand" "+r"))
2474 (set (match_dup 1)
2475 (match_dup 0))]
2476 ""
2477 "xchg{<imodesuffix>}\t%1, %0"
2478 [(set_attr "type" "imov")
2479 (set_attr "mode" "<MODE>")
2480 (set_attr "pent_pair" "np")
2481 (set_attr "athlon_decode" "vector")
2482 (set_attr "amdfam10_decode" "double")
2483 (set_attr "bdver1_decode" "double")])
2484
2485 (define_insn "*swap<mode>_1"
2486 [(set (match_operand:SWI12 0 "register_operand" "+r")
2487 (match_operand:SWI12 1 "register_operand" "+r"))
2488 (set (match_dup 1)
2489 (match_dup 0))]
2490 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2491 "xchg{l}\t%k1, %k0"
2492 [(set_attr "type" "imov")
2493 (set_attr "mode" "SI")
2494 (set_attr "pent_pair" "np")
2495 (set_attr "athlon_decode" "vector")
2496 (set_attr "amdfam10_decode" "double")
2497 (set_attr "bdver1_decode" "double")])
2498
2499 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2500 ;; is disabled for AMDFAM10
2501 (define_insn "*swap<mode>_2"
2502 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2503 (match_operand:SWI12 1 "register_operand" "+<r>"))
2504 (set (match_dup 1)
2505 (match_dup 0))]
2506 "TARGET_PARTIAL_REG_STALL"
2507 "xchg{<imodesuffix>}\t%1, %0"
2508 [(set_attr "type" "imov")
2509 (set_attr "mode" "<MODE>")
2510 (set_attr "pent_pair" "np")
2511 (set_attr "athlon_decode" "vector")])
2512
2513 (define_expand "movstrict<mode>"
2514 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2515 (match_operand:SWI12 1 "general_operand"))]
2516 ""
2517 {
2518 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2519 FAIL;
2520 if (GET_CODE (operands[0]) == SUBREG
2521 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2522 FAIL;
2523 /* Don't generate memory->memory moves, go through a register */
2524 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2525 operands[1] = force_reg (<MODE>mode, operands[1]);
2526 })
2527
2528 (define_insn "*movstrict<mode>_1"
2529 [(set (strict_low_part
2530 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2531 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2532 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2533 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2534 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2535 [(set_attr "type" "imov")
2536 (set_attr "mode" "<MODE>")])
2537
2538 (define_insn "*movstrict<mode>_xor"
2539 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2540 (match_operand:SWI12 1 "const0_operand"))
2541 (clobber (reg:CC FLAGS_REG))]
2542 "reload_completed"
2543 "xor{<imodesuffix>}\t%0, %0"
2544 [(set_attr "type" "alu1")
2545 (set_attr "mode" "<MODE>")
2546 (set_attr "length_immediate" "0")])
2547
2548 (define_insn "*mov<mode>_extv_1"
2549 [(set (match_operand:SWI24 0 "register_operand" "=R")
2550 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2551 (const_int 8)
2552 (const_int 8)))]
2553 ""
2554 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2555 [(set_attr "type" "imovx")
2556 (set_attr "mode" "SI")])
2557
2558 (define_insn "*movqi_extv_1_rex64"
2559 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2560 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2561 (const_int 8)
2562 (const_int 8)))]
2563 "TARGET_64BIT"
2564 {
2565 switch (get_attr_type (insn))
2566 {
2567 case TYPE_IMOVX:
2568 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2569 default:
2570 return "mov{b}\t{%h1, %0|%0, %h1}";
2571 }
2572 }
2573 [(set (attr "type")
2574 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2575 (match_test "TARGET_MOVX"))
2576 (const_string "imovx")
2577 (const_string "imov")))
2578 (set (attr "mode")
2579 (if_then_else (eq_attr "type" "imovx")
2580 (const_string "SI")
2581 (const_string "QI")))])
2582
2583 (define_insn "*movqi_extv_1"
2584 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2585 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2586 (const_int 8)
2587 (const_int 8)))]
2588 "!TARGET_64BIT"
2589 {
2590 switch (get_attr_type (insn))
2591 {
2592 case TYPE_IMOVX:
2593 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2594 default:
2595 return "mov{b}\t{%h1, %0|%0, %h1}";
2596 }
2597 }
2598 [(set (attr "type")
2599 (if_then_else (and (match_operand:QI 0 "register_operand")
2600 (ior (not (match_operand:QI 0 "QIreg_operand"))
2601 (match_test "TARGET_MOVX")))
2602 (const_string "imovx")
2603 (const_string "imov")))
2604 (set (attr "mode")
2605 (if_then_else (eq_attr "type" "imovx")
2606 (const_string "SI")
2607 (const_string "QI")))])
2608
2609 (define_insn "*mov<mode>_extzv_1"
2610 [(set (match_operand:SWI48 0 "register_operand" "=R")
2611 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2612 (const_int 8)
2613 (const_int 8)))]
2614 ""
2615 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2616 [(set_attr "type" "imovx")
2617 (set_attr "mode" "SI")])
2618
2619 (define_insn "*movqi_extzv_2_rex64"
2620 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2621 (subreg:QI
2622 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2623 (const_int 8)
2624 (const_int 8)) 0))]
2625 "TARGET_64BIT"
2626 {
2627 switch (get_attr_type (insn))
2628 {
2629 case TYPE_IMOVX:
2630 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2631 default:
2632 return "mov{b}\t{%h1, %0|%0, %h1}";
2633 }
2634 }
2635 [(set (attr "type")
2636 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2637 (match_test "TARGET_MOVX"))
2638 (const_string "imovx")
2639 (const_string "imov")))
2640 (set (attr "mode")
2641 (if_then_else (eq_attr "type" "imovx")
2642 (const_string "SI")
2643 (const_string "QI")))])
2644
2645 (define_insn "*movqi_extzv_2"
2646 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2647 (subreg:QI
2648 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2649 (const_int 8)
2650 (const_int 8)) 0))]
2651 "!TARGET_64BIT"
2652 {
2653 switch (get_attr_type (insn))
2654 {
2655 case TYPE_IMOVX:
2656 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2657 default:
2658 return "mov{b}\t{%h1, %0|%0, %h1}";
2659 }
2660 }
2661 [(set (attr "type")
2662 (if_then_else (and (match_operand:QI 0 "register_operand")
2663 (ior (not (match_operand:QI 0 "QIreg_operand"))
2664 (match_test "TARGET_MOVX")))
2665 (const_string "imovx")
2666 (const_string "imov")))
2667 (set (attr "mode")
2668 (if_then_else (eq_attr "type" "imovx")
2669 (const_string "SI")
2670 (const_string "QI")))])
2671
2672 (define_expand "mov<mode>_insv_1"
2673 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2674 (const_int 8)
2675 (const_int 8))
2676 (match_operand:SWI48 1 "nonmemory_operand"))])
2677
2678 (define_insn "*mov<mode>_insv_1_rex64"
2679 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2680 (const_int 8)
2681 (const_int 8))
2682 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2683 "TARGET_64BIT"
2684 "mov{b}\t{%b1, %h0|%h0, %b1}"
2685 [(set_attr "type" "imov")
2686 (set_attr "mode" "QI")])
2687
2688 (define_insn "*movsi_insv_1"
2689 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2690 (const_int 8)
2691 (const_int 8))
2692 (match_operand:SI 1 "general_operand" "Qmn"))]
2693 "!TARGET_64BIT"
2694 "mov{b}\t{%b1, %h0|%h0, %b1}"
2695 [(set_attr "type" "imov")
2696 (set_attr "mode" "QI")])
2697
2698 (define_insn "*movqi_insv_2"
2699 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2700 (const_int 8)
2701 (const_int 8))
2702 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2703 (const_int 8)))]
2704 ""
2705 "mov{b}\t{%h1, %h0|%h0, %h1}"
2706 [(set_attr "type" "imov")
2707 (set_attr "mode" "QI")])
2708 \f
2709 ;; Floating point push instructions.
2710
2711 (define_insn "*pushtf"
2712 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2713 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2714 "TARGET_SSE"
2715 {
2716 /* This insn should be already split before reg-stack. */
2717 gcc_unreachable ();
2718 }
2719 [(set_attr "type" "multi")
2720 (set_attr "unit" "sse,*,*")
2721 (set_attr "mode" "TF,SI,SI")])
2722
2723 ;; %%% Kill this when call knows how to work this out.
2724 (define_split
2725 [(set (match_operand:TF 0 "push_operand")
2726 (match_operand:TF 1 "sse_reg_operand"))]
2727 "TARGET_SSE && reload_completed"
2728 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2729 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2730
2731 (define_insn "*pushxf"
2732 [(set (match_operand:XF 0 "push_operand" "=<,<")
2733 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2734 "optimize_function_for_speed_p (cfun)"
2735 {
2736 /* This insn should be already split before reg-stack. */
2737 gcc_unreachable ();
2738 }
2739 [(set_attr "type" "multi")
2740 (set_attr "unit" "i387,*")
2741 (set_attr "mode" "XF,SI")])
2742
2743 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2744 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2745 ;; Pushing using integer instructions is longer except for constants
2746 ;; and direct memory references (assuming that any given constant is pushed
2747 ;; only once, but this ought to be handled elsewhere).
2748
2749 (define_insn "*pushxf_nointeger"
2750 [(set (match_operand:XF 0 "push_operand" "=<,<")
2751 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2752 "optimize_function_for_size_p (cfun)"
2753 {
2754 /* This insn should be already split before reg-stack. */
2755 gcc_unreachable ();
2756 }
2757 [(set_attr "type" "multi")
2758 (set_attr "unit" "i387,*")
2759 (set_attr "mode" "XF,SI")])
2760
2761 ;; %%% Kill this when call knows how to work this out.
2762 (define_split
2763 [(set (match_operand:XF 0 "push_operand")
2764 (match_operand:XF 1 "fp_register_operand"))]
2765 "reload_completed"
2766 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2767 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2768 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2769
2770 (define_insn "*pushdf_rex64"
2771 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2772 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2773 "TARGET_64BIT"
2774 {
2775 /* This insn should be already split before reg-stack. */
2776 gcc_unreachable ();
2777 }
2778 [(set_attr "type" "multi")
2779 (set_attr "unit" "i387,*,*")
2780 (set_attr "mode" "DF,DI,DF")])
2781
2782 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2783 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2784 ;; On the average, pushdf using integers can be still shorter.
2785
2786 (define_insn "*pushdf"
2787 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2788 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2789 "!TARGET_64BIT"
2790 {
2791 /* This insn should be already split before reg-stack. */
2792 gcc_unreachable ();
2793 }
2794 [(set_attr "isa" "*,*,sse2")
2795 (set_attr "type" "multi")
2796 (set_attr "unit" "i387,*,*")
2797 (set_attr "mode" "DF,DI,DF")])
2798
2799 ;; %%% Kill this when call knows how to work this out.
2800 (define_split
2801 [(set (match_operand:DF 0 "push_operand")
2802 (match_operand:DF 1 "any_fp_register_operand"))]
2803 "reload_completed"
2804 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2805 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2806
2807 (define_insn "*pushsf_rex64"
2808 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2809 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2810 "TARGET_64BIT"
2811 {
2812 /* Anything else should be already split before reg-stack. */
2813 gcc_assert (which_alternative == 1);
2814 return "push{q}\t%q1";
2815 }
2816 [(set_attr "type" "multi,push,multi")
2817 (set_attr "unit" "i387,*,*")
2818 (set_attr "mode" "SF,DI,SF")])
2819
2820 (define_insn "*pushsf"
2821 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2822 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2823 "!TARGET_64BIT"
2824 {
2825 /* Anything else should be already split before reg-stack. */
2826 gcc_assert (which_alternative == 1);
2827 return "push{l}\t%1";
2828 }
2829 [(set_attr "type" "multi,push,multi")
2830 (set_attr "unit" "i387,*,*")
2831 (set_attr "mode" "SF,SI,SF")])
2832
2833 ;; %%% Kill this when call knows how to work this out.
2834 (define_split
2835 [(set (match_operand:SF 0 "push_operand")
2836 (match_operand:SF 1 "any_fp_register_operand"))]
2837 "reload_completed"
2838 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2839 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2840 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2841
2842 (define_split
2843 [(set (match_operand:SF 0 "push_operand")
2844 (match_operand:SF 1 "memory_operand"))]
2845 "reload_completed
2846 && (operands[2] = find_constant_src (insn))"
2847 [(set (match_dup 0) (match_dup 2))])
2848
2849 (define_split
2850 [(set (match_operand 0 "push_operand")
2851 (match_operand 1 "general_operand"))]
2852 "reload_completed
2853 && (GET_MODE (operands[0]) == TFmode
2854 || GET_MODE (operands[0]) == XFmode
2855 || GET_MODE (operands[0]) == DFmode)
2856 && !ANY_FP_REG_P (operands[1])"
2857 [(const_int 0)]
2858 "ix86_split_long_move (operands); DONE;")
2859 \f
2860 ;; Floating point move instructions.
2861
2862 (define_expand "movtf"
2863 [(set (match_operand:TF 0 "nonimmediate_operand")
2864 (match_operand:TF 1 "nonimmediate_operand"))]
2865 "TARGET_SSE"
2866 {
2867 ix86_expand_move (TFmode, operands);
2868 DONE;
2869 })
2870
2871 (define_expand "mov<mode>"
2872 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2873 (match_operand:X87MODEF 1 "general_operand"))]
2874 ""
2875 "ix86_expand_move (<MODE>mode, operands); DONE;")
2876
2877 (define_insn "*movtf_internal"
2878 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2879 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,F*r"))]
2880 "TARGET_SSE
2881 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2882 && (!can_create_pseudo_p ()
2883 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2884 || GET_CODE (operands[1]) != CONST_DOUBLE
2885 || (optimize_function_for_size_p (cfun)
2886 && standard_sse_constant_p (operands[1])
2887 && !memory_operand (operands[0], TFmode))
2888 || (!TARGET_MEMORY_MISMATCH_STALL
2889 && memory_operand (operands[0], TFmode)))"
2890 {
2891 switch (which_alternative)
2892 {
2893 case 0:
2894 return standard_sse_constant_opcode (insn, operands[1]);
2895 case 1:
2896 case 2:
2897 /* Handle misaligned load/store since we
2898 don't have movmisaligntf pattern. */
2899 if (misaligned_operand (operands[0], TFmode)
2900 || misaligned_operand (operands[1], TFmode))
2901 {
2902 if (get_attr_mode (insn) == MODE_V4SF)
2903 return "%vmovups\t{%1, %0|%0, %1}";
2904 else
2905 return "%vmovdqu\t{%1, %0|%0, %1}";
2906 }
2907 else
2908 {
2909 if (get_attr_mode (insn) == MODE_V4SF)
2910 return "%vmovaps\t{%1, %0|%0, %1}";
2911 else
2912 return "%vmovdqa\t{%1, %0|%0, %1}";
2913 }
2914
2915 case 3:
2916 case 4:
2917 return "#";
2918
2919 default:
2920 gcc_unreachable ();
2921 }
2922 }
2923 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2924 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2925 (set (attr "mode")
2926 (cond [(eq_attr "alternative" "3,4")
2927 (const_string "DI")
2928 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2929 (const_string "V4SF")
2930 (and (eq_attr "alternative" "2")
2931 (match_test "TARGET_SSE_TYPELESS_STORES"))
2932 (const_string "V4SF")
2933 (match_test "TARGET_AVX")
2934 (const_string "TI")
2935 (ior (not (match_test "TARGET_SSE2"))
2936 (match_test "optimize_function_for_size_p (cfun)"))
2937 (const_string "V4SF")
2938 ]
2939 (const_string "TI")))])
2940
2941 ;; Possible store forwarding (partial memory) stall in alternative 4.
2942 (define_insn "*movxf_internal"
2943 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2944 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2945 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2946 && (!can_create_pseudo_p ()
2947 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2948 || GET_CODE (operands[1]) != CONST_DOUBLE
2949 || (optimize_function_for_size_p (cfun)
2950 && standard_80387_constant_p (operands[1]) > 0
2951 && !memory_operand (operands[0], XFmode))
2952 || (!TARGET_MEMORY_MISMATCH_STALL
2953 && memory_operand (operands[0], XFmode)))"
2954 {
2955 switch (which_alternative)
2956 {
2957 case 0:
2958 case 1:
2959 return output_387_reg_move (insn, operands);
2960
2961 case 2:
2962 return standard_80387_constant_opcode (operands[1]);
2963
2964 case 3:
2965 case 4:
2966 return "#";
2967
2968 default:
2969 gcc_unreachable ();
2970 }
2971 }
2972 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2973 (set_attr "mode" "XF,XF,XF,SI,SI")])
2974
2975 (define_insn "*movdf_internal_rex64"
2976 [(set (match_operand:DF 0 "nonimmediate_operand"
2977 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2978 (match_operand:DF 1 "general_operand"
2979 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2980 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2981 && (!can_create_pseudo_p ()
2982 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2983 || GET_CODE (operands[1]) != CONST_DOUBLE
2984 || (optimize_function_for_size_p (cfun)
2985 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2986 && standard_80387_constant_p (operands[1]) > 0)
2987 || (TARGET_SSE2 && TARGET_SSE_MATH
2988 && standard_sse_constant_p (operands[1]))))
2989 || memory_operand (operands[0], DFmode))"
2990 {
2991 switch (which_alternative)
2992 {
2993 case 0:
2994 case 1:
2995 return output_387_reg_move (insn, operands);
2996
2997 case 2:
2998 return standard_80387_constant_opcode (operands[1]);
2999
3000 case 3:
3001 case 4:
3002 return "mov{q}\t{%1, %0|%0, %1}";
3003
3004 case 5:
3005 return "movabs{q}\t{%1, %0|%0, %1}";
3006
3007 case 6:
3008 return "#";
3009
3010 case 7:
3011 return standard_sse_constant_opcode (insn, operands[1]);
3012
3013 case 8:
3014 case 9:
3015 case 10:
3016 switch (get_attr_mode (insn))
3017 {
3018 case MODE_V2DF:
3019 return "%vmovapd\t{%1, %0|%0, %1}";
3020 case MODE_V4SF:
3021 return "%vmovaps\t{%1, %0|%0, %1}";
3022
3023 case MODE_DI:
3024 return "%vmovq\t{%1, %0|%0, %1}";
3025 case MODE_DF:
3026 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3027 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3028 return "%vmovsd\t{%1, %0|%0, %1}";
3029 case MODE_V1DF:
3030 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3031 case MODE_V2SF:
3032 return "%vmovlps\t{%1, %d0|%d0, %1}";
3033 default:
3034 gcc_unreachable ();
3035 }
3036
3037 case 11:
3038 case 12:
3039 /* Handle broken assemblers that require movd instead of movq. */
3040 return "%vmovd\t{%1, %0|%0, %1}";
3041
3042 default:
3043 gcc_unreachable();
3044 }
3045 }
3046 [(set (attr "type")
3047 (cond [(eq_attr "alternative" "0,1,2")
3048 (const_string "fmov")
3049 (eq_attr "alternative" "3,4,5")
3050 (const_string "imov")
3051 (eq_attr "alternative" "6")
3052 (const_string "multi")
3053 (eq_attr "alternative" "7")
3054 (const_string "sselog1")
3055 ]
3056 (const_string "ssemov")))
3057 (set (attr "modrm")
3058 (if_then_else
3059 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3060 (const_string "0")
3061 (const_string "*")))
3062 (set (attr "length_immediate")
3063 (if_then_else
3064 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3065 (const_string "8")
3066 (const_string "*")))
3067 (set (attr "prefix")
3068 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3069 (const_string "orig")
3070 (const_string "maybe_vex")))
3071 (set (attr "prefix_data16")
3072 (if_then_else (eq_attr "mode" "V1DF")
3073 (const_string "1")
3074 (const_string "*")))
3075 (set (attr "mode")
3076 (cond [(eq_attr "alternative" "0,1,2")
3077 (const_string "DF")
3078 (eq_attr "alternative" "3,4,5,6,11,12")
3079 (const_string "DI")
3080
3081 /* xorps is one byte shorter for !TARGET_AVX. */
3082 (eq_attr "alternative" "7")
3083 (cond [(match_test "TARGET_AVX")
3084 (const_string "V2DF")
3085 (match_test "optimize_function_for_size_p (cfun)")
3086 (const_string "V4SF")
3087 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3088 (const_string "TI")
3089 ]
3090 (const_string "V2DF"))
3091
3092 /* For architectures resolving dependencies on
3093 whole SSE registers use APD move to break dependency
3094 chains, otherwise use short move to avoid extra work.
3095
3096 movaps encodes one byte shorter for !TARGET_AVX. */
3097 (eq_attr "alternative" "8")
3098 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3099 (const_string "V4SF")
3100 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3101 (const_string "V2DF")
3102 (match_test "TARGET_AVX")
3103 (const_string "DF")
3104 (match_test "optimize_function_for_size_p (cfun)")
3105 (const_string "V4SF")
3106 ]
3107 (const_string "DF"))
3108 /* For architectures resolving dependencies on register
3109 parts we may avoid extra work to zero out upper part
3110 of register. */
3111 (eq_attr "alternative" "9")
3112 (if_then_else
3113 (match_test "TARGET_SSE_SPLIT_REGS")
3114 (const_string "V1DF")
3115 (const_string "DF"))
3116 ]
3117 (const_string "DF")))])
3118
3119 ;; Possible store forwarding (partial memory) stall in alternative 4.
3120 (define_insn "*movdf_internal"
3121 [(set (match_operand:DF 0 "nonimmediate_operand"
3122 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3123 (match_operand:DF 1 "general_operand"
3124 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3125 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3126 && (!can_create_pseudo_p ()
3127 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3128 || GET_CODE (operands[1]) != CONST_DOUBLE
3129 || (optimize_function_for_size_p (cfun)
3130 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3131 && standard_80387_constant_p (operands[1]) > 0)
3132 || (TARGET_SSE2 && TARGET_SSE_MATH
3133 && standard_sse_constant_p (operands[1])))
3134 && !memory_operand (operands[0], DFmode))
3135 || (!TARGET_MEMORY_MISMATCH_STALL
3136 && memory_operand (operands[0], DFmode)))"
3137 {
3138 switch (which_alternative)
3139 {
3140 case 0:
3141 case 1:
3142 return output_387_reg_move (insn, operands);
3143
3144 case 2:
3145 return standard_80387_constant_opcode (operands[1]);
3146
3147 case 3:
3148 case 4:
3149 return "#";
3150
3151 case 5:
3152 case 9:
3153 return standard_sse_constant_opcode (insn, operands[1]);
3154
3155 case 6:
3156 case 7:
3157 case 8:
3158 case 10:
3159 case 11:
3160 case 12:
3161 switch (get_attr_mode (insn))
3162 {
3163 case MODE_V2DF:
3164 return "%vmovapd\t{%1, %0|%0, %1}";
3165 case MODE_V4SF:
3166 return "%vmovaps\t{%1, %0|%0, %1}";
3167
3168 case MODE_DI:
3169 return "%vmovq\t{%1, %0|%0, %1}";
3170 case MODE_DF:
3171 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3172 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3173 return "%vmovsd\t{%1, %0|%0, %1}";
3174 case MODE_V1DF:
3175 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3176 case MODE_V2SF:
3177 return "%vmovlps\t{%1, %d0|%d0, %1}";
3178 default:
3179 gcc_unreachable ();
3180 }
3181
3182 default:
3183 gcc_unreachable ();
3184 }
3185 }
3186 [(set (attr "isa")
3187 (if_then_else (eq_attr "alternative" "5,6,7,8")
3188 (const_string "sse2")
3189 (const_string "*")))
3190 (set (attr "type")
3191 (cond [(eq_attr "alternative" "0,1,2")
3192 (const_string "fmov")
3193 (eq_attr "alternative" "3,4")
3194 (const_string "multi")
3195 (eq_attr "alternative" "5,9")
3196 (const_string "sselog1")
3197 ]
3198 (const_string "ssemov")))
3199 (set (attr "prefix")
3200 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3201 (const_string "orig")
3202 (const_string "maybe_vex")))
3203 (set (attr "prefix_data16")
3204 (if_then_else (eq_attr "mode" "V1DF")
3205 (const_string "1")
3206 (const_string "*")))
3207 (set (attr "mode")
3208 (cond [(eq_attr "alternative" "0,1,2")
3209 (const_string "DF")
3210 (eq_attr "alternative" "3,4")
3211 (const_string "SI")
3212
3213 /* For SSE1, we have many fewer alternatives. */
3214 (not (match_test "TARGET_SSE2"))
3215 (if_then_else
3216 (eq_attr "alternative" "5,6,9,10")
3217 (const_string "V4SF")
3218 (const_string "V2SF"))
3219
3220 /* xorps is one byte shorter for !TARGET_AVX. */
3221 (eq_attr "alternative" "5,9")
3222 (cond [(match_test "TARGET_AVX")
3223 (const_string "V2DF")
3224 (match_test "optimize_function_for_size_p (cfun)")
3225 (const_string "V4SF")
3226 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3227 (const_string "TI")
3228 ]
3229 (const_string "V2DF"))
3230
3231 /* For architectures resolving dependencies on
3232 whole SSE registers use APD move to break dependency
3233 chains, otherwise use short move to avoid extra work.
3234
3235 movaps encodes one byte shorter for !TARGET_AVX. */
3236 (eq_attr "alternative" "6,10")
3237 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3238 (const_string "V4SF")
3239 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3240 (const_string "V2DF")
3241 (match_test "TARGET_AVX")
3242 (const_string "DF")
3243 (match_test "optimize_function_for_size_p (cfun)")
3244 (const_string "V4SF")
3245 ]
3246 (const_string "DF"))
3247
3248 /* For architectures resolving dependencies on register
3249 parts we may avoid extra work to zero out upper part
3250 of register. */
3251 (eq_attr "alternative" "7,11")
3252 (if_then_else
3253 (match_test "TARGET_SSE_SPLIT_REGS")
3254 (const_string "V1DF")
3255 (const_string "DF"))
3256 ]
3257 (const_string "DF")))])
3258
3259 (define_insn "*movsf_internal"
3260 [(set (match_operand:SF 0 "nonimmediate_operand"
3261 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3262 (match_operand:SF 1 "general_operand"
3263 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3264 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3265 && (!can_create_pseudo_p ()
3266 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3267 || GET_CODE (operands[1]) != CONST_DOUBLE
3268 || (optimize_function_for_size_p (cfun)
3269 && ((!TARGET_SSE_MATH
3270 && standard_80387_constant_p (operands[1]) > 0)
3271 || (TARGET_SSE_MATH
3272 && standard_sse_constant_p (operands[1]))))
3273 || memory_operand (operands[0], SFmode))"
3274 {
3275 switch (which_alternative)
3276 {
3277 case 0:
3278 case 1:
3279 return output_387_reg_move (insn, operands);
3280
3281 case 2:
3282 return standard_80387_constant_opcode (operands[1]);
3283
3284 case 3:
3285 case 4:
3286 return "mov{l}\t{%1, %0|%0, %1}";
3287
3288 case 5:
3289 return standard_sse_constant_opcode (insn, operands[1]);
3290
3291 case 6:
3292 if (get_attr_mode (insn) == MODE_V4SF)
3293 return "%vmovaps\t{%1, %0|%0, %1}";
3294 if (TARGET_AVX)
3295 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3296
3297 case 7:
3298 case 8:
3299 return "%vmovss\t{%1, %0|%0, %1}";
3300
3301 case 9:
3302 case 10:
3303 case 14:
3304 case 15:
3305 return "movd\t{%1, %0|%0, %1}";
3306
3307 case 11:
3308 return "movq\t{%1, %0|%0, %1}";
3309
3310 case 12:
3311 case 13:
3312 return "%vmovd\t{%1, %0|%0, %1}";
3313
3314 default:
3315 gcc_unreachable ();
3316 }
3317 }
3318 [(set (attr "type")
3319 (cond [(eq_attr "alternative" "0,1,2")
3320 (const_string "fmov")
3321 (eq_attr "alternative" "3,4")
3322 (const_string "multi")
3323 (eq_attr "alternative" "5")
3324 (const_string "sselog1")
3325 (eq_attr "alternative" "9,10,11,14,15")
3326 (const_string "mmxmov")
3327 ]
3328 (const_string "ssemov")))
3329 (set (attr "prefix")
3330 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3331 (const_string "maybe_vex")
3332 (const_string "orig")))
3333 (set (attr "mode")
3334 (cond [(eq_attr "alternative" "3,4,9,10")
3335 (const_string "SI")
3336 (eq_attr "alternative" "5")
3337 (cond [(match_test "TARGET_AVX")
3338 (const_string "V4SF")
3339 (ior (not (match_test "TARGET_SSE2"))
3340 (match_test "optimize_function_for_size_p (cfun)"))
3341 (const_string "V4SF")
3342 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3343 (const_string "TI")
3344 ]
3345 (const_string "V4SF"))
3346
3347 /* For architectures resolving dependencies on
3348 whole SSE registers use APS move to break dependency
3349 chains, otherwise use short move to avoid extra work.
3350
3351 Do the same for architectures resolving dependencies on
3352 the parts. While in DF mode it is better to always handle
3353 just register parts, the SF mode is different due to lack
3354 of instructions to load just part of the register. It is
3355 better to maintain the whole registers in single format
3356 to avoid problems on using packed logical operations. */
3357 (eq_attr "alternative" "6")
3358 (if_then_else
3359 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3360 (match_test "TARGET_SSE_SPLIT_REGS"))
3361 (const_string "V4SF")
3362 (const_string "SF"))
3363 (eq_attr "alternative" "11")
3364 (const_string "DI")]
3365 (const_string "SF")))])
3366
3367 (define_split
3368 [(set (match_operand 0 "any_fp_register_operand")
3369 (match_operand 1 "memory_operand"))]
3370 "reload_completed
3371 && (GET_MODE (operands[0]) == TFmode
3372 || GET_MODE (operands[0]) == XFmode
3373 || GET_MODE (operands[0]) == DFmode
3374 || GET_MODE (operands[0]) == SFmode)
3375 && (operands[2] = find_constant_src (insn))"
3376 [(set (match_dup 0) (match_dup 2))]
3377 {
3378 rtx c = operands[2];
3379 int r = REGNO (operands[0]);
3380
3381 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3382 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3383 FAIL;
3384 })
3385
3386 (define_split
3387 [(set (match_operand 0 "any_fp_register_operand")
3388 (float_extend (match_operand 1 "memory_operand")))]
3389 "reload_completed
3390 && (GET_MODE (operands[0]) == TFmode
3391 || GET_MODE (operands[0]) == XFmode
3392 || GET_MODE (operands[0]) == DFmode)
3393 && (operands[2] = find_constant_src (insn))"
3394 [(set (match_dup 0) (match_dup 2))]
3395 {
3396 rtx c = operands[2];
3397 int r = REGNO (operands[0]);
3398
3399 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3400 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3401 FAIL;
3402 })
3403
3404 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3405 (define_split
3406 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3407 (match_operand:X87MODEF 1 "immediate_operand"))]
3408 "reload_completed
3409 && (standard_80387_constant_p (operands[1]) == 8
3410 || standard_80387_constant_p (operands[1]) == 9)"
3411 [(set (match_dup 0)(match_dup 1))
3412 (set (match_dup 0)
3413 (neg:X87MODEF (match_dup 0)))]
3414 {
3415 REAL_VALUE_TYPE r;
3416
3417 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3418 if (real_isnegzero (&r))
3419 operands[1] = CONST0_RTX (<MODE>mode);
3420 else
3421 operands[1] = CONST1_RTX (<MODE>mode);
3422 })
3423
3424 (define_split
3425 [(set (match_operand 0 "nonimmediate_operand")
3426 (match_operand 1 "general_operand"))]
3427 "reload_completed
3428 && (GET_MODE (operands[0]) == TFmode
3429 || GET_MODE (operands[0]) == XFmode
3430 || GET_MODE (operands[0]) == DFmode)
3431 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3432 [(const_int 0)]
3433 "ix86_split_long_move (operands); DONE;")
3434
3435 (define_insn "swapxf"
3436 [(set (match_operand:XF 0 "register_operand" "+f")
3437 (match_operand:XF 1 "register_operand" "+f"))
3438 (set (match_dup 1)
3439 (match_dup 0))]
3440 "TARGET_80387"
3441 {
3442 if (STACK_TOP_P (operands[0]))
3443 return "fxch\t%1";
3444 else
3445 return "fxch\t%0";
3446 }
3447 [(set_attr "type" "fxch")
3448 (set_attr "mode" "XF")])
3449
3450 (define_insn "*swap<mode>"
3451 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3452 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3453 (set (match_dup 1)
3454 (match_dup 0))]
3455 "TARGET_80387 || reload_completed"
3456 {
3457 if (STACK_TOP_P (operands[0]))
3458 return "fxch\t%1";
3459 else
3460 return "fxch\t%0";
3461 }
3462 [(set_attr "type" "fxch")
3463 (set_attr "mode" "<MODE>")])
3464 \f
3465 ;; Zero extension instructions
3466
3467 (define_expand "zero_extendsidi2"
3468 [(set (match_operand:DI 0 "nonimmediate_operand")
3469 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3470
3471 (define_insn "*zero_extendsidi2_rex64"
3472 [(set (match_operand:DI 0 "nonimmediate_operand"
3473 "=r ,o,?*Ym,?*y,?*Yi,?*x")
3474 (zero_extend:DI
3475 (match_operand:SI 1 "x86_64_zext_general_operand"
3476 "rmWz,0,r ,m ,r ,m")))]
3477 "TARGET_64BIT"
3478 "@
3479 mov{l}\t{%1, %k0|%k0, %1}
3480 #
3481 movd\t{%1, %0|%0, %1}
3482 movd\t{%1, %0|%0, %1}
3483 %vmovd\t{%1, %0|%0, %1}
3484 %vmovd\t{%1, %0|%0, %1}"
3485 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3486 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3487 (set_attr "prefix_0f" "0,*,*,*,*,*")
3488 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3489
3490 (define_insn "*zero_extendsidi2"
3491 [(set (match_operand:DI 0 "nonimmediate_operand"
3492 "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3493 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3494 "0 ,rm,r ,r ,m ,r ,m")))]
3495 "!TARGET_64BIT"
3496 "@
3497 #
3498 #
3499 #
3500 movd\t{%1, %0|%0, %1}
3501 movd\t{%1, %0|%0, %1}
3502 %vmovd\t{%1, %0|%0, %1}
3503 %vmovd\t{%1, %0|%0, %1}"
3504 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3505 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3506 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3507 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3508
3509 (define_split
3510 [(set (match_operand:DI 0 "memory_operand")
3511 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3512 "reload_completed"
3513 [(set (match_dup 4) (const_int 0))]
3514 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3515
3516 (define_split
3517 [(set (match_operand:DI 0 "register_operand")
3518 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3519 "!TARGET_64BIT && reload_completed
3520 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3521 && true_regnum (operands[0]) == true_regnum (operands[1])"
3522 [(set (match_dup 4) (const_int 0))]
3523 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3524
3525 (define_split
3526 [(set (match_operand:DI 0 "nonimmediate_operand")
3527 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3528 "!TARGET_64BIT && reload_completed
3529 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3530 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3531 [(set (match_dup 3) (match_dup 1))
3532 (set (match_dup 4) (const_int 0))]
3533 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3534
3535 (define_insn "zero_extend<mode>di2"
3536 [(set (match_operand:DI 0 "register_operand" "=r")
3537 (zero_extend:DI
3538 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3539 "TARGET_64BIT"
3540 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3541 [(set_attr "type" "imovx")
3542 (set_attr "mode" "SI")])
3543
3544 (define_expand "zero_extend<mode>si2"
3545 [(set (match_operand:SI 0 "register_operand")
3546 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3547 ""
3548 {
3549 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3550 {
3551 operands[1] = force_reg (<MODE>mode, operands[1]);
3552 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3553 DONE;
3554 }
3555 })
3556
3557 (define_insn_and_split "zero_extend<mode>si2_and"
3558 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3559 (zero_extend:SI
3560 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3561 (clobber (reg:CC FLAGS_REG))]
3562 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3563 "#"
3564 "&& reload_completed"
3565 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3566 (clobber (reg:CC FLAGS_REG))])]
3567 {
3568 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3569 {
3570 ix86_expand_clear (operands[0]);
3571
3572 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3573 emit_insn (gen_movstrict<mode>
3574 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3575 DONE;
3576 }
3577
3578 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3579 }
3580 [(set_attr "type" "alu1")
3581 (set_attr "mode" "SI")])
3582
3583 (define_insn "*zero_extend<mode>si2"
3584 [(set (match_operand:SI 0 "register_operand" "=r")
3585 (zero_extend:SI
3586 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3587 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3588 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3589 [(set_attr "type" "imovx")
3590 (set_attr "mode" "SI")])
3591
3592 (define_expand "zero_extendqihi2"
3593 [(set (match_operand:HI 0 "register_operand")
3594 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3595 ""
3596 {
3597 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3598 {
3599 operands[1] = force_reg (QImode, operands[1]);
3600 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3601 DONE;
3602 }
3603 })
3604
3605 (define_insn_and_split "zero_extendqihi2_and"
3606 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3607 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3608 (clobber (reg:CC FLAGS_REG))]
3609 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3610 "#"
3611 "&& reload_completed"
3612 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3613 (clobber (reg:CC FLAGS_REG))])]
3614 {
3615 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3616 {
3617 ix86_expand_clear (operands[0]);
3618
3619 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3620 emit_insn (gen_movstrictqi
3621 (gen_lowpart (QImode, operands[0]), operands[1]));
3622 DONE;
3623 }
3624
3625 operands[0] = gen_lowpart (SImode, operands[0]);
3626 }
3627 [(set_attr "type" "alu1")
3628 (set_attr "mode" "SI")])
3629
3630 ; zero extend to SImode to avoid partial register stalls
3631 (define_insn "*zero_extendqihi2"
3632 [(set (match_operand:HI 0 "register_operand" "=r")
3633 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3634 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3635 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3636 [(set_attr "type" "imovx")
3637 (set_attr "mode" "SI")])
3638 \f
3639 ;; Sign extension instructions
3640
3641 (define_expand "extendsidi2"
3642 [(set (match_operand:DI 0 "register_operand")
3643 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3644 ""
3645 {
3646 if (!TARGET_64BIT)
3647 {
3648 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3649 DONE;
3650 }
3651 })
3652
3653 (define_insn "*extendsidi2_rex64"
3654 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3655 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3656 "TARGET_64BIT"
3657 "@
3658 {cltq|cdqe}
3659 movs{lq|x}\t{%1, %0|%0, %1}"
3660 [(set_attr "type" "imovx")
3661 (set_attr "mode" "DI")
3662 (set_attr "prefix_0f" "0")
3663 (set_attr "modrm" "0,1")])
3664
3665 (define_insn "extendsidi2_1"
3666 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3667 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3668 (clobber (reg:CC FLAGS_REG))
3669 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3670 "!TARGET_64BIT"
3671 "#")
3672
3673 ;; Extend to memory case when source register does die.
3674 (define_split
3675 [(set (match_operand:DI 0 "memory_operand")
3676 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3677 (clobber (reg:CC FLAGS_REG))
3678 (clobber (match_operand:SI 2 "register_operand"))]
3679 "(reload_completed
3680 && dead_or_set_p (insn, operands[1])
3681 && !reg_mentioned_p (operands[1], operands[0]))"
3682 [(set (match_dup 3) (match_dup 1))
3683 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3684 (clobber (reg:CC FLAGS_REG))])
3685 (set (match_dup 4) (match_dup 1))]
3686 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3687
3688 ;; Extend to memory case when source register does not die.
3689 (define_split
3690 [(set (match_operand:DI 0 "memory_operand")
3691 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3692 (clobber (reg:CC FLAGS_REG))
3693 (clobber (match_operand:SI 2 "register_operand"))]
3694 "reload_completed"
3695 [(const_int 0)]
3696 {
3697 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3698
3699 emit_move_insn (operands[3], operands[1]);
3700
3701 /* Generate a cltd if possible and doing so it profitable. */
3702 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3703 && true_regnum (operands[1]) == AX_REG
3704 && true_regnum (operands[2]) == DX_REG)
3705 {
3706 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3707 }
3708 else
3709 {
3710 emit_move_insn (operands[2], operands[1]);
3711 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3712 }
3713 emit_move_insn (operands[4], operands[2]);
3714 DONE;
3715 })
3716
3717 ;; Extend to register case. Optimize case where source and destination
3718 ;; registers match and cases where we can use cltd.
3719 (define_split
3720 [(set (match_operand:DI 0 "register_operand")
3721 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3722 (clobber (reg:CC FLAGS_REG))
3723 (clobber (match_scratch:SI 2))]
3724 "reload_completed"
3725 [(const_int 0)]
3726 {
3727 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3728
3729 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3730 emit_move_insn (operands[3], operands[1]);
3731
3732 /* Generate a cltd if possible and doing so it profitable. */
3733 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3734 && true_regnum (operands[3]) == AX_REG
3735 && true_regnum (operands[4]) == DX_REG)
3736 {
3737 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3738 DONE;
3739 }
3740
3741 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3742 emit_move_insn (operands[4], operands[1]);
3743
3744 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3745 DONE;
3746 })
3747
3748 (define_insn "extend<mode>di2"
3749 [(set (match_operand:DI 0 "register_operand" "=r")
3750 (sign_extend:DI
3751 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3752 "TARGET_64BIT"
3753 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3754 [(set_attr "type" "imovx")
3755 (set_attr "mode" "DI")])
3756
3757 (define_insn "extendhisi2"
3758 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3759 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3760 ""
3761 {
3762 switch (get_attr_prefix_0f (insn))
3763 {
3764 case 0:
3765 return "{cwtl|cwde}";
3766 default:
3767 return "movs{wl|x}\t{%1, %0|%0, %1}";
3768 }
3769 }
3770 [(set_attr "type" "imovx")
3771 (set_attr "mode" "SI")
3772 (set (attr "prefix_0f")
3773 ;; movsx is short decodable while cwtl is vector decoded.
3774 (if_then_else (and (eq_attr "cpu" "!k6")
3775 (eq_attr "alternative" "0"))
3776 (const_string "0")
3777 (const_string "1")))
3778 (set (attr "modrm")
3779 (if_then_else (eq_attr "prefix_0f" "0")
3780 (const_string "0")
3781 (const_string "1")))])
3782
3783 (define_insn "*extendhisi2_zext"
3784 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3785 (zero_extend:DI
3786 (sign_extend:SI
3787 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3788 "TARGET_64BIT"
3789 {
3790 switch (get_attr_prefix_0f (insn))
3791 {
3792 case 0:
3793 return "{cwtl|cwde}";
3794 default:
3795 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3796 }
3797 }
3798 [(set_attr "type" "imovx")
3799 (set_attr "mode" "SI")
3800 (set (attr "prefix_0f")
3801 ;; movsx is short decodable while cwtl is vector decoded.
3802 (if_then_else (and (eq_attr "cpu" "!k6")
3803 (eq_attr "alternative" "0"))
3804 (const_string "0")
3805 (const_string "1")))
3806 (set (attr "modrm")
3807 (if_then_else (eq_attr "prefix_0f" "0")
3808 (const_string "0")
3809 (const_string "1")))])
3810
3811 (define_insn "extendqisi2"
3812 [(set (match_operand:SI 0 "register_operand" "=r")
3813 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3814 ""
3815 "movs{bl|x}\t{%1, %0|%0, %1}"
3816 [(set_attr "type" "imovx")
3817 (set_attr "mode" "SI")])
3818
3819 (define_insn "*extendqisi2_zext"
3820 [(set (match_operand:DI 0 "register_operand" "=r")
3821 (zero_extend:DI
3822 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3823 "TARGET_64BIT"
3824 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3825 [(set_attr "type" "imovx")
3826 (set_attr "mode" "SI")])
3827
3828 (define_insn "extendqihi2"
3829 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3830 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3831 ""
3832 {
3833 switch (get_attr_prefix_0f (insn))
3834 {
3835 case 0:
3836 return "{cbtw|cbw}";
3837 default:
3838 return "movs{bw|x}\t{%1, %0|%0, %1}";
3839 }
3840 }
3841 [(set_attr "type" "imovx")
3842 (set_attr "mode" "HI")
3843 (set (attr "prefix_0f")
3844 ;; movsx is short decodable while cwtl is vector decoded.
3845 (if_then_else (and (eq_attr "cpu" "!k6")
3846 (eq_attr "alternative" "0"))
3847 (const_string "0")
3848 (const_string "1")))
3849 (set (attr "modrm")
3850 (if_then_else (eq_attr "prefix_0f" "0")
3851 (const_string "0")
3852 (const_string "1")))])
3853 \f
3854 ;; Conversions between float and double.
3855
3856 ;; These are all no-ops in the model used for the 80387.
3857 ;; So just emit moves.
3858
3859 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3860 (define_split
3861 [(set (match_operand:DF 0 "push_operand")
3862 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3863 "reload_completed"
3864 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3865 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3866
3867 (define_split
3868 [(set (match_operand:XF 0 "push_operand")
3869 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3870 "reload_completed"
3871 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3872 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3873 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3874
3875 (define_expand "extendsfdf2"
3876 [(set (match_operand:DF 0 "nonimmediate_operand")
3877 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3878 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3879 {
3880 /* ??? Needed for compress_float_constant since all fp constants
3881 are TARGET_LEGITIMATE_CONSTANT_P. */
3882 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3883 {
3884 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3885 && standard_80387_constant_p (operands[1]) > 0)
3886 {
3887 operands[1] = simplify_const_unary_operation
3888 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3889 emit_move_insn_1 (operands[0], operands[1]);
3890 DONE;
3891 }
3892 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3893 }
3894 })
3895
3896 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3897 cvtss2sd:
3898 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3899 cvtps2pd xmm2,xmm1
3900 We do the conversion post reload to avoid producing of 128bit spills
3901 that might lead to ICE on 32bit target. The sequence unlikely combine
3902 anyway. */
3903 (define_split
3904 [(set (match_operand:DF 0 "register_operand")
3905 (float_extend:DF
3906 (match_operand:SF 1 "nonimmediate_operand")))]
3907 "TARGET_USE_VECTOR_FP_CONVERTS
3908 && optimize_insn_for_speed_p ()
3909 && reload_completed && SSE_REG_P (operands[0])"
3910 [(set (match_dup 2)
3911 (float_extend:V2DF
3912 (vec_select:V2SF
3913 (match_dup 3)
3914 (parallel [(const_int 0) (const_int 1)]))))]
3915 {
3916 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3917 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3918 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3919 Try to avoid move when unpacking can be done in source. */
3920 if (REG_P (operands[1]))
3921 {
3922 /* If it is unsafe to overwrite upper half of source, we need
3923 to move to destination and unpack there. */
3924 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3925 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3926 && true_regnum (operands[0]) != true_regnum (operands[1]))
3927 {
3928 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3929 emit_move_insn (tmp, operands[1]);
3930 }
3931 else
3932 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3933 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3934 operands[3]));
3935 }
3936 else
3937 emit_insn (gen_vec_setv4sf_0 (operands[3],
3938 CONST0_RTX (V4SFmode), operands[1]));
3939 })
3940
3941 (define_insn "*extendsfdf2_mixed"
3942 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3943 (float_extend:DF
3944 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3945 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3946 {
3947 switch (which_alternative)
3948 {
3949 case 0:
3950 case 1:
3951 return output_387_reg_move (insn, operands);
3952
3953 case 2:
3954 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3955
3956 default:
3957 gcc_unreachable ();
3958 }
3959 }
3960 [(set_attr "type" "fmov,fmov,ssecvt")
3961 (set_attr "prefix" "orig,orig,maybe_vex")
3962 (set_attr "mode" "SF,XF,DF")])
3963
3964 (define_insn "*extendsfdf2_sse"
3965 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3966 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3967 "TARGET_SSE2 && TARGET_SSE_MATH"
3968 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3969 [(set_attr "type" "ssecvt")
3970 (set_attr "prefix" "maybe_vex")
3971 (set_attr "mode" "DF")])
3972
3973 (define_insn "*extendsfdf2_i387"
3974 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3975 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3976 "TARGET_80387"
3977 "* return output_387_reg_move (insn, operands);"
3978 [(set_attr "type" "fmov")
3979 (set_attr "mode" "SF,XF")])
3980
3981 (define_expand "extend<mode>xf2"
3982 [(set (match_operand:XF 0 "nonimmediate_operand")
3983 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3984 "TARGET_80387"
3985 {
3986 /* ??? Needed for compress_float_constant since all fp constants
3987 are TARGET_LEGITIMATE_CONSTANT_P. */
3988 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3989 {
3990 if (standard_80387_constant_p (operands[1]) > 0)
3991 {
3992 operands[1] = simplify_const_unary_operation
3993 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3994 emit_move_insn_1 (operands[0], operands[1]);
3995 DONE;
3996 }
3997 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3998 }
3999 })
4000
4001 (define_insn "*extend<mode>xf2_i387"
4002 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4003 (float_extend:XF
4004 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4005 "TARGET_80387"
4006 "* return output_387_reg_move (insn, operands);"
4007 [(set_attr "type" "fmov")
4008 (set_attr "mode" "<MODE>,XF")])
4009
4010 ;; %%% This seems bad bad news.
4011 ;; This cannot output into an f-reg because there is no way to be sure
4012 ;; of truncating in that case. Otherwise this is just like a simple move
4013 ;; insn. So we pretend we can output to a reg in order to get better
4014 ;; register preferencing, but we really use a stack slot.
4015
4016 ;; Conversion from DFmode to SFmode.
4017
4018 (define_expand "truncdfsf2"
4019 [(set (match_operand:SF 0 "nonimmediate_operand")
4020 (float_truncate:SF
4021 (match_operand:DF 1 "nonimmediate_operand")))]
4022 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4023 {
4024 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4025 ;
4026 else if (flag_unsafe_math_optimizations)
4027 ;
4028 else
4029 {
4030 enum ix86_stack_slot slot = (virtuals_instantiated
4031 ? SLOT_TEMP
4032 : SLOT_VIRTUAL);
4033 rtx temp = assign_386_stack_local (SFmode, slot);
4034 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4035 DONE;
4036 }
4037 })
4038
4039 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4040 cvtsd2ss:
4041 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4042 cvtpd2ps xmm2,xmm1
4043 We do the conversion post reload to avoid producing of 128bit spills
4044 that might lead to ICE on 32bit target. The sequence unlikely combine
4045 anyway. */
4046 (define_split
4047 [(set (match_operand:SF 0 "register_operand")
4048 (float_truncate:SF
4049 (match_operand:DF 1 "nonimmediate_operand")))]
4050 "TARGET_USE_VECTOR_FP_CONVERTS
4051 && optimize_insn_for_speed_p ()
4052 && reload_completed && SSE_REG_P (operands[0])"
4053 [(set (match_dup 2)
4054 (vec_concat:V4SF
4055 (float_truncate:V2SF
4056 (match_dup 4))
4057 (match_dup 3)))]
4058 {
4059 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4060 operands[3] = CONST0_RTX (V2SFmode);
4061 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4062 /* Use movsd for loading from memory, unpcklpd for registers.
4063 Try to avoid move when unpacking can be done in source, or SSE3
4064 movddup is available. */
4065 if (REG_P (operands[1]))
4066 {
4067 if (!TARGET_SSE3
4068 && true_regnum (operands[0]) != true_regnum (operands[1])
4069 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4070 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4071 {
4072 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4073 emit_move_insn (tmp, operands[1]);
4074 operands[1] = tmp;
4075 }
4076 else if (!TARGET_SSE3)
4077 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4078 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4079 }
4080 else
4081 emit_insn (gen_sse2_loadlpd (operands[4],
4082 CONST0_RTX (V2DFmode), operands[1]));
4083 })
4084
4085 (define_expand "truncdfsf2_with_temp"
4086 [(parallel [(set (match_operand:SF 0)
4087 (float_truncate:SF (match_operand:DF 1)))
4088 (clobber (match_operand:SF 2))])])
4089
4090 (define_insn "*truncdfsf_fast_mixed"
4091 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4092 (float_truncate:SF
4093 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4094 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4095 {
4096 switch (which_alternative)
4097 {
4098 case 0:
4099 return output_387_reg_move (insn, operands);
4100 case 1:
4101 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4102 default:
4103 gcc_unreachable ();
4104 }
4105 }
4106 [(set_attr "type" "fmov,ssecvt")
4107 (set_attr "prefix" "orig,maybe_vex")
4108 (set_attr "mode" "SF")])
4109
4110 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4111 ;; because nothing we do here is unsafe.
4112 (define_insn "*truncdfsf_fast_sse"
4113 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4114 (float_truncate:SF
4115 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4116 "TARGET_SSE2 && TARGET_SSE_MATH"
4117 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4118 [(set_attr "type" "ssecvt")
4119 (set_attr "prefix" "maybe_vex")
4120 (set_attr "mode" "SF")])
4121
4122 (define_insn "*truncdfsf_fast_i387"
4123 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4124 (float_truncate:SF
4125 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4126 "TARGET_80387 && flag_unsafe_math_optimizations"
4127 "* return output_387_reg_move (insn, operands);"
4128 [(set_attr "type" "fmov")
4129 (set_attr "mode" "SF")])
4130
4131 (define_insn "*truncdfsf_mixed"
4132 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4133 (float_truncate:SF
4134 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4135 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4136 "TARGET_MIX_SSE_I387"
4137 {
4138 switch (which_alternative)
4139 {
4140 case 0:
4141 return output_387_reg_move (insn, operands);
4142 case 1:
4143 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4144
4145 default:
4146 return "#";
4147 }
4148 }
4149 [(set_attr "isa" "*,sse2,*,*,*")
4150 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4151 (set_attr "unit" "*,*,i387,i387,i387")
4152 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4153 (set_attr "mode" "SF")])
4154
4155 (define_insn "*truncdfsf_i387"
4156 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4157 (float_truncate:SF
4158 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4159 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4160 "TARGET_80387"
4161 {
4162 switch (which_alternative)
4163 {
4164 case 0:
4165 return output_387_reg_move (insn, operands);
4166
4167 default:
4168 return "#";
4169 }
4170 }
4171 [(set_attr "type" "fmov,multi,multi,multi")
4172 (set_attr "unit" "*,i387,i387,i387")
4173 (set_attr "mode" "SF")])
4174
4175 (define_insn "*truncdfsf2_i387_1"
4176 [(set (match_operand:SF 0 "memory_operand" "=m")
4177 (float_truncate:SF
4178 (match_operand:DF 1 "register_operand" "f")))]
4179 "TARGET_80387
4180 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4181 && !TARGET_MIX_SSE_I387"
4182 "* return output_387_reg_move (insn, operands);"
4183 [(set_attr "type" "fmov")
4184 (set_attr "mode" "SF")])
4185
4186 (define_split
4187 [(set (match_operand:SF 0 "register_operand")
4188 (float_truncate:SF
4189 (match_operand:DF 1 "fp_register_operand")))
4190 (clobber (match_operand 2))]
4191 "reload_completed"
4192 [(set (match_dup 2) (match_dup 1))
4193 (set (match_dup 0) (match_dup 2))]
4194 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4195
4196 ;; Conversion from XFmode to {SF,DF}mode
4197
4198 (define_expand "truncxf<mode>2"
4199 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4200 (float_truncate:MODEF
4201 (match_operand:XF 1 "register_operand")))
4202 (clobber (match_dup 2))])]
4203 "TARGET_80387"
4204 {
4205 if (flag_unsafe_math_optimizations)
4206 {
4207 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4208 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4209 if (reg != operands[0])
4210 emit_move_insn (operands[0], reg);
4211 DONE;
4212 }
4213 else
4214 {
4215 enum ix86_stack_slot slot = (virtuals_instantiated
4216 ? SLOT_TEMP
4217 : SLOT_VIRTUAL);
4218 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4219 }
4220 })
4221
4222 (define_insn "*truncxfsf2_mixed"
4223 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4224 (float_truncate:SF
4225 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4226 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4227 "TARGET_80387"
4228 {
4229 gcc_assert (!which_alternative);
4230 return output_387_reg_move (insn, operands);
4231 }
4232 [(set_attr "type" "fmov,multi,multi,multi")
4233 (set_attr "unit" "*,i387,i387,i387")
4234 (set_attr "mode" "SF")])
4235
4236 (define_insn "*truncxfdf2_mixed"
4237 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4238 (float_truncate:DF
4239 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4240 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4241 "TARGET_80387"
4242 {
4243 gcc_assert (!which_alternative);
4244 return output_387_reg_move (insn, operands);
4245 }
4246 [(set_attr "isa" "*,*,sse2,*")
4247 (set_attr "type" "fmov,multi,multi,multi")
4248 (set_attr "unit" "*,i387,i387,i387")
4249 (set_attr "mode" "DF")])
4250
4251 (define_insn "truncxf<mode>2_i387_noop"
4252 [(set (match_operand:MODEF 0 "register_operand" "=f")
4253 (float_truncate:MODEF
4254 (match_operand:XF 1 "register_operand" "f")))]
4255 "TARGET_80387 && flag_unsafe_math_optimizations"
4256 "* return output_387_reg_move (insn, operands);"
4257 [(set_attr "type" "fmov")
4258 (set_attr "mode" "<MODE>")])
4259
4260 (define_insn "*truncxf<mode>2_i387"
4261 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4262 (float_truncate:MODEF
4263 (match_operand:XF 1 "register_operand" "f")))]
4264 "TARGET_80387"
4265 "* return output_387_reg_move (insn, operands);"
4266 [(set_attr "type" "fmov")
4267 (set_attr "mode" "<MODE>")])
4268
4269 (define_split
4270 [(set (match_operand:MODEF 0 "register_operand")
4271 (float_truncate:MODEF
4272 (match_operand:XF 1 "register_operand")))
4273 (clobber (match_operand:MODEF 2 "memory_operand"))]
4274 "TARGET_80387 && reload_completed"
4275 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4276 (set (match_dup 0) (match_dup 2))])
4277
4278 (define_split
4279 [(set (match_operand:MODEF 0 "memory_operand")
4280 (float_truncate:MODEF
4281 (match_operand:XF 1 "register_operand")))
4282 (clobber (match_operand:MODEF 2 "memory_operand"))]
4283 "TARGET_80387"
4284 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4285 \f
4286 ;; Signed conversion to DImode.
4287
4288 (define_expand "fix_truncxfdi2"
4289 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4290 (fix:DI (match_operand:XF 1 "register_operand")))
4291 (clobber (reg:CC FLAGS_REG))])]
4292 "TARGET_80387"
4293 {
4294 if (TARGET_FISTTP)
4295 {
4296 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4297 DONE;
4298 }
4299 })
4300
4301 (define_expand "fix_trunc<mode>di2"
4302 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4303 (fix:DI (match_operand:MODEF 1 "register_operand")))
4304 (clobber (reg:CC FLAGS_REG))])]
4305 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4306 {
4307 if (TARGET_FISTTP
4308 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4309 {
4310 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4311 DONE;
4312 }
4313 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4314 {
4315 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4316 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4317 if (out != operands[0])
4318 emit_move_insn (operands[0], out);
4319 DONE;
4320 }
4321 })
4322
4323 ;; Signed conversion to SImode.
4324
4325 (define_expand "fix_truncxfsi2"
4326 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4327 (fix:SI (match_operand:XF 1 "register_operand")))
4328 (clobber (reg:CC FLAGS_REG))])]
4329 "TARGET_80387"
4330 {
4331 if (TARGET_FISTTP)
4332 {
4333 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4334 DONE;
4335 }
4336 })
4337
4338 (define_expand "fix_trunc<mode>si2"
4339 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4340 (fix:SI (match_operand:MODEF 1 "register_operand")))
4341 (clobber (reg:CC FLAGS_REG))])]
4342 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4343 {
4344 if (TARGET_FISTTP
4345 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4346 {
4347 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4348 DONE;
4349 }
4350 if (SSE_FLOAT_MODE_P (<MODE>mode))
4351 {
4352 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4353 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4354 if (out != operands[0])
4355 emit_move_insn (operands[0], out);
4356 DONE;
4357 }
4358 })
4359
4360 ;; Signed conversion to HImode.
4361
4362 (define_expand "fix_trunc<mode>hi2"
4363 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4364 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4365 (clobber (reg:CC FLAGS_REG))])]
4366 "TARGET_80387
4367 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4368 {
4369 if (TARGET_FISTTP)
4370 {
4371 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4372 DONE;
4373 }
4374 })
4375
4376 ;; Unsigned conversion to SImode.
4377
4378 (define_expand "fixuns_trunc<mode>si2"
4379 [(parallel
4380 [(set (match_operand:SI 0 "register_operand")
4381 (unsigned_fix:SI
4382 (match_operand:MODEF 1 "nonimmediate_operand")))
4383 (use (match_dup 2))
4384 (clobber (match_scratch:<ssevecmode> 3))
4385 (clobber (match_scratch:<ssevecmode> 4))])]
4386 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4387 {
4388 enum machine_mode mode = <MODE>mode;
4389 enum machine_mode vecmode = <ssevecmode>mode;
4390 REAL_VALUE_TYPE TWO31r;
4391 rtx two31;
4392
4393 if (optimize_insn_for_size_p ())
4394 FAIL;
4395
4396 real_ldexp (&TWO31r, &dconst1, 31);
4397 two31 = const_double_from_real_value (TWO31r, mode);
4398 two31 = ix86_build_const_vector (vecmode, true, two31);
4399 operands[2] = force_reg (vecmode, two31);
4400 })
4401
4402 (define_insn_and_split "*fixuns_trunc<mode>_1"
4403 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4404 (unsigned_fix:SI
4405 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4406 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4407 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4408 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4409 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4410 && optimize_function_for_speed_p (cfun)"
4411 "#"
4412 "&& reload_completed"
4413 [(const_int 0)]
4414 {
4415 ix86_split_convert_uns_si_sse (operands);
4416 DONE;
4417 })
4418
4419 ;; Unsigned conversion to HImode.
4420 ;; Without these patterns, we'll try the unsigned SI conversion which
4421 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4422
4423 (define_expand "fixuns_trunc<mode>hi2"
4424 [(set (match_dup 2)
4425 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4426 (set (match_operand:HI 0 "nonimmediate_operand")
4427 (subreg:HI (match_dup 2) 0))]
4428 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4429 "operands[2] = gen_reg_rtx (SImode);")
4430
4431 ;; When SSE is available, it is always faster to use it!
4432 (define_insn "fix_trunc<mode>di_sse"
4433 [(set (match_operand:DI 0 "register_operand" "=r,r")
4434 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4435 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4436 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4437 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4438 [(set_attr "type" "sseicvt")
4439 (set_attr "prefix" "maybe_vex")
4440 (set_attr "prefix_rex" "1")
4441 (set_attr "mode" "<MODE>")
4442 (set_attr "athlon_decode" "double,vector")
4443 (set_attr "amdfam10_decode" "double,double")
4444 (set_attr "bdver1_decode" "double,double")])
4445
4446 (define_insn "fix_trunc<mode>si_sse"
4447 [(set (match_operand:SI 0 "register_operand" "=r,r")
4448 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4449 "SSE_FLOAT_MODE_P (<MODE>mode)
4450 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4451 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4452 [(set_attr "type" "sseicvt")
4453 (set_attr "prefix" "maybe_vex")
4454 (set_attr "mode" "<MODE>")
4455 (set_attr "athlon_decode" "double,vector")
4456 (set_attr "amdfam10_decode" "double,double")
4457 (set_attr "bdver1_decode" "double,double")])
4458
4459 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4460 (define_peephole2
4461 [(set (match_operand:MODEF 0 "register_operand")
4462 (match_operand:MODEF 1 "memory_operand"))
4463 (set (match_operand:SWI48x 2 "register_operand")
4464 (fix:SWI48x (match_dup 0)))]
4465 "TARGET_SHORTEN_X87_SSE
4466 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4467 && peep2_reg_dead_p (2, operands[0])"
4468 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4469
4470 ;; Avoid vector decoded forms of the instruction.
4471 (define_peephole2
4472 [(match_scratch:DF 2 "x")
4473 (set (match_operand:SWI48x 0 "register_operand")
4474 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4475 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4476 [(set (match_dup 2) (match_dup 1))
4477 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4478
4479 (define_peephole2
4480 [(match_scratch:SF 2 "x")
4481 (set (match_operand:SWI48x 0 "register_operand")
4482 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4483 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4484 [(set (match_dup 2) (match_dup 1))
4485 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4486
4487 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4488 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4489 (fix:SWI248x (match_operand 1 "register_operand")))]
4490 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4491 && TARGET_FISTTP
4492 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4493 && (TARGET_64BIT || <MODE>mode != DImode))
4494 && TARGET_SSE_MATH)
4495 && can_create_pseudo_p ()"
4496 "#"
4497 "&& 1"
4498 [(const_int 0)]
4499 {
4500 if (memory_operand (operands[0], VOIDmode))
4501 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4502 else
4503 {
4504 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4505 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4506 operands[1],
4507 operands[2]));
4508 }
4509 DONE;
4510 }
4511 [(set_attr "type" "fisttp")
4512 (set_attr "mode" "<MODE>")])
4513
4514 (define_insn "fix_trunc<mode>_i387_fisttp"
4515 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4516 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4517 (clobber (match_scratch:XF 2 "=&1f"))]
4518 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4519 && TARGET_FISTTP
4520 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4521 && (TARGET_64BIT || <MODE>mode != DImode))
4522 && TARGET_SSE_MATH)"
4523 "* return output_fix_trunc (insn, operands, true);"
4524 [(set_attr "type" "fisttp")
4525 (set_attr "mode" "<MODE>")])
4526
4527 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4528 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4529 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4530 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4531 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4532 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && TARGET_FISTTP
4534 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4535 && (TARGET_64BIT || <MODE>mode != DImode))
4536 && TARGET_SSE_MATH)"
4537 "#"
4538 [(set_attr "type" "fisttp")
4539 (set_attr "mode" "<MODE>")])
4540
4541 (define_split
4542 [(set (match_operand:SWI248x 0 "register_operand")
4543 (fix:SWI248x (match_operand 1 "register_operand")))
4544 (clobber (match_operand:SWI248x 2 "memory_operand"))
4545 (clobber (match_scratch 3))]
4546 "reload_completed"
4547 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4548 (clobber (match_dup 3))])
4549 (set (match_dup 0) (match_dup 2))])
4550
4551 (define_split
4552 [(set (match_operand:SWI248x 0 "memory_operand")
4553 (fix:SWI248x (match_operand 1 "register_operand")))
4554 (clobber (match_operand:SWI248x 2 "memory_operand"))
4555 (clobber (match_scratch 3))]
4556 "reload_completed"
4557 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4558 (clobber (match_dup 3))])])
4559
4560 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4561 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4562 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4563 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4564 ;; function in i386.c.
4565 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4566 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4567 (fix:SWI248x (match_operand 1 "register_operand")))
4568 (clobber (reg:CC FLAGS_REG))]
4569 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4570 && !TARGET_FISTTP
4571 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4572 && (TARGET_64BIT || <MODE>mode != DImode))
4573 && can_create_pseudo_p ()"
4574 "#"
4575 "&& 1"
4576 [(const_int 0)]
4577 {
4578 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4579
4580 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4581 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4582 if (memory_operand (operands[0], VOIDmode))
4583 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4584 operands[2], operands[3]));
4585 else
4586 {
4587 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4588 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4589 operands[2], operands[3],
4590 operands[4]));
4591 }
4592 DONE;
4593 }
4594 [(set_attr "type" "fistp")
4595 (set_attr "i387_cw" "trunc")
4596 (set_attr "mode" "<MODE>")])
4597
4598 (define_insn "fix_truncdi_i387"
4599 [(set (match_operand:DI 0 "memory_operand" "=m")
4600 (fix:DI (match_operand 1 "register_operand" "f")))
4601 (use (match_operand:HI 2 "memory_operand" "m"))
4602 (use (match_operand:HI 3 "memory_operand" "m"))
4603 (clobber (match_scratch:XF 4 "=&1f"))]
4604 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4605 && !TARGET_FISTTP
4606 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4607 "* return output_fix_trunc (insn, operands, false);"
4608 [(set_attr "type" "fistp")
4609 (set_attr "i387_cw" "trunc")
4610 (set_attr "mode" "DI")])
4611
4612 (define_insn "fix_truncdi_i387_with_temp"
4613 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4614 (fix:DI (match_operand 1 "register_operand" "f,f")))
4615 (use (match_operand:HI 2 "memory_operand" "m,m"))
4616 (use (match_operand:HI 3 "memory_operand" "m,m"))
4617 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4618 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4619 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4620 && !TARGET_FISTTP
4621 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4622 "#"
4623 [(set_attr "type" "fistp")
4624 (set_attr "i387_cw" "trunc")
4625 (set_attr "mode" "DI")])
4626
4627 (define_split
4628 [(set (match_operand:DI 0 "register_operand")
4629 (fix:DI (match_operand 1 "register_operand")))
4630 (use (match_operand:HI 2 "memory_operand"))
4631 (use (match_operand:HI 3 "memory_operand"))
4632 (clobber (match_operand:DI 4 "memory_operand"))
4633 (clobber (match_scratch 5))]
4634 "reload_completed"
4635 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4636 (use (match_dup 2))
4637 (use (match_dup 3))
4638 (clobber (match_dup 5))])
4639 (set (match_dup 0) (match_dup 4))])
4640
4641 (define_split
4642 [(set (match_operand:DI 0 "memory_operand")
4643 (fix:DI (match_operand 1 "register_operand")))
4644 (use (match_operand:HI 2 "memory_operand"))
4645 (use (match_operand:HI 3 "memory_operand"))
4646 (clobber (match_operand:DI 4 "memory_operand"))
4647 (clobber (match_scratch 5))]
4648 "reload_completed"
4649 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4650 (use (match_dup 2))
4651 (use (match_dup 3))
4652 (clobber (match_dup 5))])])
4653
4654 (define_insn "fix_trunc<mode>_i387"
4655 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4656 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4657 (use (match_operand:HI 2 "memory_operand" "m"))
4658 (use (match_operand:HI 3 "memory_operand" "m"))]
4659 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4660 && !TARGET_FISTTP
4661 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4662 "* return output_fix_trunc (insn, operands, false);"
4663 [(set_attr "type" "fistp")
4664 (set_attr "i387_cw" "trunc")
4665 (set_attr "mode" "<MODE>")])
4666
4667 (define_insn "fix_trunc<mode>_i387_with_temp"
4668 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4669 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4670 (use (match_operand:HI 2 "memory_operand" "m,m"))
4671 (use (match_operand:HI 3 "memory_operand" "m,m"))
4672 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4673 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4674 && !TARGET_FISTTP
4675 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4676 "#"
4677 [(set_attr "type" "fistp")
4678 (set_attr "i387_cw" "trunc")
4679 (set_attr "mode" "<MODE>")])
4680
4681 (define_split
4682 [(set (match_operand:SWI24 0 "register_operand")
4683 (fix:SWI24 (match_operand 1 "register_operand")))
4684 (use (match_operand:HI 2 "memory_operand"))
4685 (use (match_operand:HI 3 "memory_operand"))
4686 (clobber (match_operand:SWI24 4 "memory_operand"))]
4687 "reload_completed"
4688 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4689 (use (match_dup 2))
4690 (use (match_dup 3))])
4691 (set (match_dup 0) (match_dup 4))])
4692
4693 (define_split
4694 [(set (match_operand:SWI24 0 "memory_operand")
4695 (fix:SWI24 (match_operand 1 "register_operand")))
4696 (use (match_operand:HI 2 "memory_operand"))
4697 (use (match_operand:HI 3 "memory_operand"))
4698 (clobber (match_operand:SWI24 4 "memory_operand"))]
4699 "reload_completed"
4700 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4701 (use (match_dup 2))
4702 (use (match_dup 3))])])
4703
4704 (define_insn "x86_fnstcw_1"
4705 [(set (match_operand:HI 0 "memory_operand" "=m")
4706 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4707 "TARGET_80387"
4708 "fnstcw\t%0"
4709 [(set (attr "length")
4710 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4711 (set_attr "mode" "HI")
4712 (set_attr "unit" "i387")
4713 (set_attr "bdver1_decode" "vector")])
4714
4715 (define_insn "x86_fldcw_1"
4716 [(set (reg:HI FPCR_REG)
4717 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4718 "TARGET_80387"
4719 "fldcw\t%0"
4720 [(set (attr "length")
4721 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4722 (set_attr "mode" "HI")
4723 (set_attr "unit" "i387")
4724 (set_attr "athlon_decode" "vector")
4725 (set_attr "amdfam10_decode" "vector")
4726 (set_attr "bdver1_decode" "vector")])
4727 \f
4728 ;; Conversion between fixed point and floating point.
4729
4730 ;; Even though we only accept memory inputs, the backend _really_
4731 ;; wants to be able to do this between registers.
4732
4733 (define_expand "floathi<mode>2"
4734 [(set (match_operand:X87MODEF 0 "register_operand")
4735 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4736 "TARGET_80387
4737 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4738 || TARGET_MIX_SSE_I387)")
4739
4740 ;; Pre-reload splitter to add memory clobber to the pattern.
4741 (define_insn_and_split "*floathi<mode>2_1"
4742 [(set (match_operand:X87MODEF 0 "register_operand")
4743 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4744 "TARGET_80387
4745 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4746 || TARGET_MIX_SSE_I387)
4747 && can_create_pseudo_p ()"
4748 "#"
4749 "&& 1"
4750 [(parallel [(set (match_dup 0)
4751 (float:X87MODEF (match_dup 1)))
4752 (clobber (match_dup 2))])]
4753 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4754
4755 (define_insn "*floathi<mode>2_i387_with_temp"
4756 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4757 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4758 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4759 "TARGET_80387
4760 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4761 || TARGET_MIX_SSE_I387)"
4762 "#"
4763 [(set_attr "type" "fmov,multi")
4764 (set_attr "mode" "<MODE>")
4765 (set_attr "unit" "*,i387")
4766 (set_attr "fp_int_src" "true")])
4767
4768 (define_insn "*floathi<mode>2_i387"
4769 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4770 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4771 "TARGET_80387
4772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4773 || TARGET_MIX_SSE_I387)"
4774 "fild%Z1\t%1"
4775 [(set_attr "type" "fmov")
4776 (set_attr "mode" "<MODE>")
4777 (set_attr "fp_int_src" "true")])
4778
4779 (define_split
4780 [(set (match_operand:X87MODEF 0 "register_operand")
4781 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4782 (clobber (match_operand:HI 2 "memory_operand"))]
4783 "TARGET_80387
4784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4785 || TARGET_MIX_SSE_I387)
4786 && reload_completed"
4787 [(set (match_dup 2) (match_dup 1))
4788 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4789
4790 (define_split
4791 [(set (match_operand:X87MODEF 0 "register_operand")
4792 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4793 (clobber (match_operand:HI 2 "memory_operand"))]
4794 "TARGET_80387
4795 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4796 || TARGET_MIX_SSE_I387)
4797 && reload_completed"
4798 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4799
4800 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4801 [(set (match_operand:X87MODEF 0 "register_operand")
4802 (float:X87MODEF
4803 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4804 "TARGET_80387
4805 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4806 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4807 {
4808 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4809 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4810 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4811 {
4812 rtx reg = gen_reg_rtx (XFmode);
4813 rtx (*insn)(rtx, rtx);
4814
4815 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4816
4817 if (<X87MODEF:MODE>mode == SFmode)
4818 insn = gen_truncxfsf2;
4819 else if (<X87MODEF:MODE>mode == DFmode)
4820 insn = gen_truncxfdf2;
4821 else
4822 gcc_unreachable ();
4823
4824 emit_insn (insn (operands[0], reg));
4825 DONE;
4826 }
4827 })
4828
4829 ;; Pre-reload splitter to add memory clobber to the pattern.
4830 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4831 [(set (match_operand:X87MODEF 0 "register_operand")
4832 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4833 "((TARGET_80387
4834 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4835 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4836 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4837 || TARGET_MIX_SSE_I387))
4838 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4839 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4840 && ((<SWI48x:MODE>mode == SImode
4841 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4842 && optimize_function_for_speed_p (cfun)
4843 && flag_trapping_math)
4844 || !(TARGET_INTER_UNIT_CONVERSIONS
4845 || optimize_function_for_size_p (cfun)))))
4846 && can_create_pseudo_p ()"
4847 "#"
4848 "&& 1"
4849 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4850 (clobber (match_dup 2))])]
4851 {
4852 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4853
4854 /* Avoid store forwarding (partial memory) stall penalty
4855 by passing DImode value through XMM registers. */
4856 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4857 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4858 && optimize_function_for_speed_p (cfun))
4859 {
4860 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4861 operands[1],
4862 operands[2]));
4863 DONE;
4864 }
4865 })
4866
4867 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4868 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4869 (float:MODEF
4870 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4871 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4872 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4873 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4874 "#"
4875 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4876 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4877 (set_attr "unit" "*,i387,*,*,*")
4878 (set_attr "athlon_decode" "*,*,double,direct,double")
4879 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4880 (set_attr "bdver1_decode" "*,*,double,direct,double")
4881 (set_attr "fp_int_src" "true")])
4882
4883 (define_insn "*floatsi<mode>2_vector_mixed"
4884 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4885 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4886 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4887 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4888 "@
4889 fild%Z1\t%1
4890 #"
4891 [(set_attr "type" "fmov,sseicvt")
4892 (set_attr "mode" "<MODE>,<ssevecmode>")
4893 (set_attr "unit" "i387,*")
4894 (set_attr "athlon_decode" "*,direct")
4895 (set_attr "amdfam10_decode" "*,double")
4896 (set_attr "bdver1_decode" "*,direct")
4897 (set_attr "fp_int_src" "true")])
4898
4899 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4900 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4901 (float:MODEF
4902 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4903 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4904 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4905 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4906 "#"
4907 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4908 (set_attr "mode" "<MODEF:MODE>")
4909 (set_attr "unit" "*,i387,*,*")
4910 (set_attr "athlon_decode" "*,*,double,direct")
4911 (set_attr "amdfam10_decode" "*,*,vector,double")
4912 (set_attr "bdver1_decode" "*,*,double,direct")
4913 (set_attr "fp_int_src" "true")])
4914
4915 (define_split
4916 [(set (match_operand:MODEF 0 "register_operand")
4917 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4918 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4919 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4920 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4921 && TARGET_INTER_UNIT_CONVERSIONS
4922 && reload_completed
4923 && (SSE_REG_P (operands[0])
4924 || (GET_CODE (operands[0]) == SUBREG
4925 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4926 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4927
4928 (define_split
4929 [(set (match_operand:MODEF 0 "register_operand")
4930 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4931 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4932 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4933 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4934 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4935 && reload_completed
4936 && (SSE_REG_P (operands[0])
4937 || (GET_CODE (operands[0]) == SUBREG
4938 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4939 [(set (match_dup 2) (match_dup 1))
4940 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4941
4942 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4943 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4944 (float:MODEF
4945 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4946 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4947 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4948 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4949 "@
4950 fild%Z1\t%1
4951 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4952 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4953 [(set_attr "type" "fmov,sseicvt,sseicvt")
4954 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4955 (set_attr "mode" "<MODEF:MODE>")
4956 (set (attr "prefix_rex")
4957 (if_then_else
4958 (and (eq_attr "prefix" "maybe_vex")
4959 (match_test "<SWI48x:MODE>mode == DImode"))
4960 (const_string "1")
4961 (const_string "*")))
4962 (set_attr "unit" "i387,*,*")
4963 (set_attr "athlon_decode" "*,double,direct")
4964 (set_attr "amdfam10_decode" "*,vector,double")
4965 (set_attr "bdver1_decode" "*,double,direct")
4966 (set_attr "fp_int_src" "true")])
4967
4968 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4969 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4970 (float:MODEF
4971 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4972 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4973 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4974 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4975 "@
4976 fild%Z1\t%1
4977 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4978 [(set_attr "type" "fmov,sseicvt")
4979 (set_attr "prefix" "orig,maybe_vex")
4980 (set_attr "mode" "<MODEF:MODE>")
4981 (set (attr "prefix_rex")
4982 (if_then_else
4983 (and (eq_attr "prefix" "maybe_vex")
4984 (match_test "<SWI48x:MODE>mode == DImode"))
4985 (const_string "1")
4986 (const_string "*")))
4987 (set_attr "athlon_decode" "*,direct")
4988 (set_attr "amdfam10_decode" "*,double")
4989 (set_attr "bdver1_decode" "*,direct")
4990 (set_attr "fp_int_src" "true")])
4991
4992 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4993 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4994 (float:MODEF
4995 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4996 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4997 "TARGET_SSE2 && TARGET_SSE_MATH
4998 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4999 "#"
5000 [(set_attr "type" "sseicvt")
5001 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5002 (set_attr "athlon_decode" "double,direct,double")
5003 (set_attr "amdfam10_decode" "vector,double,double")
5004 (set_attr "bdver1_decode" "double,direct,double")
5005 (set_attr "fp_int_src" "true")])
5006
5007 (define_insn "*floatsi<mode>2_vector_sse"
5008 [(set (match_operand:MODEF 0 "register_operand" "=x")
5009 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5010 "TARGET_SSE2 && TARGET_SSE_MATH
5011 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5012 "#"
5013 [(set_attr "type" "sseicvt")
5014 (set_attr "mode" "<MODE>")
5015 (set_attr "athlon_decode" "direct")
5016 (set_attr "amdfam10_decode" "double")
5017 (set_attr "bdver1_decode" "direct")
5018 (set_attr "fp_int_src" "true")])
5019
5020 (define_split
5021 [(set (match_operand:MODEF 0 "register_operand")
5022 (float:MODEF (match_operand:SI 1 "register_operand")))
5023 (clobber (match_operand:SI 2 "memory_operand"))]
5024 "TARGET_SSE2 && TARGET_SSE_MATH
5025 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5026 && reload_completed
5027 && (SSE_REG_P (operands[0])
5028 || (GET_CODE (operands[0]) == SUBREG
5029 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5030 [(const_int 0)]
5031 {
5032 rtx op1 = operands[1];
5033
5034 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5035 <MODE>mode, 0);
5036 if (GET_CODE (op1) == SUBREG)
5037 op1 = SUBREG_REG (op1);
5038
5039 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5040 {
5041 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5042 emit_insn (gen_sse2_loadld (operands[4],
5043 CONST0_RTX (V4SImode), operands[1]));
5044 }
5045 /* We can ignore possible trapping value in the
5046 high part of SSE register for non-trapping math. */
5047 else if (SSE_REG_P (op1) && !flag_trapping_math)
5048 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5049 else
5050 {
5051 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5052 emit_move_insn (operands[2], operands[1]);
5053 emit_insn (gen_sse2_loadld (operands[4],
5054 CONST0_RTX (V4SImode), operands[2]));
5055 }
5056 if (<ssevecmode>mode == V4SFmode)
5057 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5058 else
5059 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5060 DONE;
5061 })
5062
5063 (define_split
5064 [(set (match_operand:MODEF 0 "register_operand")
5065 (float:MODEF (match_operand:SI 1 "memory_operand")))
5066 (clobber (match_operand:SI 2 "memory_operand"))]
5067 "TARGET_SSE2 && TARGET_SSE_MATH
5068 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5069 && reload_completed
5070 && (SSE_REG_P (operands[0])
5071 || (GET_CODE (operands[0]) == SUBREG
5072 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5073 [(const_int 0)]
5074 {
5075 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5076 <MODE>mode, 0);
5077 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5078
5079 emit_insn (gen_sse2_loadld (operands[4],
5080 CONST0_RTX (V4SImode), operands[1]));
5081 if (<ssevecmode>mode == V4SFmode)
5082 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5083 else
5084 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5085 DONE;
5086 })
5087
5088 (define_split
5089 [(set (match_operand:MODEF 0 "register_operand")
5090 (float:MODEF (match_operand:SI 1 "register_operand")))]
5091 "TARGET_SSE2 && TARGET_SSE_MATH
5092 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5093 && reload_completed
5094 && (SSE_REG_P (operands[0])
5095 || (GET_CODE (operands[0]) == SUBREG
5096 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5097 [(const_int 0)]
5098 {
5099 rtx op1 = operands[1];
5100
5101 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5102 <MODE>mode, 0);
5103 if (GET_CODE (op1) == SUBREG)
5104 op1 = SUBREG_REG (op1);
5105
5106 if (GENERAL_REG_P (op1))
5107 {
5108 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5109 if (TARGET_INTER_UNIT_MOVES)
5110 emit_insn (gen_sse2_loadld (operands[4],
5111 CONST0_RTX (V4SImode), operands[1]));
5112 else
5113 {
5114 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5115 operands[1]);
5116 emit_insn (gen_sse2_loadld (operands[4],
5117 CONST0_RTX (V4SImode), operands[5]));
5118 ix86_free_from_memory (GET_MODE (operands[1]));
5119 }
5120 }
5121 /* We can ignore possible trapping value in the
5122 high part of SSE register for non-trapping math. */
5123 else if (SSE_REG_P (op1) && !flag_trapping_math)
5124 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5125 else
5126 gcc_unreachable ();
5127 if (<ssevecmode>mode == V4SFmode)
5128 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5129 else
5130 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5131 DONE;
5132 })
5133
5134 (define_split
5135 [(set (match_operand:MODEF 0 "register_operand")
5136 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5137 "TARGET_SSE2 && TARGET_SSE_MATH
5138 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5139 && reload_completed
5140 && (SSE_REG_P (operands[0])
5141 || (GET_CODE (operands[0]) == SUBREG
5142 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5143 [(const_int 0)]
5144 {
5145 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5146 <MODE>mode, 0);
5147 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5148
5149 emit_insn (gen_sse2_loadld (operands[4],
5150 CONST0_RTX (V4SImode), operands[1]));
5151 if (<ssevecmode>mode == V4SFmode)
5152 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5153 else
5154 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5155 DONE;
5156 })
5157
5158 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5159 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5160 (float:MODEF
5161 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5162 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5163 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5164 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5165 "#"
5166 [(set_attr "type" "sseicvt")
5167 (set_attr "mode" "<MODEF:MODE>")
5168 (set_attr "athlon_decode" "double,direct")
5169 (set_attr "amdfam10_decode" "vector,double")
5170 (set_attr "bdver1_decode" "double,direct")
5171 (set_attr "fp_int_src" "true")])
5172
5173 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5174 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5175 (float:MODEF
5176 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5177 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5178 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5179 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5180 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5181 [(set_attr "type" "sseicvt")
5182 (set_attr "prefix" "maybe_vex")
5183 (set_attr "mode" "<MODEF:MODE>")
5184 (set (attr "prefix_rex")
5185 (if_then_else
5186 (and (eq_attr "prefix" "maybe_vex")
5187 (match_test "<SWI48x:MODE>mode == DImode"))
5188 (const_string "1")
5189 (const_string "*")))
5190 (set_attr "athlon_decode" "double,direct")
5191 (set_attr "amdfam10_decode" "vector,double")
5192 (set_attr "bdver1_decode" "double,direct")
5193 (set_attr "fp_int_src" "true")])
5194
5195 (define_split
5196 [(set (match_operand:MODEF 0 "register_operand")
5197 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5198 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5199 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5200 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5201 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5202 && reload_completed
5203 && (SSE_REG_P (operands[0])
5204 || (GET_CODE (operands[0]) == SUBREG
5205 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5206 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5207
5208 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5209 [(set (match_operand:MODEF 0 "register_operand" "=x")
5210 (float:MODEF
5211 (match_operand:SWI48x 1 "memory_operand" "m")))]
5212 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5213 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5214 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5215 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5216 [(set_attr "type" "sseicvt")
5217 (set_attr "prefix" "maybe_vex")
5218 (set_attr "mode" "<MODEF:MODE>")
5219 (set (attr "prefix_rex")
5220 (if_then_else
5221 (and (eq_attr "prefix" "maybe_vex")
5222 (match_test "<SWI48x:MODE>mode == DImode"))
5223 (const_string "1")
5224 (const_string "*")))
5225 (set_attr "athlon_decode" "direct")
5226 (set_attr "amdfam10_decode" "double")
5227 (set_attr "bdver1_decode" "direct")
5228 (set_attr "fp_int_src" "true")])
5229
5230 (define_split
5231 [(set (match_operand:MODEF 0 "register_operand")
5232 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5233 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5234 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5235 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5236 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5237 && reload_completed
5238 && (SSE_REG_P (operands[0])
5239 || (GET_CODE (operands[0]) == SUBREG
5240 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5241 [(set (match_dup 2) (match_dup 1))
5242 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5243
5244 (define_split
5245 [(set (match_operand:MODEF 0 "register_operand")
5246 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5247 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5248 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5249 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5250 && reload_completed
5251 && (SSE_REG_P (operands[0])
5252 || (GET_CODE (operands[0]) == SUBREG
5253 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5254 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5255
5256 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5257 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5258 (float:X87MODEF
5259 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5260 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5261 "TARGET_80387
5262 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5263 "@
5264 fild%Z1\t%1
5265 #"
5266 [(set_attr "type" "fmov,multi")
5267 (set_attr "mode" "<X87MODEF:MODE>")
5268 (set_attr "unit" "*,i387")
5269 (set_attr "fp_int_src" "true")])
5270
5271 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5272 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5273 (float:X87MODEF
5274 (match_operand:SWI48x 1 "memory_operand" "m")))]
5275 "TARGET_80387
5276 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5277 "fild%Z1\t%1"
5278 [(set_attr "type" "fmov")
5279 (set_attr "mode" "<X87MODEF:MODE>")
5280 (set_attr "fp_int_src" "true")])
5281
5282 (define_split
5283 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5284 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5285 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5286 "TARGET_80387
5287 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5288 && reload_completed"
5289 [(set (match_dup 2) (match_dup 1))
5290 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5291
5292 (define_split
5293 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5294 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5295 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5296 "TARGET_80387
5297 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5298 && reload_completed"
5299 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5300
5301 ;; Avoid store forwarding (partial memory) stall penalty
5302 ;; by passing DImode value through XMM registers. */
5303
5304 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5305 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5306 (float:X87MODEF
5307 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5308 (clobber (match_scratch:V4SI 3 "=X,x"))
5309 (clobber (match_scratch:V4SI 4 "=X,x"))
5310 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5311 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5312 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5313 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5314 "#"
5315 [(set_attr "type" "multi")
5316 (set_attr "mode" "<X87MODEF:MODE>")
5317 (set_attr "unit" "i387")
5318 (set_attr "fp_int_src" "true")])
5319
5320 (define_split
5321 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5322 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5323 (clobber (match_scratch:V4SI 3))
5324 (clobber (match_scratch:V4SI 4))
5325 (clobber (match_operand:DI 2 "memory_operand"))]
5326 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5327 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5328 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5329 && reload_completed"
5330 [(set (match_dup 2) (match_dup 3))
5331 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5332 {
5333 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5334 Assemble the 64-bit DImode value in an xmm register. */
5335 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5336 gen_rtx_SUBREG (SImode, operands[1], 0)));
5337 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5338 gen_rtx_SUBREG (SImode, operands[1], 4)));
5339 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5340 operands[4]));
5341
5342 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5343 })
5344
5345 (define_split
5346 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5347 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5348 (clobber (match_scratch:V4SI 3))
5349 (clobber (match_scratch:V4SI 4))
5350 (clobber (match_operand:DI 2 "memory_operand"))]
5351 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5352 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5353 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5354 && reload_completed"
5355 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5356
5357 ;; Avoid store forwarding (partial memory) stall penalty by extending
5358 ;; SImode value to DImode through XMM register instead of pushing two
5359 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5360 ;; targets benefit from this optimization. Also note that fild
5361 ;; loads from memory only.
5362
5363 (define_insn "*floatunssi<mode>2_1"
5364 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5365 (unsigned_float:X87MODEF
5366 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5367 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5368 (clobber (match_scratch:SI 3 "=X,x"))]
5369 "!TARGET_64BIT
5370 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5371 && TARGET_SSE"
5372 "#"
5373 [(set_attr "type" "multi")
5374 (set_attr "mode" "<MODE>")])
5375
5376 (define_split
5377 [(set (match_operand:X87MODEF 0 "register_operand")
5378 (unsigned_float:X87MODEF
5379 (match_operand:SI 1 "register_operand")))
5380 (clobber (match_operand:DI 2 "memory_operand"))
5381 (clobber (match_scratch:SI 3))]
5382 "!TARGET_64BIT
5383 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5384 && TARGET_SSE
5385 && reload_completed"
5386 [(set (match_dup 2) (match_dup 1))
5387 (set (match_dup 0)
5388 (float:X87MODEF (match_dup 2)))]
5389 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5390
5391 (define_split
5392 [(set (match_operand:X87MODEF 0 "register_operand")
5393 (unsigned_float:X87MODEF
5394 (match_operand:SI 1 "memory_operand")))
5395 (clobber (match_operand:DI 2 "memory_operand"))
5396 (clobber (match_scratch:SI 3))]
5397 "!TARGET_64BIT
5398 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5399 && TARGET_SSE
5400 && reload_completed"
5401 [(set (match_dup 2) (match_dup 3))
5402 (set (match_dup 0)
5403 (float:X87MODEF (match_dup 2)))]
5404 {
5405 emit_move_insn (operands[3], operands[1]);
5406 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5407 })
5408
5409 (define_expand "floatunssi<mode>2"
5410 [(parallel
5411 [(set (match_operand:X87MODEF 0 "register_operand")
5412 (unsigned_float:X87MODEF
5413 (match_operand:SI 1 "nonimmediate_operand")))
5414 (clobber (match_dup 2))
5415 (clobber (match_scratch:SI 3))])]
5416 "!TARGET_64BIT
5417 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5418 && TARGET_SSE)
5419 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5420 {
5421 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5422 {
5423 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5424 DONE;
5425 }
5426 else
5427 {
5428 enum ix86_stack_slot slot = (virtuals_instantiated
5429 ? SLOT_TEMP
5430 : SLOT_VIRTUAL);
5431 operands[2] = assign_386_stack_local (DImode, slot);
5432 }
5433 })
5434
5435 (define_expand "floatunsdisf2"
5436 [(use (match_operand:SF 0 "register_operand"))
5437 (use (match_operand:DI 1 "nonimmediate_operand"))]
5438 "TARGET_64BIT && TARGET_SSE_MATH"
5439 "x86_emit_floatuns (operands); DONE;")
5440
5441 (define_expand "floatunsdidf2"
5442 [(use (match_operand:DF 0 "register_operand"))
5443 (use (match_operand:DI 1 "nonimmediate_operand"))]
5444 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5445 && TARGET_SSE2 && TARGET_SSE_MATH"
5446 {
5447 if (TARGET_64BIT)
5448 x86_emit_floatuns (operands);
5449 else
5450 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5451 DONE;
5452 })
5453 \f
5454 ;; Add instructions
5455
5456 (define_expand "add<mode>3"
5457 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5458 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5459 (match_operand:SDWIM 2 "<general_operand>")))]
5460 ""
5461 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5462
5463 (define_insn_and_split "*add<dwi>3_doubleword"
5464 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5465 (plus:<DWI>
5466 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5467 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5468 (clobber (reg:CC FLAGS_REG))]
5469 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5470 "#"
5471 "reload_completed"
5472 [(parallel [(set (reg:CC FLAGS_REG)
5473 (unspec:CC [(match_dup 1) (match_dup 2)]
5474 UNSPEC_ADD_CARRY))
5475 (set (match_dup 0)
5476 (plus:DWIH (match_dup 1) (match_dup 2)))])
5477 (parallel [(set (match_dup 3)
5478 (plus:DWIH
5479 (match_dup 4)
5480 (plus:DWIH
5481 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5482 (match_dup 5))))
5483 (clobber (reg:CC FLAGS_REG))])]
5484 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5485
5486 (define_insn "*add<mode>3_cc"
5487 [(set (reg:CC FLAGS_REG)
5488 (unspec:CC
5489 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5490 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5491 UNSPEC_ADD_CARRY))
5492 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5493 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5494 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5495 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5496 [(set_attr "type" "alu")
5497 (set_attr "mode" "<MODE>")])
5498
5499 (define_insn "addqi3_cc"
5500 [(set (reg:CC FLAGS_REG)
5501 (unspec:CC
5502 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5503 (match_operand:QI 2 "general_operand" "qn,qm")]
5504 UNSPEC_ADD_CARRY))
5505 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5506 (plus:QI (match_dup 1) (match_dup 2)))]
5507 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5508 "add{b}\t{%2, %0|%0, %2}"
5509 [(set_attr "type" "alu")
5510 (set_attr "mode" "QI")])
5511
5512 (define_insn_and_split "*lea_1"
5513 [(set (match_operand:SI 0 "register_operand" "=r")
5514 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5515 "TARGET_64BIT"
5516 "lea{l}\t{%E1, %0|%0, %E1}"
5517 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5518 [(const_int 0)]
5519 {
5520 ix86_split_lea_for_addr (operands, SImode);
5521 DONE;
5522 }
5523 [(set_attr "type" "lea")
5524 (set_attr "mode" "SI")])
5525
5526 (define_insn_and_split "*lea<mode>_2"
5527 [(set (match_operand:SWI48 0 "register_operand" "=r")
5528 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5529 ""
5530 "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
5531 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5532 [(const_int 0)]
5533 {
5534 ix86_split_lea_for_addr (operands, <MODE>mode);
5535 DONE;
5536 }
5537 [(set_attr "type" "lea")
5538 (set_attr "mode" "<MODE>")])
5539
5540 (define_insn "*lea_3_zext"
5541 [(set (match_operand:DI 0 "register_operand" "=r")
5542 (zero_extend:DI
5543 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5544 "TARGET_64BIT"
5545 "lea{l}\t{%E1, %k0|%k0, %E1}"
5546 [(set_attr "type" "lea")
5547 (set_attr "mode" "SI")])
5548
5549 (define_insn "*lea_4_zext"
5550 [(set (match_operand:DI 0 "register_operand" "=r")
5551 (zero_extend:DI
5552 (match_operand:SI 1 "lea_address_operand" "j")))]
5553 "TARGET_64BIT"
5554 "lea{l}\t{%E1, %k0|%k0, %E1}"
5555 [(set_attr "type" "lea")
5556 (set_attr "mode" "SI")])
5557
5558 (define_insn "*lea_5_zext"
5559 [(set (match_operand:DI 0 "register_operand" "=r")
5560 (and:DI
5561 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5562 (match_operand:DI 2 "const_32bit_mask" "n")))]
5563 "TARGET_64BIT"
5564 "lea{l}\t{%E1, %k0|%k0, %E1}"
5565 [(set_attr "type" "lea")
5566 (set_attr "mode" "SI")])
5567
5568 (define_insn "*lea_6_zext"
5569 [(set (match_operand:DI 0 "register_operand" "=r")
5570 (and:DI
5571 (match_operand:DI 1 "lea_address_operand" "p")
5572 (match_operand:DI 2 "const_32bit_mask" "n")))]
5573 "TARGET_64BIT"
5574 "lea{l}\t{%E1, %k0|%k0, %E1}"
5575 [(set_attr "type" "lea")
5576 (set_attr "mode" "SI")])
5577
5578 (define_insn "*add<mode>_1"
5579 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5580 (plus:SWI48
5581 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5582 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5583 (clobber (reg:CC FLAGS_REG))]
5584 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5585 {
5586 switch (get_attr_type (insn))
5587 {
5588 case TYPE_LEA:
5589 return "#";
5590
5591 case TYPE_INCDEC:
5592 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5593 if (operands[2] == const1_rtx)
5594 return "inc{<imodesuffix>}\t%0";
5595 else
5596 {
5597 gcc_assert (operands[2] == constm1_rtx);
5598 return "dec{<imodesuffix>}\t%0";
5599 }
5600
5601 default:
5602 /* For most processors, ADD is faster than LEA. This alternative
5603 was added to use ADD as much as possible. */
5604 if (which_alternative == 2)
5605 {
5606 rtx tmp;
5607 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5608 }
5609
5610 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5611 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5612 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5613
5614 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5615 }
5616 }
5617 [(set (attr "type")
5618 (cond [(eq_attr "alternative" "3")
5619 (const_string "lea")
5620 (match_operand:SWI48 2 "incdec_operand")
5621 (const_string "incdec")
5622 ]
5623 (const_string "alu")))
5624 (set (attr "length_immediate")
5625 (if_then_else
5626 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5627 (const_string "1")
5628 (const_string "*")))
5629 (set_attr "mode" "<MODE>")])
5630
5631 ;; It may seem that nonimmediate operand is proper one for operand 1.
5632 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5633 ;; we take care in ix86_binary_operator_ok to not allow two memory
5634 ;; operands so proper swapping will be done in reload. This allow
5635 ;; patterns constructed from addsi_1 to match.
5636
5637 (define_insn "addsi_1_zext"
5638 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5639 (zero_extend:DI
5640 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5641 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5642 (clobber (reg:CC FLAGS_REG))]
5643 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5644 {
5645 switch (get_attr_type (insn))
5646 {
5647 case TYPE_LEA:
5648 return "#";
5649
5650 case TYPE_INCDEC:
5651 if (operands[2] == const1_rtx)
5652 return "inc{l}\t%k0";
5653 else
5654 {
5655 gcc_assert (operands[2] == constm1_rtx);
5656 return "dec{l}\t%k0";
5657 }
5658
5659 default:
5660 /* For most processors, ADD is faster than LEA. This alternative
5661 was added to use ADD as much as possible. */
5662 if (which_alternative == 1)
5663 {
5664 rtx tmp;
5665 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5666 }
5667
5668 if (x86_maybe_negate_const_int (&operands[2], SImode))
5669 return "sub{l}\t{%2, %k0|%k0, %2}";
5670
5671 return "add{l}\t{%2, %k0|%k0, %2}";
5672 }
5673 }
5674 [(set (attr "type")
5675 (cond [(eq_attr "alternative" "2")
5676 (const_string "lea")
5677 (match_operand:SI 2 "incdec_operand")
5678 (const_string "incdec")
5679 ]
5680 (const_string "alu")))
5681 (set (attr "length_immediate")
5682 (if_then_else
5683 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5684 (const_string "1")
5685 (const_string "*")))
5686 (set_attr "mode" "SI")])
5687
5688 (define_insn "*addhi_1"
5689 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5690 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5691 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5692 (clobber (reg:CC FLAGS_REG))]
5693 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5694 {
5695 switch (get_attr_type (insn))
5696 {
5697 case TYPE_LEA:
5698 return "#";
5699
5700 case TYPE_INCDEC:
5701 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5702 if (operands[2] == const1_rtx)
5703 return "inc{w}\t%0";
5704 else
5705 {
5706 gcc_assert (operands[2] == constm1_rtx);
5707 return "dec{w}\t%0";
5708 }
5709
5710 default:
5711 /* For most processors, ADD is faster than LEA. This alternative
5712 was added to use ADD as much as possible. */
5713 if (which_alternative == 2)
5714 {
5715 rtx tmp;
5716 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5717 }
5718
5719 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5720 if (x86_maybe_negate_const_int (&operands[2], HImode))
5721 return "sub{w}\t{%2, %0|%0, %2}";
5722
5723 return "add{w}\t{%2, %0|%0, %2}";
5724 }
5725 }
5726 [(set (attr "type")
5727 (cond [(eq_attr "alternative" "3")
5728 (const_string "lea")
5729 (match_operand:HI 2 "incdec_operand")
5730 (const_string "incdec")
5731 ]
5732 (const_string "alu")))
5733 (set (attr "length_immediate")
5734 (if_then_else
5735 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5736 (const_string "1")
5737 (const_string "*")))
5738 (set_attr "mode" "HI,HI,HI,SI")])
5739
5740 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5741 (define_insn "*addqi_1"
5742 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5743 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5744 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5745 (clobber (reg:CC FLAGS_REG))]
5746 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5747 {
5748 bool widen = (which_alternative == 3 || which_alternative == 4);
5749
5750 switch (get_attr_type (insn))
5751 {
5752 case TYPE_LEA:
5753 return "#";
5754
5755 case TYPE_INCDEC:
5756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5757 if (operands[2] == const1_rtx)
5758 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5759 else
5760 {
5761 gcc_assert (operands[2] == constm1_rtx);
5762 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5763 }
5764
5765 default:
5766 /* For most processors, ADD is faster than LEA. These alternatives
5767 were added to use ADD as much as possible. */
5768 if (which_alternative == 2 || which_alternative == 4)
5769 {
5770 rtx tmp;
5771 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5772 }
5773
5774 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5775 if (x86_maybe_negate_const_int (&operands[2], QImode))
5776 {
5777 if (widen)
5778 return "sub{l}\t{%2, %k0|%k0, %2}";
5779 else
5780 return "sub{b}\t{%2, %0|%0, %2}";
5781 }
5782 if (widen)
5783 return "add{l}\t{%k2, %k0|%k0, %k2}";
5784 else
5785 return "add{b}\t{%2, %0|%0, %2}";
5786 }
5787 }
5788 [(set (attr "type")
5789 (cond [(eq_attr "alternative" "5")
5790 (const_string "lea")
5791 (match_operand:QI 2 "incdec_operand")
5792 (const_string "incdec")
5793 ]
5794 (const_string "alu")))
5795 (set (attr "length_immediate")
5796 (if_then_else
5797 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5798 (const_string "1")
5799 (const_string "*")))
5800 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5801
5802 (define_insn "*addqi_1_slp"
5803 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5804 (plus:QI (match_dup 0)
5805 (match_operand:QI 1 "general_operand" "qn,qm")))
5806 (clobber (reg:CC FLAGS_REG))]
5807 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5808 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5809 {
5810 switch (get_attr_type (insn))
5811 {
5812 case TYPE_INCDEC:
5813 if (operands[1] == const1_rtx)
5814 return "inc{b}\t%0";
5815 else
5816 {
5817 gcc_assert (operands[1] == constm1_rtx);
5818 return "dec{b}\t%0";
5819 }
5820
5821 default:
5822 if (x86_maybe_negate_const_int (&operands[1], QImode))
5823 return "sub{b}\t{%1, %0|%0, %1}";
5824
5825 return "add{b}\t{%1, %0|%0, %1}";
5826 }
5827 }
5828 [(set (attr "type")
5829 (if_then_else (match_operand:QI 1 "incdec_operand")
5830 (const_string "incdec")
5831 (const_string "alu1")))
5832 (set (attr "memory")
5833 (if_then_else (match_operand 1 "memory_operand")
5834 (const_string "load")
5835 (const_string "none")))
5836 (set_attr "mode" "QI")])
5837
5838 ;; Split non destructive adds if we cannot use lea.
5839 (define_split
5840 [(set (match_operand:SWI48 0 "register_operand")
5841 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5842 (match_operand:SWI48 2 "nonmemory_operand")))
5843 (clobber (reg:CC FLAGS_REG))]
5844 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5845 [(set (match_dup 0) (match_dup 1))
5846 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5847 (clobber (reg:CC FLAGS_REG))])])
5848
5849 ;; Convert add to the lea pattern to avoid flags dependency.
5850 (define_split
5851 [(set (match_operand:SWI 0 "register_operand")
5852 (plus:SWI (match_operand:SWI 1 "register_operand")
5853 (match_operand:SWI 2 "<nonmemory_operand>")))
5854 (clobber (reg:CC FLAGS_REG))]
5855 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5856 [(const_int 0)]
5857 {
5858 enum machine_mode mode = <MODE>mode;
5859 rtx pat;
5860
5861 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5862 {
5863 mode = SImode;
5864 operands[0] = gen_lowpart (mode, operands[0]);
5865 operands[1] = gen_lowpart (mode, operands[1]);
5866 operands[2] = gen_lowpart (mode, operands[2]);
5867 }
5868
5869 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5870
5871 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5872 DONE;
5873 })
5874
5875 ;; Convert add to the lea pattern to avoid flags dependency.
5876 (define_split
5877 [(set (match_operand:DI 0 "register_operand")
5878 (zero_extend:DI
5879 (plus:SI (match_operand:SI 1 "register_operand")
5880 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5881 (clobber (reg:CC FLAGS_REG))]
5882 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5883 [(set (match_dup 0)
5884 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5885
5886 (define_insn "*add<mode>_2"
5887 [(set (reg FLAGS_REG)
5888 (compare
5889 (plus:SWI
5890 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5891 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5892 (const_int 0)))
5893 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5894 (plus:SWI (match_dup 1) (match_dup 2)))]
5895 "ix86_match_ccmode (insn, CCGOCmode)
5896 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5897 {
5898 switch (get_attr_type (insn))
5899 {
5900 case TYPE_INCDEC:
5901 if (operands[2] == const1_rtx)
5902 return "inc{<imodesuffix>}\t%0";
5903 else
5904 {
5905 gcc_assert (operands[2] == constm1_rtx);
5906 return "dec{<imodesuffix>}\t%0";
5907 }
5908
5909 default:
5910 if (which_alternative == 2)
5911 {
5912 rtx tmp;
5913 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5914 }
5915
5916 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5917 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5918 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5919
5920 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5921 }
5922 }
5923 [(set (attr "type")
5924 (if_then_else (match_operand:SWI 2 "incdec_operand")
5925 (const_string "incdec")
5926 (const_string "alu")))
5927 (set (attr "length_immediate")
5928 (if_then_else
5929 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5930 (const_string "1")
5931 (const_string "*")))
5932 (set_attr "mode" "<MODE>")])
5933
5934 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5935 (define_insn "*addsi_2_zext"
5936 [(set (reg FLAGS_REG)
5937 (compare
5938 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5939 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5940 (const_int 0)))
5941 (set (match_operand:DI 0 "register_operand" "=r,r")
5942 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5943 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5944 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5945 {
5946 switch (get_attr_type (insn))
5947 {
5948 case TYPE_INCDEC:
5949 if (operands[2] == const1_rtx)
5950 return "inc{l}\t%k0";
5951 else
5952 {
5953 gcc_assert (operands[2] == constm1_rtx);
5954 return "dec{l}\t%k0";
5955 }
5956
5957 default:
5958 if (which_alternative == 1)
5959 {
5960 rtx tmp;
5961 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5962 }
5963
5964 if (x86_maybe_negate_const_int (&operands[2], SImode))
5965 return "sub{l}\t{%2, %k0|%k0, %2}";
5966
5967 return "add{l}\t{%2, %k0|%k0, %2}";
5968 }
5969 }
5970 [(set (attr "type")
5971 (if_then_else (match_operand:SI 2 "incdec_operand")
5972 (const_string "incdec")
5973 (const_string "alu")))
5974 (set (attr "length_immediate")
5975 (if_then_else
5976 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5977 (const_string "1")
5978 (const_string "*")))
5979 (set_attr "mode" "SI")])
5980
5981 (define_insn "*add<mode>_3"
5982 [(set (reg FLAGS_REG)
5983 (compare
5984 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5985 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5986 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5987 "ix86_match_ccmode (insn, CCZmode)
5988 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5989 {
5990 switch (get_attr_type (insn))
5991 {
5992 case TYPE_INCDEC:
5993 if (operands[2] == const1_rtx)
5994 return "inc{<imodesuffix>}\t%0";
5995 else
5996 {
5997 gcc_assert (operands[2] == constm1_rtx);
5998 return "dec{<imodesuffix>}\t%0";
5999 }
6000
6001 default:
6002 if (which_alternative == 1)
6003 {
6004 rtx tmp;
6005 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6006 }
6007
6008 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6009 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6010 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6011
6012 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6013 }
6014 }
6015 [(set (attr "type")
6016 (if_then_else (match_operand:SWI 2 "incdec_operand")
6017 (const_string "incdec")
6018 (const_string "alu")))
6019 (set (attr "length_immediate")
6020 (if_then_else
6021 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6022 (const_string "1")
6023 (const_string "*")))
6024 (set_attr "mode" "<MODE>")])
6025
6026 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6027 (define_insn "*addsi_3_zext"
6028 [(set (reg FLAGS_REG)
6029 (compare
6030 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6031 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6032 (set (match_operand:DI 0 "register_operand" "=r,r")
6033 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6034 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6035 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6036 {
6037 switch (get_attr_type (insn))
6038 {
6039 case TYPE_INCDEC:
6040 if (operands[2] == const1_rtx)
6041 return "inc{l}\t%k0";
6042 else
6043 {
6044 gcc_assert (operands[2] == constm1_rtx);
6045 return "dec{l}\t%k0";
6046 }
6047
6048 default:
6049 if (which_alternative == 1)
6050 {
6051 rtx tmp;
6052 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6053 }
6054
6055 if (x86_maybe_negate_const_int (&operands[2], SImode))
6056 return "sub{l}\t{%2, %k0|%k0, %2}";
6057
6058 return "add{l}\t{%2, %k0|%k0, %2}";
6059 }
6060 }
6061 [(set (attr "type")
6062 (if_then_else (match_operand:SI 2 "incdec_operand")
6063 (const_string "incdec")
6064 (const_string "alu")))
6065 (set (attr "length_immediate")
6066 (if_then_else
6067 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6068 (const_string "1")
6069 (const_string "*")))
6070 (set_attr "mode" "SI")])
6071
6072 ; For comparisons against 1, -1 and 128, we may generate better code
6073 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6074 ; is matched then. We can't accept general immediate, because for
6075 ; case of overflows, the result is messed up.
6076 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6077 ; only for comparisons not depending on it.
6078
6079 (define_insn "*adddi_4"
6080 [(set (reg FLAGS_REG)
6081 (compare
6082 (match_operand:DI 1 "nonimmediate_operand" "0")
6083 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6084 (clobber (match_scratch:DI 0 "=rm"))]
6085 "TARGET_64BIT
6086 && ix86_match_ccmode (insn, CCGCmode)"
6087 {
6088 switch (get_attr_type (insn))
6089 {
6090 case TYPE_INCDEC:
6091 if (operands[2] == constm1_rtx)
6092 return "inc{q}\t%0";
6093 else
6094 {
6095 gcc_assert (operands[2] == const1_rtx);
6096 return "dec{q}\t%0";
6097 }
6098
6099 default:
6100 if (x86_maybe_negate_const_int (&operands[2], DImode))
6101 return "add{q}\t{%2, %0|%0, %2}";
6102
6103 return "sub{q}\t{%2, %0|%0, %2}";
6104 }
6105 }
6106 [(set (attr "type")
6107 (if_then_else (match_operand:DI 2 "incdec_operand")
6108 (const_string "incdec")
6109 (const_string "alu")))
6110 (set (attr "length_immediate")
6111 (if_then_else
6112 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6113 (const_string "1")
6114 (const_string "*")))
6115 (set_attr "mode" "DI")])
6116
6117 ; For comparisons against 1, -1 and 128, we may generate better code
6118 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6119 ; is matched then. We can't accept general immediate, because for
6120 ; case of overflows, the result is messed up.
6121 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6122 ; only for comparisons not depending on it.
6123
6124 (define_insn "*add<mode>_4"
6125 [(set (reg FLAGS_REG)
6126 (compare
6127 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6128 (match_operand:SWI124 2 "const_int_operand" "n")))
6129 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6130 "ix86_match_ccmode (insn, CCGCmode)"
6131 {
6132 switch (get_attr_type (insn))
6133 {
6134 case TYPE_INCDEC:
6135 if (operands[2] == constm1_rtx)
6136 return "inc{<imodesuffix>}\t%0";
6137 else
6138 {
6139 gcc_assert (operands[2] == const1_rtx);
6140 return "dec{<imodesuffix>}\t%0";
6141 }
6142
6143 default:
6144 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6145 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6146
6147 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6148 }
6149 }
6150 [(set (attr "type")
6151 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6152 (const_string "incdec")
6153 (const_string "alu")))
6154 (set (attr "length_immediate")
6155 (if_then_else
6156 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6157 (const_string "1")
6158 (const_string "*")))
6159 (set_attr "mode" "<MODE>")])
6160
6161 (define_insn "*add<mode>_5"
6162 [(set (reg FLAGS_REG)
6163 (compare
6164 (plus:SWI
6165 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6166 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6167 (const_int 0)))
6168 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6169 "ix86_match_ccmode (insn, CCGOCmode)
6170 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6171 {
6172 switch (get_attr_type (insn))
6173 {
6174 case TYPE_INCDEC:
6175 if (operands[2] == const1_rtx)
6176 return "inc{<imodesuffix>}\t%0";
6177 else
6178 {
6179 gcc_assert (operands[2] == constm1_rtx);
6180 return "dec{<imodesuffix>}\t%0";
6181 }
6182
6183 default:
6184 if (which_alternative == 1)
6185 {
6186 rtx tmp;
6187 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6188 }
6189
6190 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6191 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6192 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6193
6194 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6195 }
6196 }
6197 [(set (attr "type")
6198 (if_then_else (match_operand:SWI 2 "incdec_operand")
6199 (const_string "incdec")
6200 (const_string "alu")))
6201 (set (attr "length_immediate")
6202 (if_then_else
6203 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6204 (const_string "1")
6205 (const_string "*")))
6206 (set_attr "mode" "<MODE>")])
6207
6208 (define_insn "*addqi_ext_1_rex64"
6209 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6210 (const_int 8)
6211 (const_int 8))
6212 (plus:SI
6213 (zero_extract:SI
6214 (match_operand 1 "ext_register_operand" "0")
6215 (const_int 8)
6216 (const_int 8))
6217 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6218 (clobber (reg:CC FLAGS_REG))]
6219 "TARGET_64BIT"
6220 {
6221 switch (get_attr_type (insn))
6222 {
6223 case TYPE_INCDEC:
6224 if (operands[2] == const1_rtx)
6225 return "inc{b}\t%h0";
6226 else
6227 {
6228 gcc_assert (operands[2] == constm1_rtx);
6229 return "dec{b}\t%h0";
6230 }
6231
6232 default:
6233 return "add{b}\t{%2, %h0|%h0, %2}";
6234 }
6235 }
6236 [(set (attr "type")
6237 (if_then_else (match_operand:QI 2 "incdec_operand")
6238 (const_string "incdec")
6239 (const_string "alu")))
6240 (set_attr "modrm" "1")
6241 (set_attr "mode" "QI")])
6242
6243 (define_insn "addqi_ext_1"
6244 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6245 (const_int 8)
6246 (const_int 8))
6247 (plus:SI
6248 (zero_extract:SI
6249 (match_operand 1 "ext_register_operand" "0")
6250 (const_int 8)
6251 (const_int 8))
6252 (match_operand:QI 2 "general_operand" "Qmn")))
6253 (clobber (reg:CC FLAGS_REG))]
6254 "!TARGET_64BIT"
6255 {
6256 switch (get_attr_type (insn))
6257 {
6258 case TYPE_INCDEC:
6259 if (operands[2] == const1_rtx)
6260 return "inc{b}\t%h0";
6261 else
6262 {
6263 gcc_assert (operands[2] == constm1_rtx);
6264 return "dec{b}\t%h0";
6265 }
6266
6267 default:
6268 return "add{b}\t{%2, %h0|%h0, %2}";
6269 }
6270 }
6271 [(set (attr "type")
6272 (if_then_else (match_operand:QI 2 "incdec_operand")
6273 (const_string "incdec")
6274 (const_string "alu")))
6275 (set_attr "modrm" "1")
6276 (set_attr "mode" "QI")])
6277
6278 (define_insn "*addqi_ext_2"
6279 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6280 (const_int 8)
6281 (const_int 8))
6282 (plus:SI
6283 (zero_extract:SI
6284 (match_operand 1 "ext_register_operand" "%0")
6285 (const_int 8)
6286 (const_int 8))
6287 (zero_extract:SI
6288 (match_operand 2 "ext_register_operand" "Q")
6289 (const_int 8)
6290 (const_int 8))))
6291 (clobber (reg:CC FLAGS_REG))]
6292 ""
6293 "add{b}\t{%h2, %h0|%h0, %h2}"
6294 [(set_attr "type" "alu")
6295 (set_attr "mode" "QI")])
6296
6297 ;; The lea patterns for modes less than 32 bits need to be matched by
6298 ;; several insns converted to real lea by splitters.
6299
6300 (define_insn_and_split "*lea_general_1"
6301 [(set (match_operand 0 "register_operand" "=r")
6302 (plus (plus (match_operand 1 "index_register_operand" "l")
6303 (match_operand 2 "register_operand" "r"))
6304 (match_operand 3 "immediate_operand" "i")))]
6305 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6306 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6307 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6308 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6309 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6310 || GET_MODE (operands[3]) == VOIDmode)"
6311 "#"
6312 "&& reload_completed"
6313 [(const_int 0)]
6314 {
6315 enum machine_mode mode = SImode;
6316 rtx pat;
6317
6318 operands[0] = gen_lowpart (mode, operands[0]);
6319 operands[1] = gen_lowpart (mode, operands[1]);
6320 operands[2] = gen_lowpart (mode, operands[2]);
6321 operands[3] = gen_lowpart (mode, operands[3]);
6322
6323 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6324 operands[3]);
6325
6326 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6327 DONE;
6328 }
6329 [(set_attr "type" "lea")
6330 (set_attr "mode" "SI")])
6331
6332 (define_insn_and_split "*lea_general_2"
6333 [(set (match_operand 0 "register_operand" "=r")
6334 (plus (mult (match_operand 1 "index_register_operand" "l")
6335 (match_operand 2 "const248_operand" "n"))
6336 (match_operand 3 "nonmemory_operand" "ri")))]
6337 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6338 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6339 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6340 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6341 || GET_MODE (operands[3]) == VOIDmode)"
6342 "#"
6343 "&& reload_completed"
6344 [(const_int 0)]
6345 {
6346 enum machine_mode mode = SImode;
6347 rtx pat;
6348
6349 operands[0] = gen_lowpart (mode, operands[0]);
6350 operands[1] = gen_lowpart (mode, operands[1]);
6351 operands[3] = gen_lowpart (mode, operands[3]);
6352
6353 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6354 operands[3]);
6355
6356 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6357 DONE;
6358 }
6359 [(set_attr "type" "lea")
6360 (set_attr "mode" "SI")])
6361
6362 (define_insn_and_split "*lea_general_3"
6363 [(set (match_operand 0 "register_operand" "=r")
6364 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6365 (match_operand 2 "const248_operand" "n"))
6366 (match_operand 3 "register_operand" "r"))
6367 (match_operand 4 "immediate_operand" "i")))]
6368 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6369 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6370 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6371 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6372 "#"
6373 "&& reload_completed"
6374 [(const_int 0)]
6375 {
6376 enum machine_mode mode = SImode;
6377 rtx pat;
6378
6379 operands[0] = gen_lowpart (mode, operands[0]);
6380 operands[1] = gen_lowpart (mode, operands[1]);
6381 operands[3] = gen_lowpart (mode, operands[3]);
6382 operands[4] = gen_lowpart (mode, operands[4]);
6383
6384 pat = gen_rtx_PLUS (mode,
6385 gen_rtx_PLUS (mode,
6386 gen_rtx_MULT (mode, operands[1],
6387 operands[2]),
6388 operands[3]),
6389 operands[4]);
6390
6391 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6392 DONE;
6393 }
6394 [(set_attr "type" "lea")
6395 (set_attr "mode" "SI")])
6396
6397 (define_insn_and_split "*lea_general_4"
6398 [(set (match_operand 0 "register_operand" "=r")
6399 (any_or (ashift
6400 (match_operand 1 "index_register_operand" "l")
6401 (match_operand 2 "const_int_operand" "n"))
6402 (match_operand 3 "const_int_operand" "n")))]
6403 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6404 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6405 || GET_MODE (operands[0]) == SImode
6406 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6407 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6408 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6409 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6410 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6411 "#"
6412 "&& reload_completed"
6413 [(const_int 0)]
6414 {
6415 enum machine_mode mode = GET_MODE (operands[0]);
6416 rtx pat;
6417
6418 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6419 {
6420 mode = SImode;
6421 operands[0] = gen_lowpart (mode, operands[0]);
6422 operands[1] = gen_lowpart (mode, operands[1]);
6423 }
6424
6425 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6426
6427 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6428 INTVAL (operands[3]));
6429
6430 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6431 DONE;
6432 }
6433 [(set_attr "type" "lea")
6434 (set (attr "mode")
6435 (if_then_else (match_operand:DI 0)
6436 (const_string "DI")
6437 (const_string "SI")))])
6438 \f
6439 ;; Subtract instructions
6440
6441 (define_expand "sub<mode>3"
6442 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6443 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6444 (match_operand:SDWIM 2 "<general_operand>")))]
6445 ""
6446 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6447
6448 (define_insn_and_split "*sub<dwi>3_doubleword"
6449 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6450 (minus:<DWI>
6451 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6452 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6453 (clobber (reg:CC FLAGS_REG))]
6454 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6455 "#"
6456 "reload_completed"
6457 [(parallel [(set (reg:CC FLAGS_REG)
6458 (compare:CC (match_dup 1) (match_dup 2)))
6459 (set (match_dup 0)
6460 (minus:DWIH (match_dup 1) (match_dup 2)))])
6461 (parallel [(set (match_dup 3)
6462 (minus:DWIH
6463 (match_dup 4)
6464 (plus:DWIH
6465 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6466 (match_dup 5))))
6467 (clobber (reg:CC FLAGS_REG))])]
6468 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6469
6470 (define_insn "*sub<mode>_1"
6471 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6472 (minus:SWI
6473 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6474 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6475 (clobber (reg:CC FLAGS_REG))]
6476 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6477 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6478 [(set_attr "type" "alu")
6479 (set_attr "mode" "<MODE>")])
6480
6481 (define_insn "*subsi_1_zext"
6482 [(set (match_operand:DI 0 "register_operand" "=r")
6483 (zero_extend:DI
6484 (minus:SI (match_operand:SI 1 "register_operand" "0")
6485 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6486 (clobber (reg:CC FLAGS_REG))]
6487 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6488 "sub{l}\t{%2, %k0|%k0, %2}"
6489 [(set_attr "type" "alu")
6490 (set_attr "mode" "SI")])
6491
6492 (define_insn "*subqi_1_slp"
6493 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6494 (minus:QI (match_dup 0)
6495 (match_operand:QI 1 "general_operand" "qn,qm")))
6496 (clobber (reg:CC FLAGS_REG))]
6497 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6498 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6499 "sub{b}\t{%1, %0|%0, %1}"
6500 [(set_attr "type" "alu1")
6501 (set_attr "mode" "QI")])
6502
6503 (define_insn "*sub<mode>_2"
6504 [(set (reg FLAGS_REG)
6505 (compare
6506 (minus:SWI
6507 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6508 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6509 (const_int 0)))
6510 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6511 (minus:SWI (match_dup 1) (match_dup 2)))]
6512 "ix86_match_ccmode (insn, CCGOCmode)
6513 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6514 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6515 [(set_attr "type" "alu")
6516 (set_attr "mode" "<MODE>")])
6517
6518 (define_insn "*subsi_2_zext"
6519 [(set (reg FLAGS_REG)
6520 (compare
6521 (minus:SI (match_operand:SI 1 "register_operand" "0")
6522 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6523 (const_int 0)))
6524 (set (match_operand:DI 0 "register_operand" "=r")
6525 (zero_extend:DI
6526 (minus:SI (match_dup 1)
6527 (match_dup 2))))]
6528 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6529 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6530 "sub{l}\t{%2, %k0|%k0, %2}"
6531 [(set_attr "type" "alu")
6532 (set_attr "mode" "SI")])
6533
6534 (define_insn "*sub<mode>_3"
6535 [(set (reg FLAGS_REG)
6536 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6537 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6538 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6539 (minus:SWI (match_dup 1) (match_dup 2)))]
6540 "ix86_match_ccmode (insn, CCmode)
6541 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6542 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6543 [(set_attr "type" "alu")
6544 (set_attr "mode" "<MODE>")])
6545
6546 (define_insn "*subsi_3_zext"
6547 [(set (reg FLAGS_REG)
6548 (compare (match_operand:SI 1 "register_operand" "0")
6549 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6550 (set (match_operand:DI 0 "register_operand" "=r")
6551 (zero_extend:DI
6552 (minus:SI (match_dup 1)
6553 (match_dup 2))))]
6554 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6555 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6556 "sub{l}\t{%2, %1|%1, %2}"
6557 [(set_attr "type" "alu")
6558 (set_attr "mode" "SI")])
6559 \f
6560 ;; Add with carry and subtract with borrow
6561
6562 (define_expand "<plusminus_insn><mode>3_carry"
6563 [(parallel
6564 [(set (match_operand:SWI 0 "nonimmediate_operand")
6565 (plusminus:SWI
6566 (match_operand:SWI 1 "nonimmediate_operand")
6567 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6568 [(match_operand 3 "flags_reg_operand")
6569 (const_int 0)])
6570 (match_operand:SWI 2 "<general_operand>"))))
6571 (clobber (reg:CC FLAGS_REG))])]
6572 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6573
6574 (define_insn "*<plusminus_insn><mode>3_carry"
6575 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6576 (plusminus:SWI
6577 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6578 (plus:SWI
6579 (match_operator 3 "ix86_carry_flag_operator"
6580 [(reg FLAGS_REG) (const_int 0)])
6581 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6582 (clobber (reg:CC FLAGS_REG))]
6583 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6584 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6585 [(set_attr "type" "alu")
6586 (set_attr "use_carry" "1")
6587 (set_attr "pent_pair" "pu")
6588 (set_attr "mode" "<MODE>")])
6589
6590 (define_insn "*addsi3_carry_zext"
6591 [(set (match_operand:DI 0 "register_operand" "=r")
6592 (zero_extend:DI
6593 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6594 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6595 [(reg FLAGS_REG) (const_int 0)])
6596 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6597 (clobber (reg:CC FLAGS_REG))]
6598 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6599 "adc{l}\t{%2, %k0|%k0, %2}"
6600 [(set_attr "type" "alu")
6601 (set_attr "use_carry" "1")
6602 (set_attr "pent_pair" "pu")
6603 (set_attr "mode" "SI")])
6604
6605 (define_insn "*subsi3_carry_zext"
6606 [(set (match_operand:DI 0 "register_operand" "=r")
6607 (zero_extend:DI
6608 (minus:SI (match_operand:SI 1 "register_operand" "0")
6609 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6610 [(reg FLAGS_REG) (const_int 0)])
6611 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6612 (clobber (reg:CC FLAGS_REG))]
6613 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6614 "sbb{l}\t{%2, %k0|%k0, %2}"
6615 [(set_attr "type" "alu")
6616 (set_attr "pent_pair" "pu")
6617 (set_attr "mode" "SI")])
6618 \f
6619 ;; Overflow setting add and subtract instructions
6620
6621 (define_insn "*add<mode>3_cconly_overflow"
6622 [(set (reg:CCC FLAGS_REG)
6623 (compare:CCC
6624 (plus:SWI
6625 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6626 (match_operand:SWI 2 "<general_operand>" "<g>"))
6627 (match_dup 1)))
6628 (clobber (match_scratch:SWI 0 "=<r>"))]
6629 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6630 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6631 [(set_attr "type" "alu")
6632 (set_attr "mode" "<MODE>")])
6633
6634 (define_insn "*sub<mode>3_cconly_overflow"
6635 [(set (reg:CCC FLAGS_REG)
6636 (compare:CCC
6637 (minus:SWI
6638 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6639 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6640 (match_dup 0)))]
6641 ""
6642 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6643 [(set_attr "type" "icmp")
6644 (set_attr "mode" "<MODE>")])
6645
6646 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6647 [(set (reg:CCC FLAGS_REG)
6648 (compare:CCC
6649 (plusminus:SWI
6650 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6651 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6652 (match_dup 1)))
6653 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6654 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6655 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6656 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6657 [(set_attr "type" "alu")
6658 (set_attr "mode" "<MODE>")])
6659
6660 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6661 [(set (reg:CCC FLAGS_REG)
6662 (compare:CCC
6663 (plusminus:SI
6664 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6665 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6666 (match_dup 1)))
6667 (set (match_operand:DI 0 "register_operand" "=r")
6668 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6669 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6670 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6671 [(set_attr "type" "alu")
6672 (set_attr "mode" "SI")])
6673
6674 ;; The patterns that match these are at the end of this file.
6675
6676 (define_expand "<plusminus_insn>xf3"
6677 [(set (match_operand:XF 0 "register_operand")
6678 (plusminus:XF
6679 (match_operand:XF 1 "register_operand")
6680 (match_operand:XF 2 "register_operand")))]
6681 "TARGET_80387")
6682
6683 (define_expand "<plusminus_insn><mode>3"
6684 [(set (match_operand:MODEF 0 "register_operand")
6685 (plusminus:MODEF
6686 (match_operand:MODEF 1 "register_operand")
6687 (match_operand:MODEF 2 "nonimmediate_operand")))]
6688 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6689 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6690 \f
6691 ;; Multiply instructions
6692
6693 (define_expand "mul<mode>3"
6694 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6695 (mult:SWIM248
6696 (match_operand:SWIM248 1 "register_operand")
6697 (match_operand:SWIM248 2 "<general_operand>")))
6698 (clobber (reg:CC FLAGS_REG))])])
6699
6700 (define_expand "mulqi3"
6701 [(parallel [(set (match_operand:QI 0 "register_operand")
6702 (mult:QI
6703 (match_operand:QI 1 "register_operand")
6704 (match_operand:QI 2 "nonimmediate_operand")))
6705 (clobber (reg:CC FLAGS_REG))])]
6706 "TARGET_QIMODE_MATH")
6707
6708 ;; On AMDFAM10
6709 ;; IMUL reg32/64, reg32/64, imm8 Direct
6710 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6711 ;; IMUL reg32/64, reg32/64, imm32 Direct
6712 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6713 ;; IMUL reg32/64, reg32/64 Direct
6714 ;; IMUL reg32/64, mem32/64 Direct
6715 ;;
6716 ;; On BDVER1, all above IMULs use DirectPath
6717
6718 (define_insn "*mul<mode>3_1"
6719 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6720 (mult:SWI48
6721 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6722 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6723 (clobber (reg:CC FLAGS_REG))]
6724 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6725 "@
6726 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6727 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6728 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6729 [(set_attr "type" "imul")
6730 (set_attr "prefix_0f" "0,0,1")
6731 (set (attr "athlon_decode")
6732 (cond [(eq_attr "cpu" "athlon")
6733 (const_string "vector")
6734 (eq_attr "alternative" "1")
6735 (const_string "vector")
6736 (and (eq_attr "alternative" "2")
6737 (match_operand 1 "memory_operand"))
6738 (const_string "vector")]
6739 (const_string "direct")))
6740 (set (attr "amdfam10_decode")
6741 (cond [(and (eq_attr "alternative" "0,1")
6742 (match_operand 1 "memory_operand"))
6743 (const_string "vector")]
6744 (const_string "direct")))
6745 (set_attr "bdver1_decode" "direct")
6746 (set_attr "mode" "<MODE>")])
6747
6748 (define_insn "*mulsi3_1_zext"
6749 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6750 (zero_extend:DI
6751 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6752 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6753 (clobber (reg:CC FLAGS_REG))]
6754 "TARGET_64BIT
6755 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6756 "@
6757 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6758 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6759 imul{l}\t{%2, %k0|%k0, %2}"
6760 [(set_attr "type" "imul")
6761 (set_attr "prefix_0f" "0,0,1")
6762 (set (attr "athlon_decode")
6763 (cond [(eq_attr "cpu" "athlon")
6764 (const_string "vector")
6765 (eq_attr "alternative" "1")
6766 (const_string "vector")
6767 (and (eq_attr "alternative" "2")
6768 (match_operand 1 "memory_operand"))
6769 (const_string "vector")]
6770 (const_string "direct")))
6771 (set (attr "amdfam10_decode")
6772 (cond [(and (eq_attr "alternative" "0,1")
6773 (match_operand 1 "memory_operand"))
6774 (const_string "vector")]
6775 (const_string "direct")))
6776 (set_attr "bdver1_decode" "direct")
6777 (set_attr "mode" "SI")])
6778
6779 ;; On AMDFAM10
6780 ;; IMUL reg16, reg16, imm8 VectorPath
6781 ;; IMUL reg16, mem16, imm8 VectorPath
6782 ;; IMUL reg16, reg16, imm16 VectorPath
6783 ;; IMUL reg16, mem16, imm16 VectorPath
6784 ;; IMUL reg16, reg16 Direct
6785 ;; IMUL reg16, mem16 Direct
6786 ;;
6787 ;; On BDVER1, all HI MULs use DoublePath
6788
6789 (define_insn "*mulhi3_1"
6790 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6791 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6792 (match_operand:HI 2 "general_operand" "K,n,mr")))
6793 (clobber (reg:CC FLAGS_REG))]
6794 "TARGET_HIMODE_MATH
6795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796 "@
6797 imul{w}\t{%2, %1, %0|%0, %1, %2}
6798 imul{w}\t{%2, %1, %0|%0, %1, %2}
6799 imul{w}\t{%2, %0|%0, %2}"
6800 [(set_attr "type" "imul")
6801 (set_attr "prefix_0f" "0,0,1")
6802 (set (attr "athlon_decode")
6803 (cond [(eq_attr "cpu" "athlon")
6804 (const_string "vector")
6805 (eq_attr "alternative" "1,2")
6806 (const_string "vector")]
6807 (const_string "direct")))
6808 (set (attr "amdfam10_decode")
6809 (cond [(eq_attr "alternative" "0,1")
6810 (const_string "vector")]
6811 (const_string "direct")))
6812 (set_attr "bdver1_decode" "double")
6813 (set_attr "mode" "HI")])
6814
6815 ;;On AMDFAM10 and BDVER1
6816 ;; MUL reg8 Direct
6817 ;; MUL mem8 Direct
6818
6819 (define_insn "*mulqi3_1"
6820 [(set (match_operand:QI 0 "register_operand" "=a")
6821 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6822 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6823 (clobber (reg:CC FLAGS_REG))]
6824 "TARGET_QIMODE_MATH
6825 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6826 "mul{b}\t%2"
6827 [(set_attr "type" "imul")
6828 (set_attr "length_immediate" "0")
6829 (set (attr "athlon_decode")
6830 (if_then_else (eq_attr "cpu" "athlon")
6831 (const_string "vector")
6832 (const_string "direct")))
6833 (set_attr "amdfam10_decode" "direct")
6834 (set_attr "bdver1_decode" "direct")
6835 (set_attr "mode" "QI")])
6836
6837 (define_expand "<u>mul<mode><dwi>3"
6838 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6839 (mult:<DWI>
6840 (any_extend:<DWI>
6841 (match_operand:DWIH 1 "nonimmediate_operand"))
6842 (any_extend:<DWI>
6843 (match_operand:DWIH 2 "register_operand"))))
6844 (clobber (reg:CC FLAGS_REG))])])
6845
6846 (define_expand "<u>mulqihi3"
6847 [(parallel [(set (match_operand:HI 0 "register_operand")
6848 (mult:HI
6849 (any_extend:HI
6850 (match_operand:QI 1 "nonimmediate_operand"))
6851 (any_extend:HI
6852 (match_operand:QI 2 "register_operand"))))
6853 (clobber (reg:CC FLAGS_REG))])]
6854 "TARGET_QIMODE_MATH")
6855
6856 (define_insn "*bmi2_umulditi3_1"
6857 [(set (match_operand:DI 0 "register_operand" "=r")
6858 (mult:DI
6859 (match_operand:DI 2 "nonimmediate_operand" "%d")
6860 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6861 (set (match_operand:DI 1 "register_operand" "=r")
6862 (truncate:DI
6863 (lshiftrt:TI
6864 (mult:TI (zero_extend:TI (match_dup 2))
6865 (zero_extend:TI (match_dup 3)))
6866 (const_int 64))))]
6867 "TARGET_64BIT && TARGET_BMI2
6868 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6869 "mulx\t{%3, %0, %1|%1, %0, %3}"
6870 [(set_attr "type" "imulx")
6871 (set_attr "prefix" "vex")
6872 (set_attr "mode" "DI")])
6873
6874 (define_insn "*bmi2_umulsidi3_1"
6875 [(set (match_operand:SI 0 "register_operand" "=r")
6876 (mult:SI
6877 (match_operand:SI 2 "nonimmediate_operand" "%d")
6878 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6879 (set (match_operand:SI 1 "register_operand" "=r")
6880 (truncate:SI
6881 (lshiftrt:DI
6882 (mult:DI (zero_extend:DI (match_dup 2))
6883 (zero_extend:DI (match_dup 3)))
6884 (const_int 32))))]
6885 "!TARGET_64BIT && TARGET_BMI2
6886 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6887 "mulx\t{%3, %0, %1|%1, %0, %3}"
6888 [(set_attr "type" "imulx")
6889 (set_attr "prefix" "vex")
6890 (set_attr "mode" "SI")])
6891
6892 (define_insn "*umul<mode><dwi>3_1"
6893 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6894 (mult:<DWI>
6895 (zero_extend:<DWI>
6896 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6897 (zero_extend:<DWI>
6898 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6899 (clobber (reg:CC FLAGS_REG))]
6900 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6901 "@
6902 #
6903 mul{<imodesuffix>}\t%2"
6904 [(set_attr "isa" "bmi2,*")
6905 (set_attr "type" "imulx,imul")
6906 (set_attr "length_immediate" "*,0")
6907 (set (attr "athlon_decode")
6908 (cond [(eq_attr "alternative" "1")
6909 (if_then_else (eq_attr "cpu" "athlon")
6910 (const_string "vector")
6911 (const_string "double"))]
6912 (const_string "*")))
6913 (set_attr "amdfam10_decode" "*,double")
6914 (set_attr "bdver1_decode" "*,direct")
6915 (set_attr "prefix" "vex,orig")
6916 (set_attr "mode" "<MODE>")])
6917
6918 ;; Convert mul to the mulx pattern to avoid flags dependency.
6919 (define_split
6920 [(set (match_operand:<DWI> 0 "register_operand")
6921 (mult:<DWI>
6922 (zero_extend:<DWI>
6923 (match_operand:DWIH 1 "register_operand"))
6924 (zero_extend:<DWI>
6925 (match_operand:DWIH 2 "nonimmediate_operand"))))
6926 (clobber (reg:CC FLAGS_REG))]
6927 "TARGET_BMI2 && reload_completed
6928 && true_regnum (operands[1]) == DX_REG"
6929 [(parallel [(set (match_dup 3)
6930 (mult:DWIH (match_dup 1) (match_dup 2)))
6931 (set (match_dup 4)
6932 (truncate:DWIH
6933 (lshiftrt:<DWI>
6934 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6935 (zero_extend:<DWI> (match_dup 2)))
6936 (match_dup 5))))])]
6937 {
6938 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6939
6940 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6941 })
6942
6943 (define_insn "*mul<mode><dwi>3_1"
6944 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6945 (mult:<DWI>
6946 (sign_extend:<DWI>
6947 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6948 (sign_extend:<DWI>
6949 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6950 (clobber (reg:CC FLAGS_REG))]
6951 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6952 "imul{<imodesuffix>}\t%2"
6953 [(set_attr "type" "imul")
6954 (set_attr "length_immediate" "0")
6955 (set (attr "athlon_decode")
6956 (if_then_else (eq_attr "cpu" "athlon")
6957 (const_string "vector")
6958 (const_string "double")))
6959 (set_attr "amdfam10_decode" "double")
6960 (set_attr "bdver1_decode" "direct")
6961 (set_attr "mode" "<MODE>")])
6962
6963 (define_insn "*<u>mulqihi3_1"
6964 [(set (match_operand:HI 0 "register_operand" "=a")
6965 (mult:HI
6966 (any_extend:HI
6967 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6968 (any_extend:HI
6969 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6970 (clobber (reg:CC FLAGS_REG))]
6971 "TARGET_QIMODE_MATH
6972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6973 "<sgnprefix>mul{b}\t%2"
6974 [(set_attr "type" "imul")
6975 (set_attr "length_immediate" "0")
6976 (set (attr "athlon_decode")
6977 (if_then_else (eq_attr "cpu" "athlon")
6978 (const_string "vector")
6979 (const_string "direct")))
6980 (set_attr "amdfam10_decode" "direct")
6981 (set_attr "bdver1_decode" "direct")
6982 (set_attr "mode" "QI")])
6983
6984 (define_expand "<s>mul<mode>3_highpart"
6985 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6986 (truncate:SWI48
6987 (lshiftrt:<DWI>
6988 (mult:<DWI>
6989 (any_extend:<DWI>
6990 (match_operand:SWI48 1 "nonimmediate_operand"))
6991 (any_extend:<DWI>
6992 (match_operand:SWI48 2 "register_operand")))
6993 (match_dup 4))))
6994 (clobber (match_scratch:SWI48 3))
6995 (clobber (reg:CC FLAGS_REG))])]
6996 ""
6997 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6998
6999 (define_insn "*<s>muldi3_highpart_1"
7000 [(set (match_operand:DI 0 "register_operand" "=d")
7001 (truncate:DI
7002 (lshiftrt:TI
7003 (mult:TI
7004 (any_extend:TI
7005 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7006 (any_extend:TI
7007 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7008 (const_int 64))))
7009 (clobber (match_scratch:DI 3 "=1"))
7010 (clobber (reg:CC FLAGS_REG))]
7011 "TARGET_64BIT
7012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7013 "<sgnprefix>mul{q}\t%2"
7014 [(set_attr "type" "imul")
7015 (set_attr "length_immediate" "0")
7016 (set (attr "athlon_decode")
7017 (if_then_else (eq_attr "cpu" "athlon")
7018 (const_string "vector")
7019 (const_string "double")))
7020 (set_attr "amdfam10_decode" "double")
7021 (set_attr "bdver1_decode" "direct")
7022 (set_attr "mode" "DI")])
7023
7024 (define_insn "*<s>mulsi3_highpart_1"
7025 [(set (match_operand:SI 0 "register_operand" "=d")
7026 (truncate:SI
7027 (lshiftrt:DI
7028 (mult:DI
7029 (any_extend:DI
7030 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7031 (any_extend:DI
7032 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7033 (const_int 32))))
7034 (clobber (match_scratch:SI 3 "=1"))
7035 (clobber (reg:CC FLAGS_REG))]
7036 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7037 "<sgnprefix>mul{l}\t%2"
7038 [(set_attr "type" "imul")
7039 (set_attr "length_immediate" "0")
7040 (set (attr "athlon_decode")
7041 (if_then_else (eq_attr "cpu" "athlon")
7042 (const_string "vector")
7043 (const_string "double")))
7044 (set_attr "amdfam10_decode" "double")
7045 (set_attr "bdver1_decode" "direct")
7046 (set_attr "mode" "SI")])
7047
7048 (define_insn "*<s>mulsi3_highpart_zext"
7049 [(set (match_operand:DI 0 "register_operand" "=d")
7050 (zero_extend:DI (truncate:SI
7051 (lshiftrt:DI
7052 (mult:DI (any_extend:DI
7053 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7054 (any_extend:DI
7055 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7056 (const_int 32)))))
7057 (clobber (match_scratch:SI 3 "=1"))
7058 (clobber (reg:CC FLAGS_REG))]
7059 "TARGET_64BIT
7060 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7061 "<sgnprefix>mul{l}\t%2"
7062 [(set_attr "type" "imul")
7063 (set_attr "length_immediate" "0")
7064 (set (attr "athlon_decode")
7065 (if_then_else (eq_attr "cpu" "athlon")
7066 (const_string "vector")
7067 (const_string "double")))
7068 (set_attr "amdfam10_decode" "double")
7069 (set_attr "bdver1_decode" "direct")
7070 (set_attr "mode" "SI")])
7071
7072 ;; The patterns that match these are at the end of this file.
7073
7074 (define_expand "mulxf3"
7075 [(set (match_operand:XF 0 "register_operand")
7076 (mult:XF (match_operand:XF 1 "register_operand")
7077 (match_operand:XF 2 "register_operand")))]
7078 "TARGET_80387")
7079
7080 (define_expand "mul<mode>3"
7081 [(set (match_operand:MODEF 0 "register_operand")
7082 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7083 (match_operand:MODEF 2 "nonimmediate_operand")))]
7084 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7085 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7086 \f
7087 ;; Divide instructions
7088
7089 ;; The patterns that match these are at the end of this file.
7090
7091 (define_expand "divxf3"
7092 [(set (match_operand:XF 0 "register_operand")
7093 (div:XF (match_operand:XF 1 "register_operand")
7094 (match_operand:XF 2 "register_operand")))]
7095 "TARGET_80387")
7096
7097 (define_expand "divdf3"
7098 [(set (match_operand:DF 0 "register_operand")
7099 (div:DF (match_operand:DF 1 "register_operand")
7100 (match_operand:DF 2 "nonimmediate_operand")))]
7101 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7102 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7103
7104 (define_expand "divsf3"
7105 [(set (match_operand:SF 0 "register_operand")
7106 (div:SF (match_operand:SF 1 "register_operand")
7107 (match_operand:SF 2 "nonimmediate_operand")))]
7108 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7109 || TARGET_SSE_MATH"
7110 {
7111 if (TARGET_SSE_MATH
7112 && TARGET_RECIP_DIV
7113 && optimize_insn_for_speed_p ()
7114 && flag_finite_math_only && !flag_trapping_math
7115 && flag_unsafe_math_optimizations)
7116 {
7117 ix86_emit_swdivsf (operands[0], operands[1],
7118 operands[2], SFmode);
7119 DONE;
7120 }
7121 })
7122 \f
7123 ;; Divmod instructions.
7124
7125 (define_expand "divmod<mode>4"
7126 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7127 (div:SWIM248
7128 (match_operand:SWIM248 1 "register_operand")
7129 (match_operand:SWIM248 2 "nonimmediate_operand")))
7130 (set (match_operand:SWIM248 3 "register_operand")
7131 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7132 (clobber (reg:CC FLAGS_REG))])])
7133
7134 ;; Split with 8bit unsigned divide:
7135 ;; if (dividend an divisor are in [0-255])
7136 ;; use 8bit unsigned integer divide
7137 ;; else
7138 ;; use original integer divide
7139 (define_split
7140 [(set (match_operand:SWI48 0 "register_operand")
7141 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7142 (match_operand:SWI48 3 "nonimmediate_operand")))
7143 (set (match_operand:SWI48 1 "register_operand")
7144 (mod:SWI48 (match_dup 2) (match_dup 3)))
7145 (clobber (reg:CC FLAGS_REG))]
7146 "TARGET_USE_8BIT_IDIV
7147 && TARGET_QIMODE_MATH
7148 && can_create_pseudo_p ()
7149 && !optimize_insn_for_size_p ()"
7150 [(const_int 0)]
7151 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7152
7153 (define_insn_and_split "divmod<mode>4_1"
7154 [(set (match_operand:SWI48 0 "register_operand" "=a")
7155 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7156 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7157 (set (match_operand:SWI48 1 "register_operand" "=&d")
7158 (mod:SWI48 (match_dup 2) (match_dup 3)))
7159 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7160 (clobber (reg:CC FLAGS_REG))]
7161 ""
7162 "#"
7163 "reload_completed"
7164 [(parallel [(set (match_dup 1)
7165 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7166 (clobber (reg:CC FLAGS_REG))])
7167 (parallel [(set (match_dup 0)
7168 (div:SWI48 (match_dup 2) (match_dup 3)))
7169 (set (match_dup 1)
7170 (mod:SWI48 (match_dup 2) (match_dup 3)))
7171 (use (match_dup 1))
7172 (clobber (reg:CC FLAGS_REG))])]
7173 {
7174 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7175
7176 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7177 operands[4] = operands[2];
7178 else
7179 {
7180 /* Avoid use of cltd in favor of a mov+shift. */
7181 emit_move_insn (operands[1], operands[2]);
7182 operands[4] = operands[1];
7183 }
7184 }
7185 [(set_attr "type" "multi")
7186 (set_attr "mode" "<MODE>")])
7187
7188 (define_insn_and_split "*divmod<mode>4"
7189 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7190 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7191 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7192 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7193 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7194 (clobber (reg:CC FLAGS_REG))]
7195 ""
7196 "#"
7197 "reload_completed"
7198 [(parallel [(set (match_dup 1)
7199 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7200 (clobber (reg:CC FLAGS_REG))])
7201 (parallel [(set (match_dup 0)
7202 (div:SWIM248 (match_dup 2) (match_dup 3)))
7203 (set (match_dup 1)
7204 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7205 (use (match_dup 1))
7206 (clobber (reg:CC FLAGS_REG))])]
7207 {
7208 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7209
7210 if (<MODE>mode != HImode
7211 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7212 operands[4] = operands[2];
7213 else
7214 {
7215 /* Avoid use of cltd in favor of a mov+shift. */
7216 emit_move_insn (operands[1], operands[2]);
7217 operands[4] = operands[1];
7218 }
7219 }
7220 [(set_attr "type" "multi")
7221 (set_attr "mode" "<MODE>")])
7222
7223 (define_insn "*divmod<mode>4_noext"
7224 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7225 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7226 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7227 (set (match_operand:SWIM248 1 "register_operand" "=d")
7228 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7229 (use (match_operand:SWIM248 4 "register_operand" "1"))
7230 (clobber (reg:CC FLAGS_REG))]
7231 ""
7232 "idiv{<imodesuffix>}\t%3"
7233 [(set_attr "type" "idiv")
7234 (set_attr "mode" "<MODE>")])
7235
7236 (define_expand "divmodqi4"
7237 [(parallel [(set (match_operand:QI 0 "register_operand")
7238 (div:QI
7239 (match_operand:QI 1 "register_operand")
7240 (match_operand:QI 2 "nonimmediate_operand")))
7241 (set (match_operand:QI 3 "register_operand")
7242 (mod:QI (match_dup 1) (match_dup 2)))
7243 (clobber (reg:CC FLAGS_REG))])]
7244 "TARGET_QIMODE_MATH"
7245 {
7246 rtx div, mod, insn;
7247 rtx tmp0, tmp1;
7248
7249 tmp0 = gen_reg_rtx (HImode);
7250 tmp1 = gen_reg_rtx (HImode);
7251
7252 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7253 in AX. */
7254 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7255 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7256
7257 /* Extract remainder from AH. */
7258 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7259 insn = emit_move_insn (operands[3], tmp1);
7260
7261 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7262 set_unique_reg_note (insn, REG_EQUAL, mod);
7263
7264 /* Extract quotient from AL. */
7265 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7266
7267 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7268 set_unique_reg_note (insn, REG_EQUAL, div);
7269
7270 DONE;
7271 })
7272
7273 ;; Divide AX by r/m8, with result stored in
7274 ;; AL <- Quotient
7275 ;; AH <- Remainder
7276 ;; Change div/mod to HImode and extend the second argument to HImode
7277 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7278 ;; combine may fail.
7279 (define_insn "divmodhiqi3"
7280 [(set (match_operand:HI 0 "register_operand" "=a")
7281 (ior:HI
7282 (ashift:HI
7283 (zero_extend:HI
7284 (truncate:QI
7285 (mod:HI (match_operand:HI 1 "register_operand" "0")
7286 (sign_extend:HI
7287 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7288 (const_int 8))
7289 (zero_extend:HI
7290 (truncate:QI
7291 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7292 (clobber (reg:CC FLAGS_REG))]
7293 "TARGET_QIMODE_MATH"
7294 "idiv{b}\t%2"
7295 [(set_attr "type" "idiv")
7296 (set_attr "mode" "QI")])
7297
7298 (define_expand "udivmod<mode>4"
7299 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7300 (udiv:SWIM248
7301 (match_operand:SWIM248 1 "register_operand")
7302 (match_operand:SWIM248 2 "nonimmediate_operand")))
7303 (set (match_operand:SWIM248 3 "register_operand")
7304 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7305 (clobber (reg:CC FLAGS_REG))])])
7306
7307 ;; Split with 8bit unsigned divide:
7308 ;; if (dividend an divisor are in [0-255])
7309 ;; use 8bit unsigned integer divide
7310 ;; else
7311 ;; use original integer divide
7312 (define_split
7313 [(set (match_operand:SWI48 0 "register_operand")
7314 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7315 (match_operand:SWI48 3 "nonimmediate_operand")))
7316 (set (match_operand:SWI48 1 "register_operand")
7317 (umod:SWI48 (match_dup 2) (match_dup 3)))
7318 (clobber (reg:CC FLAGS_REG))]
7319 "TARGET_USE_8BIT_IDIV
7320 && TARGET_QIMODE_MATH
7321 && can_create_pseudo_p ()
7322 && !optimize_insn_for_size_p ()"
7323 [(const_int 0)]
7324 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7325
7326 (define_insn_and_split "udivmod<mode>4_1"
7327 [(set (match_operand:SWI48 0 "register_operand" "=a")
7328 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7329 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7330 (set (match_operand:SWI48 1 "register_operand" "=&d")
7331 (umod:SWI48 (match_dup 2) (match_dup 3)))
7332 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7333 (clobber (reg:CC FLAGS_REG))]
7334 ""
7335 "#"
7336 "reload_completed"
7337 [(set (match_dup 1) (const_int 0))
7338 (parallel [(set (match_dup 0)
7339 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7340 (set (match_dup 1)
7341 (umod:SWI48 (match_dup 2) (match_dup 3)))
7342 (use (match_dup 1))
7343 (clobber (reg:CC FLAGS_REG))])]
7344 ""
7345 [(set_attr "type" "multi")
7346 (set_attr "mode" "<MODE>")])
7347
7348 (define_insn_and_split "*udivmod<mode>4"
7349 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7350 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7351 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7352 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7353 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7354 (clobber (reg:CC FLAGS_REG))]
7355 ""
7356 "#"
7357 "reload_completed"
7358 [(set (match_dup 1) (const_int 0))
7359 (parallel [(set (match_dup 0)
7360 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7361 (set (match_dup 1)
7362 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7363 (use (match_dup 1))
7364 (clobber (reg:CC FLAGS_REG))])]
7365 ""
7366 [(set_attr "type" "multi")
7367 (set_attr "mode" "<MODE>")])
7368
7369 (define_insn "*udivmod<mode>4_noext"
7370 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7371 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7372 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7373 (set (match_operand:SWIM248 1 "register_operand" "=d")
7374 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7375 (use (match_operand:SWIM248 4 "register_operand" "1"))
7376 (clobber (reg:CC FLAGS_REG))]
7377 ""
7378 "div{<imodesuffix>}\t%3"
7379 [(set_attr "type" "idiv")
7380 (set_attr "mode" "<MODE>")])
7381
7382 (define_expand "udivmodqi4"
7383 [(parallel [(set (match_operand:QI 0 "register_operand")
7384 (udiv:QI
7385 (match_operand:QI 1 "register_operand")
7386 (match_operand:QI 2 "nonimmediate_operand")))
7387 (set (match_operand:QI 3 "register_operand")
7388 (umod:QI (match_dup 1) (match_dup 2)))
7389 (clobber (reg:CC FLAGS_REG))])]
7390 "TARGET_QIMODE_MATH"
7391 {
7392 rtx div, mod, insn;
7393 rtx tmp0, tmp1;
7394
7395 tmp0 = gen_reg_rtx (HImode);
7396 tmp1 = gen_reg_rtx (HImode);
7397
7398 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7399 in AX. */
7400 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7401 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7402
7403 /* Extract remainder from AH. */
7404 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7405 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7406 insn = emit_move_insn (operands[3], tmp1);
7407
7408 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7409 set_unique_reg_note (insn, REG_EQUAL, mod);
7410
7411 /* Extract quotient from AL. */
7412 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7413
7414 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7415 set_unique_reg_note (insn, REG_EQUAL, div);
7416
7417 DONE;
7418 })
7419
7420 (define_insn "udivmodhiqi3"
7421 [(set (match_operand:HI 0 "register_operand" "=a")
7422 (ior:HI
7423 (ashift:HI
7424 (zero_extend:HI
7425 (truncate:QI
7426 (mod:HI (match_operand:HI 1 "register_operand" "0")
7427 (zero_extend:HI
7428 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7429 (const_int 8))
7430 (zero_extend:HI
7431 (truncate:QI
7432 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7433 (clobber (reg:CC FLAGS_REG))]
7434 "TARGET_QIMODE_MATH"
7435 "div{b}\t%2"
7436 [(set_attr "type" "idiv")
7437 (set_attr "mode" "QI")])
7438
7439 ;; We cannot use div/idiv for double division, because it causes
7440 ;; "division by zero" on the overflow and that's not what we expect
7441 ;; from truncate. Because true (non truncating) double division is
7442 ;; never generated, we can't create this insn anyway.
7443 ;
7444 ;(define_insn ""
7445 ; [(set (match_operand:SI 0 "register_operand" "=a")
7446 ; (truncate:SI
7447 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7448 ; (zero_extend:DI
7449 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7450 ; (set (match_operand:SI 3 "register_operand" "=d")
7451 ; (truncate:SI
7452 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7453 ; (clobber (reg:CC FLAGS_REG))]
7454 ; ""
7455 ; "div{l}\t{%2, %0|%0, %2}"
7456 ; [(set_attr "type" "idiv")])
7457 \f
7458 ;;- Logical AND instructions
7459
7460 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7461 ;; Note that this excludes ah.
7462
7463 (define_expand "testsi_ccno_1"
7464 [(set (reg:CCNO FLAGS_REG)
7465 (compare:CCNO
7466 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7467 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7468 (const_int 0)))])
7469
7470 (define_expand "testqi_ccz_1"
7471 [(set (reg:CCZ FLAGS_REG)
7472 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7473 (match_operand:QI 1 "nonmemory_operand"))
7474 (const_int 0)))])
7475
7476 (define_expand "testdi_ccno_1"
7477 [(set (reg:CCNO FLAGS_REG)
7478 (compare:CCNO
7479 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7480 (match_operand:DI 1 "x86_64_szext_general_operand"))
7481 (const_int 0)))]
7482 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7483
7484 (define_insn "*testdi_1"
7485 [(set (reg FLAGS_REG)
7486 (compare
7487 (and:DI
7488 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7489 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7490 (const_int 0)))]
7491 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7492 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7493 "@
7494 test{l}\t{%k1, %k0|%k0, %k1}
7495 test{l}\t{%k1, %k0|%k0, %k1}
7496 test{q}\t{%1, %0|%0, %1}
7497 test{q}\t{%1, %0|%0, %1}
7498 test{q}\t{%1, %0|%0, %1}"
7499 [(set_attr "type" "test")
7500 (set_attr "modrm" "0,1,0,1,1")
7501 (set_attr "mode" "SI,SI,DI,DI,DI")])
7502
7503 (define_insn "*testqi_1_maybe_si"
7504 [(set (reg FLAGS_REG)
7505 (compare
7506 (and:QI
7507 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7508 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7509 (const_int 0)))]
7510 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7511 && ix86_match_ccmode (insn,
7512 CONST_INT_P (operands[1])
7513 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7514 {
7515 if (which_alternative == 3)
7516 {
7517 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7518 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7519 return "test{l}\t{%1, %k0|%k0, %1}";
7520 }
7521 return "test{b}\t{%1, %0|%0, %1}";
7522 }
7523 [(set_attr "type" "test")
7524 (set_attr "modrm" "0,1,1,1")
7525 (set_attr "mode" "QI,QI,QI,SI")
7526 (set_attr "pent_pair" "uv,np,uv,np")])
7527
7528 (define_insn "*test<mode>_1"
7529 [(set (reg FLAGS_REG)
7530 (compare
7531 (and:SWI124
7532 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7533 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7534 (const_int 0)))]
7535 "ix86_match_ccmode (insn, CCNOmode)
7536 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7537 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7538 [(set_attr "type" "test")
7539 (set_attr "modrm" "0,1,1")
7540 (set_attr "mode" "<MODE>")
7541 (set_attr "pent_pair" "uv,np,uv")])
7542
7543 (define_expand "testqi_ext_ccno_0"
7544 [(set (reg:CCNO FLAGS_REG)
7545 (compare:CCNO
7546 (and:SI
7547 (zero_extract:SI
7548 (match_operand 0 "ext_register_operand")
7549 (const_int 8)
7550 (const_int 8))
7551 (match_operand 1 "const_int_operand"))
7552 (const_int 0)))])
7553
7554 (define_insn "*testqi_ext_0"
7555 [(set (reg FLAGS_REG)
7556 (compare
7557 (and:SI
7558 (zero_extract:SI
7559 (match_operand 0 "ext_register_operand" "Q")
7560 (const_int 8)
7561 (const_int 8))
7562 (match_operand 1 "const_int_operand" "n"))
7563 (const_int 0)))]
7564 "ix86_match_ccmode (insn, CCNOmode)"
7565 "test{b}\t{%1, %h0|%h0, %1}"
7566 [(set_attr "type" "test")
7567 (set_attr "mode" "QI")
7568 (set_attr "length_immediate" "1")
7569 (set_attr "modrm" "1")
7570 (set_attr "pent_pair" "np")])
7571
7572 (define_insn "*testqi_ext_1_rex64"
7573 [(set (reg FLAGS_REG)
7574 (compare
7575 (and:SI
7576 (zero_extract:SI
7577 (match_operand 0 "ext_register_operand" "Q")
7578 (const_int 8)
7579 (const_int 8))
7580 (zero_extend:SI
7581 (match_operand:QI 1 "register_operand" "Q")))
7582 (const_int 0)))]
7583 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7584 "test{b}\t{%1, %h0|%h0, %1}"
7585 [(set_attr "type" "test")
7586 (set_attr "mode" "QI")])
7587
7588 (define_insn "*testqi_ext_1"
7589 [(set (reg FLAGS_REG)
7590 (compare
7591 (and:SI
7592 (zero_extract:SI
7593 (match_operand 0 "ext_register_operand" "Q")
7594 (const_int 8)
7595 (const_int 8))
7596 (zero_extend:SI
7597 (match_operand:QI 1 "general_operand" "Qm")))
7598 (const_int 0)))]
7599 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7600 "test{b}\t{%1, %h0|%h0, %1}"
7601 [(set_attr "type" "test")
7602 (set_attr "mode" "QI")])
7603
7604 (define_insn "*testqi_ext_2"
7605 [(set (reg FLAGS_REG)
7606 (compare
7607 (and:SI
7608 (zero_extract:SI
7609 (match_operand 0 "ext_register_operand" "Q")
7610 (const_int 8)
7611 (const_int 8))
7612 (zero_extract:SI
7613 (match_operand 1 "ext_register_operand" "Q")
7614 (const_int 8)
7615 (const_int 8)))
7616 (const_int 0)))]
7617 "ix86_match_ccmode (insn, CCNOmode)"
7618 "test{b}\t{%h1, %h0|%h0, %h1}"
7619 [(set_attr "type" "test")
7620 (set_attr "mode" "QI")])
7621
7622 (define_insn "*testqi_ext_3_rex64"
7623 [(set (reg FLAGS_REG)
7624 (compare (zero_extract:DI
7625 (match_operand 0 "nonimmediate_operand" "rm")
7626 (match_operand:DI 1 "const_int_operand")
7627 (match_operand:DI 2 "const_int_operand"))
7628 (const_int 0)))]
7629 "TARGET_64BIT
7630 && ix86_match_ccmode (insn, CCNOmode)
7631 && INTVAL (operands[1]) > 0
7632 && INTVAL (operands[2]) >= 0
7633 /* Ensure that resulting mask is zero or sign extended operand. */
7634 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7635 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7636 && INTVAL (operands[1]) > 32))
7637 && (GET_MODE (operands[0]) == SImode
7638 || GET_MODE (operands[0]) == DImode
7639 || GET_MODE (operands[0]) == HImode
7640 || GET_MODE (operands[0]) == QImode)"
7641 "#")
7642
7643 ;; Combine likes to form bit extractions for some tests. Humor it.
7644 (define_insn "*testqi_ext_3"
7645 [(set (reg FLAGS_REG)
7646 (compare (zero_extract:SI
7647 (match_operand 0 "nonimmediate_operand" "rm")
7648 (match_operand:SI 1 "const_int_operand")
7649 (match_operand:SI 2 "const_int_operand"))
7650 (const_int 0)))]
7651 "ix86_match_ccmode (insn, CCNOmode)
7652 && INTVAL (operands[1]) > 0
7653 && INTVAL (operands[2]) >= 0
7654 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7655 && (GET_MODE (operands[0]) == SImode
7656 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7657 || GET_MODE (operands[0]) == HImode
7658 || GET_MODE (operands[0]) == QImode)"
7659 "#")
7660
7661 (define_split
7662 [(set (match_operand 0 "flags_reg_operand")
7663 (match_operator 1 "compare_operator"
7664 [(zero_extract
7665 (match_operand 2 "nonimmediate_operand")
7666 (match_operand 3 "const_int_operand")
7667 (match_operand 4 "const_int_operand"))
7668 (const_int 0)]))]
7669 "ix86_match_ccmode (insn, CCNOmode)"
7670 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7671 {
7672 rtx val = operands[2];
7673 HOST_WIDE_INT len = INTVAL (operands[3]);
7674 HOST_WIDE_INT pos = INTVAL (operands[4]);
7675 HOST_WIDE_INT mask;
7676 enum machine_mode mode, submode;
7677
7678 mode = GET_MODE (val);
7679 if (MEM_P (val))
7680 {
7681 /* ??? Combine likes to put non-volatile mem extractions in QImode
7682 no matter the size of the test. So find a mode that works. */
7683 if (! MEM_VOLATILE_P (val))
7684 {
7685 mode = smallest_mode_for_size (pos + len, MODE_INT);
7686 val = adjust_address (val, mode, 0);
7687 }
7688 }
7689 else if (GET_CODE (val) == SUBREG
7690 && (submode = GET_MODE (SUBREG_REG (val)),
7691 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7692 && pos + len <= GET_MODE_BITSIZE (submode)
7693 && GET_MODE_CLASS (submode) == MODE_INT)
7694 {
7695 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7696 mode = submode;
7697 val = SUBREG_REG (val);
7698 }
7699 else if (mode == HImode && pos + len <= 8)
7700 {
7701 /* Small HImode tests can be converted to QImode. */
7702 mode = QImode;
7703 val = gen_lowpart (QImode, val);
7704 }
7705
7706 if (len == HOST_BITS_PER_WIDE_INT)
7707 mask = -1;
7708 else
7709 mask = ((HOST_WIDE_INT)1 << len) - 1;
7710 mask <<= pos;
7711
7712 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7713 })
7714
7715 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7716 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7717 ;; this is relatively important trick.
7718 ;; Do the conversion only post-reload to avoid limiting of the register class
7719 ;; to QI regs.
7720 (define_split
7721 [(set (match_operand 0 "flags_reg_operand")
7722 (match_operator 1 "compare_operator"
7723 [(and (match_operand 2 "register_operand")
7724 (match_operand 3 "const_int_operand"))
7725 (const_int 0)]))]
7726 "reload_completed
7727 && QI_REG_P (operands[2])
7728 && GET_MODE (operands[2]) != QImode
7729 && ((ix86_match_ccmode (insn, CCZmode)
7730 && !(INTVAL (operands[3]) & ~(255 << 8)))
7731 || (ix86_match_ccmode (insn, CCNOmode)
7732 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7733 [(set (match_dup 0)
7734 (match_op_dup 1
7735 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7736 (match_dup 3))
7737 (const_int 0)]))]
7738 {
7739 operands[2] = gen_lowpart (SImode, operands[2]);
7740 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7741 })
7742
7743 (define_split
7744 [(set (match_operand 0 "flags_reg_operand")
7745 (match_operator 1 "compare_operator"
7746 [(and (match_operand 2 "nonimmediate_operand")
7747 (match_operand 3 "const_int_operand"))
7748 (const_int 0)]))]
7749 "reload_completed
7750 && GET_MODE (operands[2]) != QImode
7751 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7752 && ((ix86_match_ccmode (insn, CCZmode)
7753 && !(INTVAL (operands[3]) & ~255))
7754 || (ix86_match_ccmode (insn, CCNOmode)
7755 && !(INTVAL (operands[3]) & ~127)))"
7756 [(set (match_dup 0)
7757 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7758 (const_int 0)]))]
7759 {
7760 operands[2] = gen_lowpart (QImode, operands[2]);
7761 operands[3] = gen_lowpart (QImode, operands[3]);
7762 })
7763
7764 ;; %%% This used to optimize known byte-wide and operations to memory,
7765 ;; and sometimes to QImode registers. If this is considered useful,
7766 ;; it should be done with splitters.
7767
7768 (define_expand "and<mode>3"
7769 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7770 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7771 (match_operand:SWIM 2 "<general_szext_operand>")))]
7772 ""
7773 {
7774 enum machine_mode mode = <MODE>mode;
7775 rtx (*insn) (rtx, rtx);
7776
7777 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7778 {
7779 HOST_WIDE_INT ival = INTVAL (operands[2]);
7780
7781 if (ival == (HOST_WIDE_INT) 0xffffffff)
7782 mode = SImode;
7783 else if (ival == 0xffff)
7784 mode = HImode;
7785 else if (ival == 0xff)
7786 mode = QImode;
7787 }
7788
7789 if (mode == <MODE>mode)
7790 {
7791 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7792 DONE;
7793 }
7794
7795 if (<MODE>mode == DImode)
7796 insn = (mode == SImode)
7797 ? gen_zero_extendsidi2
7798 : (mode == HImode)
7799 ? gen_zero_extendhidi2
7800 : gen_zero_extendqidi2;
7801 else if (<MODE>mode == SImode)
7802 insn = (mode == HImode)
7803 ? gen_zero_extendhisi2
7804 : gen_zero_extendqisi2;
7805 else if (<MODE>mode == HImode)
7806 insn = gen_zero_extendqihi2;
7807 else
7808 gcc_unreachable ();
7809
7810 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7811 DONE;
7812 })
7813
7814 (define_insn "*anddi_1"
7815 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7816 (and:DI
7817 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7818 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7819 (clobber (reg:CC FLAGS_REG))]
7820 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7821 {
7822 switch (get_attr_type (insn))
7823 {
7824 case TYPE_IMOVX:
7825 return "#";
7826
7827 default:
7828 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7829 if (get_attr_mode (insn) == MODE_SI)
7830 return "and{l}\t{%k2, %k0|%k0, %k2}";
7831 else
7832 return "and{q}\t{%2, %0|%0, %2}";
7833 }
7834 }
7835 [(set_attr "type" "alu,alu,alu,imovx")
7836 (set_attr "length_immediate" "*,*,*,0")
7837 (set (attr "prefix_rex")
7838 (if_then_else
7839 (and (eq_attr "type" "imovx")
7840 (and (match_test "INTVAL (operands[2]) == 0xff")
7841 (match_operand 1 "ext_QIreg_operand")))
7842 (const_string "1")
7843 (const_string "*")))
7844 (set_attr "mode" "SI,DI,DI,SI")])
7845
7846 (define_insn "*andsi_1"
7847 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7848 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7849 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7850 (clobber (reg:CC FLAGS_REG))]
7851 "ix86_binary_operator_ok (AND, SImode, operands)"
7852 {
7853 switch (get_attr_type (insn))
7854 {
7855 case TYPE_IMOVX:
7856 return "#";
7857
7858 default:
7859 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7860 return "and{l}\t{%2, %0|%0, %2}";
7861 }
7862 }
7863 [(set_attr "type" "alu,alu,imovx")
7864 (set (attr "prefix_rex")
7865 (if_then_else
7866 (and (eq_attr "type" "imovx")
7867 (and (match_test "INTVAL (operands[2]) == 0xff")
7868 (match_operand 1 "ext_QIreg_operand")))
7869 (const_string "1")
7870 (const_string "*")))
7871 (set_attr "length_immediate" "*,*,0")
7872 (set_attr "mode" "SI")])
7873
7874 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7875 (define_insn "*andsi_1_zext"
7876 [(set (match_operand:DI 0 "register_operand" "=r")
7877 (zero_extend:DI
7878 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7879 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7880 (clobber (reg:CC FLAGS_REG))]
7881 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7882 "and{l}\t{%2, %k0|%k0, %2}"
7883 [(set_attr "type" "alu")
7884 (set_attr "mode" "SI")])
7885
7886 (define_insn "*andhi_1"
7887 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7888 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7889 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7890 (clobber (reg:CC FLAGS_REG))]
7891 "ix86_binary_operator_ok (AND, HImode, operands)"
7892 {
7893 switch (get_attr_type (insn))
7894 {
7895 case TYPE_IMOVX:
7896 return "#";
7897
7898 default:
7899 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7900 return "and{w}\t{%2, %0|%0, %2}";
7901 }
7902 }
7903 [(set_attr "type" "alu,alu,imovx")
7904 (set_attr "length_immediate" "*,*,0")
7905 (set (attr "prefix_rex")
7906 (if_then_else
7907 (and (eq_attr "type" "imovx")
7908 (match_operand 1 "ext_QIreg_operand"))
7909 (const_string "1")
7910 (const_string "*")))
7911 (set_attr "mode" "HI,HI,SI")])
7912
7913 ;; %%% Potential partial reg stall on alternative 2. What to do?
7914 (define_insn "*andqi_1"
7915 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7916 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7917 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7918 (clobber (reg:CC FLAGS_REG))]
7919 "ix86_binary_operator_ok (AND, QImode, operands)"
7920 "@
7921 and{b}\t{%2, %0|%0, %2}
7922 and{b}\t{%2, %0|%0, %2}
7923 and{l}\t{%k2, %k0|%k0, %k2}"
7924 [(set_attr "type" "alu")
7925 (set_attr "mode" "QI,QI,SI")])
7926
7927 (define_insn "*andqi_1_slp"
7928 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7929 (and:QI (match_dup 0)
7930 (match_operand:QI 1 "general_operand" "qn,qmn")))
7931 (clobber (reg:CC FLAGS_REG))]
7932 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7933 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7934 "and{b}\t{%1, %0|%0, %1}"
7935 [(set_attr "type" "alu1")
7936 (set_attr "mode" "QI")])
7937
7938 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7939 (define_split
7940 [(set (match_operand:DI 0 "register_operand")
7941 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7942 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7943 (clobber (reg:CC FLAGS_REG))]
7944 "TARGET_64BIT"
7945 [(parallel [(set (match_dup 0)
7946 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7947 (clobber (reg:CC FLAGS_REG))])]
7948 "operands[2] = gen_lowpart (SImode, operands[2]);")
7949
7950 (define_split
7951 [(set (match_operand:SWI248 0 "register_operand")
7952 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7953 (match_operand:SWI248 2 "const_int_operand")))
7954 (clobber (reg:CC FLAGS_REG))]
7955 "reload_completed
7956 && true_regnum (operands[0]) != true_regnum (operands[1])"
7957 [(const_int 0)]
7958 {
7959 HOST_WIDE_INT ival = INTVAL (operands[2]);
7960 enum machine_mode mode;
7961 rtx (*insn) (rtx, rtx);
7962
7963 if (ival == (HOST_WIDE_INT) 0xffffffff)
7964 mode = SImode;
7965 else if (ival == 0xffff)
7966 mode = HImode;
7967 else
7968 {
7969 gcc_assert (ival == 0xff);
7970 mode = QImode;
7971 }
7972
7973 if (<MODE>mode == DImode)
7974 insn = (mode == SImode)
7975 ? gen_zero_extendsidi2
7976 : (mode == HImode)
7977 ? gen_zero_extendhidi2
7978 : gen_zero_extendqidi2;
7979 else
7980 {
7981 if (<MODE>mode != SImode)
7982 /* Zero extend to SImode to avoid partial register stalls. */
7983 operands[0] = gen_lowpart (SImode, operands[0]);
7984
7985 insn = (mode == HImode)
7986 ? gen_zero_extendhisi2
7987 : gen_zero_extendqisi2;
7988 }
7989 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7990 DONE;
7991 })
7992
7993 (define_split
7994 [(set (match_operand 0 "register_operand")
7995 (and (match_dup 0)
7996 (const_int -65536)))
7997 (clobber (reg:CC FLAGS_REG))]
7998 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7999 || optimize_function_for_size_p (cfun)"
8000 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8001 "operands[1] = gen_lowpart (HImode, operands[0]);")
8002
8003 (define_split
8004 [(set (match_operand 0 "ext_register_operand")
8005 (and (match_dup 0)
8006 (const_int -256)))
8007 (clobber (reg:CC FLAGS_REG))]
8008 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8009 && reload_completed"
8010 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8011 "operands[1] = gen_lowpart (QImode, operands[0]);")
8012
8013 (define_split
8014 [(set (match_operand 0 "ext_register_operand")
8015 (and (match_dup 0)
8016 (const_int -65281)))
8017 (clobber (reg:CC FLAGS_REG))]
8018 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8019 && reload_completed"
8020 [(parallel [(set (zero_extract:SI (match_dup 0)
8021 (const_int 8)
8022 (const_int 8))
8023 (xor:SI
8024 (zero_extract:SI (match_dup 0)
8025 (const_int 8)
8026 (const_int 8))
8027 (zero_extract:SI (match_dup 0)
8028 (const_int 8)
8029 (const_int 8))))
8030 (clobber (reg:CC FLAGS_REG))])]
8031 "operands[0] = gen_lowpart (SImode, operands[0]);")
8032
8033 (define_insn "*anddi_2"
8034 [(set (reg FLAGS_REG)
8035 (compare
8036 (and:DI
8037 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8038 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8039 (const_int 0)))
8040 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8041 (and:DI (match_dup 1) (match_dup 2)))]
8042 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8043 && ix86_binary_operator_ok (AND, DImode, operands)"
8044 "@
8045 and{l}\t{%k2, %k0|%k0, %k2}
8046 and{q}\t{%2, %0|%0, %2}
8047 and{q}\t{%2, %0|%0, %2}"
8048 [(set_attr "type" "alu")
8049 (set_attr "mode" "SI,DI,DI")])
8050
8051 (define_insn "*andqi_2_maybe_si"
8052 [(set (reg FLAGS_REG)
8053 (compare (and:QI
8054 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8055 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8056 (const_int 0)))
8057 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8058 (and:QI (match_dup 1) (match_dup 2)))]
8059 "ix86_binary_operator_ok (AND, QImode, operands)
8060 && ix86_match_ccmode (insn,
8061 CONST_INT_P (operands[2])
8062 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8063 {
8064 if (which_alternative == 2)
8065 {
8066 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8067 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8068 return "and{l}\t{%2, %k0|%k0, %2}";
8069 }
8070 return "and{b}\t{%2, %0|%0, %2}";
8071 }
8072 [(set_attr "type" "alu")
8073 (set_attr "mode" "QI,QI,SI")])
8074
8075 (define_insn "*and<mode>_2"
8076 [(set (reg FLAGS_REG)
8077 (compare (and:SWI124
8078 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8079 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8080 (const_int 0)))
8081 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8082 (and:SWI124 (match_dup 1) (match_dup 2)))]
8083 "ix86_match_ccmode (insn, CCNOmode)
8084 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8085 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8086 [(set_attr "type" "alu")
8087 (set_attr "mode" "<MODE>")])
8088
8089 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8090 (define_insn "*andsi_2_zext"
8091 [(set (reg FLAGS_REG)
8092 (compare (and:SI
8093 (match_operand:SI 1 "nonimmediate_operand" "%0")
8094 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8095 (const_int 0)))
8096 (set (match_operand:DI 0 "register_operand" "=r")
8097 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8098 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8099 && ix86_binary_operator_ok (AND, SImode, operands)"
8100 "and{l}\t{%2, %k0|%k0, %2}"
8101 [(set_attr "type" "alu")
8102 (set_attr "mode" "SI")])
8103
8104 (define_insn "*andqi_2_slp"
8105 [(set (reg FLAGS_REG)
8106 (compare (and:QI
8107 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8108 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8109 (const_int 0)))
8110 (set (strict_low_part (match_dup 0))
8111 (and:QI (match_dup 0) (match_dup 1)))]
8112 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8113 && ix86_match_ccmode (insn, CCNOmode)
8114 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8115 "and{b}\t{%1, %0|%0, %1}"
8116 [(set_attr "type" "alu1")
8117 (set_attr "mode" "QI")])
8118
8119 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8120 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8121 ;; for a QImode operand, which of course failed.
8122 (define_insn "andqi_ext_0"
8123 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8124 (const_int 8)
8125 (const_int 8))
8126 (and:SI
8127 (zero_extract:SI
8128 (match_operand 1 "ext_register_operand" "0")
8129 (const_int 8)
8130 (const_int 8))
8131 (match_operand 2 "const_int_operand" "n")))
8132 (clobber (reg:CC FLAGS_REG))]
8133 ""
8134 "and{b}\t{%2, %h0|%h0, %2}"
8135 [(set_attr "type" "alu")
8136 (set_attr "length_immediate" "1")
8137 (set_attr "modrm" "1")
8138 (set_attr "mode" "QI")])
8139
8140 ;; Generated by peephole translating test to and. This shows up
8141 ;; often in fp comparisons.
8142 (define_insn "*andqi_ext_0_cc"
8143 [(set (reg FLAGS_REG)
8144 (compare
8145 (and:SI
8146 (zero_extract:SI
8147 (match_operand 1 "ext_register_operand" "0")
8148 (const_int 8)
8149 (const_int 8))
8150 (match_operand 2 "const_int_operand" "n"))
8151 (const_int 0)))
8152 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8153 (const_int 8)
8154 (const_int 8))
8155 (and:SI
8156 (zero_extract:SI
8157 (match_dup 1)
8158 (const_int 8)
8159 (const_int 8))
8160 (match_dup 2)))]
8161 "ix86_match_ccmode (insn, CCNOmode)"
8162 "and{b}\t{%2, %h0|%h0, %2}"
8163 [(set_attr "type" "alu")
8164 (set_attr "length_immediate" "1")
8165 (set_attr "modrm" "1")
8166 (set_attr "mode" "QI")])
8167
8168 (define_insn "*andqi_ext_1_rex64"
8169 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8170 (const_int 8)
8171 (const_int 8))
8172 (and:SI
8173 (zero_extract:SI
8174 (match_operand 1 "ext_register_operand" "0")
8175 (const_int 8)
8176 (const_int 8))
8177 (zero_extend:SI
8178 (match_operand 2 "ext_register_operand" "Q"))))
8179 (clobber (reg:CC FLAGS_REG))]
8180 "TARGET_64BIT"
8181 "and{b}\t{%2, %h0|%h0, %2}"
8182 [(set_attr "type" "alu")
8183 (set_attr "length_immediate" "0")
8184 (set_attr "mode" "QI")])
8185
8186 (define_insn "*andqi_ext_1"
8187 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8188 (const_int 8)
8189 (const_int 8))
8190 (and:SI
8191 (zero_extract:SI
8192 (match_operand 1 "ext_register_operand" "0")
8193 (const_int 8)
8194 (const_int 8))
8195 (zero_extend:SI
8196 (match_operand:QI 2 "general_operand" "Qm"))))
8197 (clobber (reg:CC FLAGS_REG))]
8198 "!TARGET_64BIT"
8199 "and{b}\t{%2, %h0|%h0, %2}"
8200 [(set_attr "type" "alu")
8201 (set_attr "length_immediate" "0")
8202 (set_attr "mode" "QI")])
8203
8204 (define_insn "*andqi_ext_2"
8205 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8206 (const_int 8)
8207 (const_int 8))
8208 (and:SI
8209 (zero_extract:SI
8210 (match_operand 1 "ext_register_operand" "%0")
8211 (const_int 8)
8212 (const_int 8))
8213 (zero_extract:SI
8214 (match_operand 2 "ext_register_operand" "Q")
8215 (const_int 8)
8216 (const_int 8))))
8217 (clobber (reg:CC FLAGS_REG))]
8218 ""
8219 "and{b}\t{%h2, %h0|%h0, %h2}"
8220 [(set_attr "type" "alu")
8221 (set_attr "length_immediate" "0")
8222 (set_attr "mode" "QI")])
8223
8224 ;; Convert wide AND instructions with immediate operand to shorter QImode
8225 ;; equivalents when possible.
8226 ;; Don't do the splitting with memory operands, since it introduces risk
8227 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8228 ;; for size, but that can (should?) be handled by generic code instead.
8229 (define_split
8230 [(set (match_operand 0 "register_operand")
8231 (and (match_operand 1 "register_operand")
8232 (match_operand 2 "const_int_operand")))
8233 (clobber (reg:CC FLAGS_REG))]
8234 "reload_completed
8235 && QI_REG_P (operands[0])
8236 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8237 && !(~INTVAL (operands[2]) & ~(255 << 8))
8238 && GET_MODE (operands[0]) != QImode"
8239 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8240 (and:SI (zero_extract:SI (match_dup 1)
8241 (const_int 8) (const_int 8))
8242 (match_dup 2)))
8243 (clobber (reg:CC FLAGS_REG))])]
8244 {
8245 operands[0] = gen_lowpart (SImode, operands[0]);
8246 operands[1] = gen_lowpart (SImode, operands[1]);
8247 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8248 })
8249
8250 ;; Since AND can be encoded with sign extended immediate, this is only
8251 ;; profitable when 7th bit is not set.
8252 (define_split
8253 [(set (match_operand 0 "register_operand")
8254 (and (match_operand 1 "general_operand")
8255 (match_operand 2 "const_int_operand")))
8256 (clobber (reg:CC FLAGS_REG))]
8257 "reload_completed
8258 && ANY_QI_REG_P (operands[0])
8259 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8260 && !(~INTVAL (operands[2]) & ~255)
8261 && !(INTVAL (operands[2]) & 128)
8262 && GET_MODE (operands[0]) != QImode"
8263 [(parallel [(set (strict_low_part (match_dup 0))
8264 (and:QI (match_dup 1)
8265 (match_dup 2)))
8266 (clobber (reg:CC FLAGS_REG))])]
8267 {
8268 operands[0] = gen_lowpart (QImode, operands[0]);
8269 operands[1] = gen_lowpart (QImode, operands[1]);
8270 operands[2] = gen_lowpart (QImode, operands[2]);
8271 })
8272 \f
8273 ;; Logical inclusive and exclusive OR instructions
8274
8275 ;; %%% This used to optimize known byte-wide and operations to memory.
8276 ;; If this is considered useful, it should be done with splitters.
8277
8278 (define_expand "<code><mode>3"
8279 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8280 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8281 (match_operand:SWIM 2 "<general_operand>")))]
8282 ""
8283 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8284
8285 (define_insn "*<code><mode>_1"
8286 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8287 (any_or:SWI248
8288 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8289 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8290 (clobber (reg:CC FLAGS_REG))]
8291 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8292 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8293 [(set_attr "type" "alu")
8294 (set_attr "mode" "<MODE>")])
8295
8296 ;; %%% Potential partial reg stall on alternative 2. What to do?
8297 (define_insn "*<code>qi_1"
8298 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8299 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8300 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8301 (clobber (reg:CC FLAGS_REG))]
8302 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8303 "@
8304 <logic>{b}\t{%2, %0|%0, %2}
8305 <logic>{b}\t{%2, %0|%0, %2}
8306 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8307 [(set_attr "type" "alu")
8308 (set_attr "mode" "QI,QI,SI")])
8309
8310 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8311 (define_insn "*<code>si_1_zext"
8312 [(set (match_operand:DI 0 "register_operand" "=r")
8313 (zero_extend:DI
8314 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8315 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8316 (clobber (reg:CC FLAGS_REG))]
8317 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8318 "<logic>{l}\t{%2, %k0|%k0, %2}"
8319 [(set_attr "type" "alu")
8320 (set_attr "mode" "SI")])
8321
8322 (define_insn "*<code>si_1_zext_imm"
8323 [(set (match_operand:DI 0 "register_operand" "=r")
8324 (any_or:DI
8325 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8326 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8327 (clobber (reg:CC FLAGS_REG))]
8328 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8329 "<logic>{l}\t{%2, %k0|%k0, %2}"
8330 [(set_attr "type" "alu")
8331 (set_attr "mode" "SI")])
8332
8333 (define_insn "*<code>qi_1_slp"
8334 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8335 (any_or:QI (match_dup 0)
8336 (match_operand:QI 1 "general_operand" "qmn,qn")))
8337 (clobber (reg:CC FLAGS_REG))]
8338 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8339 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8340 "<logic>{b}\t{%1, %0|%0, %1}"
8341 [(set_attr "type" "alu1")
8342 (set_attr "mode" "QI")])
8343
8344 (define_insn "*<code><mode>_2"
8345 [(set (reg FLAGS_REG)
8346 (compare (any_or:SWI
8347 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8348 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8349 (const_int 0)))
8350 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8351 (any_or:SWI (match_dup 1) (match_dup 2)))]
8352 "ix86_match_ccmode (insn, CCNOmode)
8353 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8354 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8355 [(set_attr "type" "alu")
8356 (set_attr "mode" "<MODE>")])
8357
8358 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8359 ;; ??? Special case for immediate operand is missing - it is tricky.
8360 (define_insn "*<code>si_2_zext"
8361 [(set (reg FLAGS_REG)
8362 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8363 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8364 (const_int 0)))
8365 (set (match_operand:DI 0 "register_operand" "=r")
8366 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8367 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8368 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8369 "<logic>{l}\t{%2, %k0|%k0, %2}"
8370 [(set_attr "type" "alu")
8371 (set_attr "mode" "SI")])
8372
8373 (define_insn "*<code>si_2_zext_imm"
8374 [(set (reg FLAGS_REG)
8375 (compare (any_or:SI
8376 (match_operand:SI 1 "nonimmediate_operand" "%0")
8377 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8378 (const_int 0)))
8379 (set (match_operand:DI 0 "register_operand" "=r")
8380 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8381 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8382 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8383 "<logic>{l}\t{%2, %k0|%k0, %2}"
8384 [(set_attr "type" "alu")
8385 (set_attr "mode" "SI")])
8386
8387 (define_insn "*<code>qi_2_slp"
8388 [(set (reg FLAGS_REG)
8389 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8390 (match_operand:QI 1 "general_operand" "qmn,qn"))
8391 (const_int 0)))
8392 (set (strict_low_part (match_dup 0))
8393 (any_or:QI (match_dup 0) (match_dup 1)))]
8394 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8395 && ix86_match_ccmode (insn, CCNOmode)
8396 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8397 "<logic>{b}\t{%1, %0|%0, %1}"
8398 [(set_attr "type" "alu1")
8399 (set_attr "mode" "QI")])
8400
8401 (define_insn "*<code><mode>_3"
8402 [(set (reg FLAGS_REG)
8403 (compare (any_or:SWI
8404 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8405 (match_operand:SWI 2 "<general_operand>" "<g>"))
8406 (const_int 0)))
8407 (clobber (match_scratch:SWI 0 "=<r>"))]
8408 "ix86_match_ccmode (insn, CCNOmode)
8409 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8410 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8411 [(set_attr "type" "alu")
8412 (set_attr "mode" "<MODE>")])
8413
8414 (define_insn "*<code>qi_ext_0"
8415 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8416 (const_int 8)
8417 (const_int 8))
8418 (any_or:SI
8419 (zero_extract:SI
8420 (match_operand 1 "ext_register_operand" "0")
8421 (const_int 8)
8422 (const_int 8))
8423 (match_operand 2 "const_int_operand" "n")))
8424 (clobber (reg:CC FLAGS_REG))]
8425 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8426 "<logic>{b}\t{%2, %h0|%h0, %2}"
8427 [(set_attr "type" "alu")
8428 (set_attr "length_immediate" "1")
8429 (set_attr "modrm" "1")
8430 (set_attr "mode" "QI")])
8431
8432 (define_insn "*<code>qi_ext_1_rex64"
8433 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8434 (const_int 8)
8435 (const_int 8))
8436 (any_or:SI
8437 (zero_extract:SI
8438 (match_operand 1 "ext_register_operand" "0")
8439 (const_int 8)
8440 (const_int 8))
8441 (zero_extend:SI
8442 (match_operand 2 "ext_register_operand" "Q"))))
8443 (clobber (reg:CC FLAGS_REG))]
8444 "TARGET_64BIT
8445 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8446 "<logic>{b}\t{%2, %h0|%h0, %2}"
8447 [(set_attr "type" "alu")
8448 (set_attr "length_immediate" "0")
8449 (set_attr "mode" "QI")])
8450
8451 (define_insn "*<code>qi_ext_1"
8452 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8453 (const_int 8)
8454 (const_int 8))
8455 (any_or:SI
8456 (zero_extract:SI
8457 (match_operand 1 "ext_register_operand" "0")
8458 (const_int 8)
8459 (const_int 8))
8460 (zero_extend:SI
8461 (match_operand:QI 2 "general_operand" "Qm"))))
8462 (clobber (reg:CC FLAGS_REG))]
8463 "!TARGET_64BIT
8464 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8465 "<logic>{b}\t{%2, %h0|%h0, %2}"
8466 [(set_attr "type" "alu")
8467 (set_attr "length_immediate" "0")
8468 (set_attr "mode" "QI")])
8469
8470 (define_insn "*<code>qi_ext_2"
8471 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8472 (const_int 8)
8473 (const_int 8))
8474 (any_or:SI
8475 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8476 (const_int 8)
8477 (const_int 8))
8478 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8479 (const_int 8)
8480 (const_int 8))))
8481 (clobber (reg:CC FLAGS_REG))]
8482 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8483 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8484 [(set_attr "type" "alu")
8485 (set_attr "length_immediate" "0")
8486 (set_attr "mode" "QI")])
8487
8488 (define_split
8489 [(set (match_operand 0 "register_operand")
8490 (any_or (match_operand 1 "register_operand")
8491 (match_operand 2 "const_int_operand")))
8492 (clobber (reg:CC FLAGS_REG))]
8493 "reload_completed
8494 && QI_REG_P (operands[0])
8495 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8496 && !(INTVAL (operands[2]) & ~(255 << 8))
8497 && GET_MODE (operands[0]) != QImode"
8498 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8499 (any_or:SI (zero_extract:SI (match_dup 1)
8500 (const_int 8) (const_int 8))
8501 (match_dup 2)))
8502 (clobber (reg:CC FLAGS_REG))])]
8503 {
8504 operands[0] = gen_lowpart (SImode, operands[0]);
8505 operands[1] = gen_lowpart (SImode, operands[1]);
8506 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8507 })
8508
8509 ;; Since OR can be encoded with sign extended immediate, this is only
8510 ;; profitable when 7th bit is set.
8511 (define_split
8512 [(set (match_operand 0 "register_operand")
8513 (any_or (match_operand 1 "general_operand")
8514 (match_operand 2 "const_int_operand")))
8515 (clobber (reg:CC FLAGS_REG))]
8516 "reload_completed
8517 && ANY_QI_REG_P (operands[0])
8518 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8519 && !(INTVAL (operands[2]) & ~255)
8520 && (INTVAL (operands[2]) & 128)
8521 && GET_MODE (operands[0]) != QImode"
8522 [(parallel [(set (strict_low_part (match_dup 0))
8523 (any_or:QI (match_dup 1)
8524 (match_dup 2)))
8525 (clobber (reg:CC FLAGS_REG))])]
8526 {
8527 operands[0] = gen_lowpart (QImode, operands[0]);
8528 operands[1] = gen_lowpart (QImode, operands[1]);
8529 operands[2] = gen_lowpart (QImode, operands[2]);
8530 })
8531
8532 (define_expand "xorqi_cc_ext_1"
8533 [(parallel [
8534 (set (reg:CCNO FLAGS_REG)
8535 (compare:CCNO
8536 (xor:SI
8537 (zero_extract:SI
8538 (match_operand 1 "ext_register_operand")
8539 (const_int 8)
8540 (const_int 8))
8541 (match_operand:QI 2 "general_operand"))
8542 (const_int 0)))
8543 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8544 (const_int 8)
8545 (const_int 8))
8546 (xor:SI
8547 (zero_extract:SI
8548 (match_dup 1)
8549 (const_int 8)
8550 (const_int 8))
8551 (match_dup 2)))])])
8552
8553 (define_insn "*xorqi_cc_ext_1_rex64"
8554 [(set (reg FLAGS_REG)
8555 (compare
8556 (xor:SI
8557 (zero_extract:SI
8558 (match_operand 1 "ext_register_operand" "0")
8559 (const_int 8)
8560 (const_int 8))
8561 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8562 (const_int 0)))
8563 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8564 (const_int 8)
8565 (const_int 8))
8566 (xor:SI
8567 (zero_extract:SI
8568 (match_dup 1)
8569 (const_int 8)
8570 (const_int 8))
8571 (match_dup 2)))]
8572 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8573 "xor{b}\t{%2, %h0|%h0, %2}"
8574 [(set_attr "type" "alu")
8575 (set_attr "modrm" "1")
8576 (set_attr "mode" "QI")])
8577
8578 (define_insn "*xorqi_cc_ext_1"
8579 [(set (reg FLAGS_REG)
8580 (compare
8581 (xor:SI
8582 (zero_extract:SI
8583 (match_operand 1 "ext_register_operand" "0")
8584 (const_int 8)
8585 (const_int 8))
8586 (match_operand:QI 2 "general_operand" "qmn"))
8587 (const_int 0)))
8588 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8589 (const_int 8)
8590 (const_int 8))
8591 (xor:SI
8592 (zero_extract:SI
8593 (match_dup 1)
8594 (const_int 8)
8595 (const_int 8))
8596 (match_dup 2)))]
8597 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8598 "xor{b}\t{%2, %h0|%h0, %2}"
8599 [(set_attr "type" "alu")
8600 (set_attr "modrm" "1")
8601 (set_attr "mode" "QI")])
8602 \f
8603 ;; Negation instructions
8604
8605 (define_expand "neg<mode>2"
8606 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8607 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8608 ""
8609 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8610
8611 (define_insn_and_split "*neg<dwi>2_doubleword"
8612 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8613 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8614 (clobber (reg:CC FLAGS_REG))]
8615 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8616 "#"
8617 "reload_completed"
8618 [(parallel
8619 [(set (reg:CCZ FLAGS_REG)
8620 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8621 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8622 (parallel
8623 [(set (match_dup 2)
8624 (plus:DWIH (match_dup 3)
8625 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8626 (const_int 0))))
8627 (clobber (reg:CC FLAGS_REG))])
8628 (parallel
8629 [(set (match_dup 2)
8630 (neg:DWIH (match_dup 2)))
8631 (clobber (reg:CC FLAGS_REG))])]
8632 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8633
8634 (define_insn "*neg<mode>2_1"
8635 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8636 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8637 (clobber (reg:CC FLAGS_REG))]
8638 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8639 "neg{<imodesuffix>}\t%0"
8640 [(set_attr "type" "negnot")
8641 (set_attr "mode" "<MODE>")])
8642
8643 ;; Combine is quite creative about this pattern.
8644 (define_insn "*negsi2_1_zext"
8645 [(set (match_operand:DI 0 "register_operand" "=r")
8646 (lshiftrt:DI
8647 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8648 (const_int 32)))
8649 (const_int 32)))
8650 (clobber (reg:CC FLAGS_REG))]
8651 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8652 "neg{l}\t%k0"
8653 [(set_attr "type" "negnot")
8654 (set_attr "mode" "SI")])
8655
8656 ;; The problem with neg is that it does not perform (compare x 0),
8657 ;; it really performs (compare 0 x), which leaves us with the zero
8658 ;; flag being the only useful item.
8659
8660 (define_insn "*neg<mode>2_cmpz"
8661 [(set (reg:CCZ FLAGS_REG)
8662 (compare:CCZ
8663 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8664 (const_int 0)))
8665 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8666 (neg:SWI (match_dup 1)))]
8667 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8668 "neg{<imodesuffix>}\t%0"
8669 [(set_attr "type" "negnot")
8670 (set_attr "mode" "<MODE>")])
8671
8672 (define_insn "*negsi2_cmpz_zext"
8673 [(set (reg:CCZ FLAGS_REG)
8674 (compare:CCZ
8675 (lshiftrt:DI
8676 (neg:DI (ashift:DI
8677 (match_operand:DI 1 "register_operand" "0")
8678 (const_int 32)))
8679 (const_int 32))
8680 (const_int 0)))
8681 (set (match_operand:DI 0 "register_operand" "=r")
8682 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8683 (const_int 32)))
8684 (const_int 32)))]
8685 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8686 "neg{l}\t%k0"
8687 [(set_attr "type" "negnot")
8688 (set_attr "mode" "SI")])
8689
8690 ;; Changing of sign for FP values is doable using integer unit too.
8691
8692 (define_expand "<code><mode>2"
8693 [(set (match_operand:X87MODEF 0 "register_operand")
8694 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8695 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8696 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8697
8698 (define_insn "*absneg<mode>2_mixed"
8699 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8700 (match_operator:MODEF 3 "absneg_operator"
8701 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8702 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8703 (clobber (reg:CC FLAGS_REG))]
8704 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8705 "#")
8706
8707 (define_insn "*absneg<mode>2_sse"
8708 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8709 (match_operator:MODEF 3 "absneg_operator"
8710 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8711 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8712 (clobber (reg:CC FLAGS_REG))]
8713 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8714 "#")
8715
8716 (define_insn "*absneg<mode>2_i387"
8717 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8718 (match_operator:X87MODEF 3 "absneg_operator"
8719 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8720 (use (match_operand 2))
8721 (clobber (reg:CC FLAGS_REG))]
8722 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8723 "#")
8724
8725 (define_expand "<code>tf2"
8726 [(set (match_operand:TF 0 "register_operand")
8727 (absneg:TF (match_operand:TF 1 "register_operand")))]
8728 "TARGET_SSE"
8729 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8730
8731 (define_insn "*absnegtf2_sse"
8732 [(set (match_operand:TF 0 "register_operand" "=x,x")
8733 (match_operator:TF 3 "absneg_operator"
8734 [(match_operand:TF 1 "register_operand" "0,x")]))
8735 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8736 (clobber (reg:CC FLAGS_REG))]
8737 "TARGET_SSE"
8738 "#")
8739
8740 ;; Splitters for fp abs and neg.
8741
8742 (define_split
8743 [(set (match_operand 0 "fp_register_operand")
8744 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8745 (use (match_operand 2))
8746 (clobber (reg:CC FLAGS_REG))]
8747 "reload_completed"
8748 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8749
8750 (define_split
8751 [(set (match_operand 0 "register_operand")
8752 (match_operator 3 "absneg_operator"
8753 [(match_operand 1 "register_operand")]))
8754 (use (match_operand 2 "nonimmediate_operand"))
8755 (clobber (reg:CC FLAGS_REG))]
8756 "reload_completed && SSE_REG_P (operands[0])"
8757 [(set (match_dup 0) (match_dup 3))]
8758 {
8759 enum machine_mode mode = GET_MODE (operands[0]);
8760 enum machine_mode vmode = GET_MODE (operands[2]);
8761 rtx tmp;
8762
8763 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8764 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8765 if (operands_match_p (operands[0], operands[2]))
8766 {
8767 tmp = operands[1];
8768 operands[1] = operands[2];
8769 operands[2] = tmp;
8770 }
8771 if (GET_CODE (operands[3]) == ABS)
8772 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8773 else
8774 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8775 operands[3] = tmp;
8776 })
8777
8778 (define_split
8779 [(set (match_operand:SF 0 "register_operand")
8780 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8781 (use (match_operand:V4SF 2))
8782 (clobber (reg:CC FLAGS_REG))]
8783 "reload_completed"
8784 [(parallel [(set (match_dup 0) (match_dup 1))
8785 (clobber (reg:CC FLAGS_REG))])]
8786 {
8787 rtx tmp;
8788 operands[0] = gen_lowpart (SImode, operands[0]);
8789 if (GET_CODE (operands[1]) == ABS)
8790 {
8791 tmp = gen_int_mode (0x7fffffff, SImode);
8792 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8793 }
8794 else
8795 {
8796 tmp = gen_int_mode (0x80000000, SImode);
8797 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8798 }
8799 operands[1] = tmp;
8800 })
8801
8802 (define_split
8803 [(set (match_operand:DF 0 "register_operand")
8804 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8805 (use (match_operand 2))
8806 (clobber (reg:CC FLAGS_REG))]
8807 "reload_completed"
8808 [(parallel [(set (match_dup 0) (match_dup 1))
8809 (clobber (reg:CC FLAGS_REG))])]
8810 {
8811 rtx tmp;
8812 if (TARGET_64BIT)
8813 {
8814 tmp = gen_lowpart (DImode, operands[0]);
8815 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8816 operands[0] = tmp;
8817
8818 if (GET_CODE (operands[1]) == ABS)
8819 tmp = const0_rtx;
8820 else
8821 tmp = gen_rtx_NOT (DImode, tmp);
8822 }
8823 else
8824 {
8825 operands[0] = gen_highpart (SImode, operands[0]);
8826 if (GET_CODE (operands[1]) == ABS)
8827 {
8828 tmp = gen_int_mode (0x7fffffff, SImode);
8829 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8830 }
8831 else
8832 {
8833 tmp = gen_int_mode (0x80000000, SImode);
8834 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8835 }
8836 }
8837 operands[1] = tmp;
8838 })
8839
8840 (define_split
8841 [(set (match_operand:XF 0 "register_operand")
8842 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8843 (use (match_operand 2))
8844 (clobber (reg:CC FLAGS_REG))]
8845 "reload_completed"
8846 [(parallel [(set (match_dup 0) (match_dup 1))
8847 (clobber (reg:CC FLAGS_REG))])]
8848 {
8849 rtx tmp;
8850 operands[0] = gen_rtx_REG (SImode,
8851 true_regnum (operands[0])
8852 + (TARGET_64BIT ? 1 : 2));
8853 if (GET_CODE (operands[1]) == ABS)
8854 {
8855 tmp = GEN_INT (0x7fff);
8856 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8857 }
8858 else
8859 {
8860 tmp = GEN_INT (0x8000);
8861 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8862 }
8863 operands[1] = tmp;
8864 })
8865
8866 ;; Conditionalize these after reload. If they match before reload, we
8867 ;; lose the clobber and ability to use integer instructions.
8868
8869 (define_insn "*<code><mode>2_1"
8870 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8871 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8872 "TARGET_80387
8873 && (reload_completed
8874 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8875 "f<absneg_mnemonic>"
8876 [(set_attr "type" "fsgn")
8877 (set_attr "mode" "<MODE>")])
8878
8879 (define_insn "*<code>extendsfdf2"
8880 [(set (match_operand:DF 0 "register_operand" "=f")
8881 (absneg:DF (float_extend:DF
8882 (match_operand:SF 1 "register_operand" "0"))))]
8883 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8884 "f<absneg_mnemonic>"
8885 [(set_attr "type" "fsgn")
8886 (set_attr "mode" "DF")])
8887
8888 (define_insn "*<code>extendsfxf2"
8889 [(set (match_operand:XF 0 "register_operand" "=f")
8890 (absneg:XF (float_extend:XF
8891 (match_operand:SF 1 "register_operand" "0"))))]
8892 "TARGET_80387"
8893 "f<absneg_mnemonic>"
8894 [(set_attr "type" "fsgn")
8895 (set_attr "mode" "XF")])
8896
8897 (define_insn "*<code>extenddfxf2"
8898 [(set (match_operand:XF 0 "register_operand" "=f")
8899 (absneg:XF (float_extend:XF
8900 (match_operand:DF 1 "register_operand" "0"))))]
8901 "TARGET_80387"
8902 "f<absneg_mnemonic>"
8903 [(set_attr "type" "fsgn")
8904 (set_attr "mode" "XF")])
8905
8906 ;; Copysign instructions
8907
8908 (define_mode_iterator CSGNMODE [SF DF TF])
8909 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8910
8911 (define_expand "copysign<mode>3"
8912 [(match_operand:CSGNMODE 0 "register_operand")
8913 (match_operand:CSGNMODE 1 "nonmemory_operand")
8914 (match_operand:CSGNMODE 2 "register_operand")]
8915 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8916 || (TARGET_SSE && (<MODE>mode == TFmode))"
8917 "ix86_expand_copysign (operands); DONE;")
8918
8919 (define_insn_and_split "copysign<mode>3_const"
8920 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8921 (unspec:CSGNMODE
8922 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8923 (match_operand:CSGNMODE 2 "register_operand" "0")
8924 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8925 UNSPEC_COPYSIGN))]
8926 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8927 || (TARGET_SSE && (<MODE>mode == TFmode))"
8928 "#"
8929 "&& reload_completed"
8930 [(const_int 0)]
8931 "ix86_split_copysign_const (operands); DONE;")
8932
8933 (define_insn "copysign<mode>3_var"
8934 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8935 (unspec:CSGNMODE
8936 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8937 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8938 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8939 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8940 UNSPEC_COPYSIGN))
8941 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8942 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8943 || (TARGET_SSE && (<MODE>mode == TFmode))"
8944 "#")
8945
8946 (define_split
8947 [(set (match_operand:CSGNMODE 0 "register_operand")
8948 (unspec:CSGNMODE
8949 [(match_operand:CSGNMODE 2 "register_operand")
8950 (match_operand:CSGNMODE 3 "register_operand")
8951 (match_operand:<CSGNVMODE> 4)
8952 (match_operand:<CSGNVMODE> 5)]
8953 UNSPEC_COPYSIGN))
8954 (clobber (match_scratch:<CSGNVMODE> 1))]
8955 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8956 || (TARGET_SSE && (<MODE>mode == TFmode)))
8957 && reload_completed"
8958 [(const_int 0)]
8959 "ix86_split_copysign_var (operands); DONE;")
8960 \f
8961 ;; One complement instructions
8962
8963 (define_expand "one_cmpl<mode>2"
8964 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8965 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8966 ""
8967 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8968
8969 (define_insn "*one_cmpl<mode>2_1"
8970 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8971 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8972 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8973 "not{<imodesuffix>}\t%0"
8974 [(set_attr "type" "negnot")
8975 (set_attr "mode" "<MODE>")])
8976
8977 ;; %%% Potential partial reg stall on alternative 1. What to do?
8978 (define_insn "*one_cmplqi2_1"
8979 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8980 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8981 "ix86_unary_operator_ok (NOT, QImode, operands)"
8982 "@
8983 not{b}\t%0
8984 not{l}\t%k0"
8985 [(set_attr "type" "negnot")
8986 (set_attr "mode" "QI,SI")])
8987
8988 ;; ??? Currently never generated - xor is used instead.
8989 (define_insn "*one_cmplsi2_1_zext"
8990 [(set (match_operand:DI 0 "register_operand" "=r")
8991 (zero_extend:DI
8992 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8993 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8994 "not{l}\t%k0"
8995 [(set_attr "type" "negnot")
8996 (set_attr "mode" "SI")])
8997
8998 (define_insn "*one_cmpl<mode>2_2"
8999 [(set (reg FLAGS_REG)
9000 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9001 (const_int 0)))
9002 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9003 (not:SWI (match_dup 1)))]
9004 "ix86_match_ccmode (insn, CCNOmode)
9005 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9006 "#"
9007 [(set_attr "type" "alu1")
9008 (set_attr "mode" "<MODE>")])
9009
9010 (define_split
9011 [(set (match_operand 0 "flags_reg_operand")
9012 (match_operator 2 "compare_operator"
9013 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9014 (const_int 0)]))
9015 (set (match_operand:SWI 1 "nonimmediate_operand")
9016 (not:SWI (match_dup 3)))]
9017 "ix86_match_ccmode (insn, CCNOmode)"
9018 [(parallel [(set (match_dup 0)
9019 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9020 (const_int 0)]))
9021 (set (match_dup 1)
9022 (xor:SWI (match_dup 3) (const_int -1)))])])
9023
9024 ;; ??? Currently never generated - xor is used instead.
9025 (define_insn "*one_cmplsi2_2_zext"
9026 [(set (reg FLAGS_REG)
9027 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9028 (const_int 0)))
9029 (set (match_operand:DI 0 "register_operand" "=r")
9030 (zero_extend:DI (not:SI (match_dup 1))))]
9031 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9032 && ix86_unary_operator_ok (NOT, SImode, operands)"
9033 "#"
9034 [(set_attr "type" "alu1")
9035 (set_attr "mode" "SI")])
9036
9037 (define_split
9038 [(set (match_operand 0 "flags_reg_operand")
9039 (match_operator 2 "compare_operator"
9040 [(not:SI (match_operand:SI 3 "register_operand"))
9041 (const_int 0)]))
9042 (set (match_operand:DI 1 "register_operand")
9043 (zero_extend:DI (not:SI (match_dup 3))))]
9044 "ix86_match_ccmode (insn, CCNOmode)"
9045 [(parallel [(set (match_dup 0)
9046 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9047 (const_int 0)]))
9048 (set (match_dup 1)
9049 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9050 \f
9051 ;; Shift instructions
9052
9053 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9054 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9055 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9056 ;; from the assembler input.
9057 ;;
9058 ;; This instruction shifts the target reg/mem as usual, but instead of
9059 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9060 ;; is a left shift double, bits are taken from the high order bits of
9061 ;; reg, else if the insn is a shift right double, bits are taken from the
9062 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9063 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9064 ;;
9065 ;; Since sh[lr]d does not change the `reg' operand, that is done
9066 ;; separately, making all shifts emit pairs of shift double and normal
9067 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9068 ;; support a 63 bit shift, each shift where the count is in a reg expands
9069 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9070 ;;
9071 ;; If the shift count is a constant, we need never emit more than one
9072 ;; shift pair, instead using moves and sign extension for counts greater
9073 ;; than 31.
9074
9075 (define_expand "ashl<mode>3"
9076 [(set (match_operand:SDWIM 0 "<shift_operand>")
9077 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9078 (match_operand:QI 2 "nonmemory_operand")))]
9079 ""
9080 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9081
9082 (define_insn "*ashl<mode>3_doubleword"
9083 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9084 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9085 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9086 (clobber (reg:CC FLAGS_REG))]
9087 ""
9088 "#"
9089 [(set_attr "type" "multi")])
9090
9091 (define_split
9092 [(set (match_operand:DWI 0 "register_operand")
9093 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9094 (match_operand:QI 2 "nonmemory_operand")))
9095 (clobber (reg:CC FLAGS_REG))]
9096 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9097 [(const_int 0)]
9098 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9099
9100 ;; By default we don't ask for a scratch register, because when DWImode
9101 ;; values are manipulated, registers are already at a premium. But if
9102 ;; we have one handy, we won't turn it away.
9103
9104 (define_peephole2
9105 [(match_scratch:DWIH 3 "r")
9106 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9107 (ashift:<DWI>
9108 (match_operand:<DWI> 1 "nonmemory_operand")
9109 (match_operand:QI 2 "nonmemory_operand")))
9110 (clobber (reg:CC FLAGS_REG))])
9111 (match_dup 3)]
9112 "TARGET_CMOVE"
9113 [(const_int 0)]
9114 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9115
9116 (define_insn "x86_64_shld"
9117 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9118 (ior:DI (ashift:DI (match_dup 0)
9119 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9120 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9121 (minus:QI (const_int 64) (match_dup 2)))))
9122 (clobber (reg:CC FLAGS_REG))]
9123 "TARGET_64BIT"
9124 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9125 [(set_attr "type" "ishift")
9126 (set_attr "prefix_0f" "1")
9127 (set_attr "mode" "DI")
9128 (set_attr "athlon_decode" "vector")
9129 (set_attr "amdfam10_decode" "vector")
9130 (set_attr "bdver1_decode" "vector")])
9131
9132 (define_insn "x86_shld"
9133 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9134 (ior:SI (ashift:SI (match_dup 0)
9135 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9136 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9137 (minus:QI (const_int 32) (match_dup 2)))))
9138 (clobber (reg:CC FLAGS_REG))]
9139 ""
9140 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9141 [(set_attr "type" "ishift")
9142 (set_attr "prefix_0f" "1")
9143 (set_attr "mode" "SI")
9144 (set_attr "pent_pair" "np")
9145 (set_attr "athlon_decode" "vector")
9146 (set_attr "amdfam10_decode" "vector")
9147 (set_attr "bdver1_decode" "vector")])
9148
9149 (define_expand "x86_shift<mode>_adj_1"
9150 [(set (reg:CCZ FLAGS_REG)
9151 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9152 (match_dup 4))
9153 (const_int 0)))
9154 (set (match_operand:SWI48 0 "register_operand")
9155 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9156 (match_operand:SWI48 1 "register_operand")
9157 (match_dup 0)))
9158 (set (match_dup 1)
9159 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9160 (match_operand:SWI48 3 "register_operand")
9161 (match_dup 1)))]
9162 "TARGET_CMOVE"
9163 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9164
9165 (define_expand "x86_shift<mode>_adj_2"
9166 [(use (match_operand:SWI48 0 "register_operand"))
9167 (use (match_operand:SWI48 1 "register_operand"))
9168 (use (match_operand:QI 2 "register_operand"))]
9169 ""
9170 {
9171 rtx label = gen_label_rtx ();
9172 rtx tmp;
9173
9174 emit_insn (gen_testqi_ccz_1 (operands[2],
9175 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9176
9177 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9178 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9179 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9180 gen_rtx_LABEL_REF (VOIDmode, label),
9181 pc_rtx);
9182 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9183 JUMP_LABEL (tmp) = label;
9184
9185 emit_move_insn (operands[0], operands[1]);
9186 ix86_expand_clear (operands[1]);
9187
9188 emit_label (label);
9189 LABEL_NUSES (label) = 1;
9190
9191 DONE;
9192 })
9193
9194 ;; Avoid useless masking of count operand.
9195 (define_insn_and_split "*ashl<mode>3_mask"
9196 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9197 (ashift:SWI48
9198 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9199 (subreg:QI
9200 (and:SI
9201 (match_operand:SI 2 "nonimmediate_operand" "c")
9202 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9203 (clobber (reg:CC FLAGS_REG))]
9204 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9205 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9206 == GET_MODE_BITSIZE (<MODE>mode)-1"
9207 "#"
9208 "&& 1"
9209 [(parallel [(set (match_dup 0)
9210 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9211 (clobber (reg:CC FLAGS_REG))])]
9212 {
9213 if (can_create_pseudo_p ())
9214 operands [2] = force_reg (SImode, operands[2]);
9215
9216 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9217 }
9218 [(set_attr "type" "ishift")
9219 (set_attr "mode" "<MODE>")])
9220
9221 (define_insn "*bmi2_ashl<mode>3_1"
9222 [(set (match_operand:SWI48 0 "register_operand" "=r")
9223 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9224 (match_operand:SWI48 2 "register_operand" "r")))]
9225 "TARGET_BMI2"
9226 "shlx\t{%2, %1, %0|%0, %1, %2}"
9227 [(set_attr "type" "ishiftx")
9228 (set_attr "mode" "<MODE>")])
9229
9230 (define_insn "*ashl<mode>3_1"
9231 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9232 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9233 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9234 (clobber (reg:CC FLAGS_REG))]
9235 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9236 {
9237 switch (get_attr_type (insn))
9238 {
9239 case TYPE_LEA:
9240 case TYPE_ISHIFTX:
9241 return "#";
9242
9243 case TYPE_ALU:
9244 gcc_assert (operands[2] == const1_rtx);
9245 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9246 return "add{<imodesuffix>}\t%0, %0";
9247
9248 default:
9249 if (operands[2] == const1_rtx
9250 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9251 return "sal{<imodesuffix>}\t%0";
9252 else
9253 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9254 }
9255 }
9256 [(set_attr "isa" "*,*,bmi2")
9257 (set (attr "type")
9258 (cond [(eq_attr "alternative" "1")
9259 (const_string "lea")
9260 (eq_attr "alternative" "2")
9261 (const_string "ishiftx")
9262 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9263 (match_operand 0 "register_operand"))
9264 (match_operand 2 "const1_operand"))
9265 (const_string "alu")
9266 ]
9267 (const_string "ishift")))
9268 (set (attr "length_immediate")
9269 (if_then_else
9270 (ior (eq_attr "type" "alu")
9271 (and (eq_attr "type" "ishift")
9272 (and (match_operand 2 "const1_operand")
9273 (ior (match_test "TARGET_SHIFT1")
9274 (match_test "optimize_function_for_size_p (cfun)")))))
9275 (const_string "0")
9276 (const_string "*")))
9277 (set_attr "mode" "<MODE>")])
9278
9279 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9280 (define_split
9281 [(set (match_operand:SWI48 0 "register_operand")
9282 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9283 (match_operand:QI 2 "register_operand")))
9284 (clobber (reg:CC FLAGS_REG))]
9285 "TARGET_BMI2 && reload_completed"
9286 [(set (match_dup 0)
9287 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9288 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9289
9290 (define_insn "*bmi2_ashlsi3_1_zext"
9291 [(set (match_operand:DI 0 "register_operand" "=r")
9292 (zero_extend:DI
9293 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9294 (match_operand:SI 2 "register_operand" "r"))))]
9295 "TARGET_64BIT && TARGET_BMI2"
9296 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9297 [(set_attr "type" "ishiftx")
9298 (set_attr "mode" "SI")])
9299
9300 (define_insn "*ashlsi3_1_zext"
9301 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9302 (zero_extend:DI
9303 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9304 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9305 (clobber (reg:CC FLAGS_REG))]
9306 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9307 {
9308 switch (get_attr_type (insn))
9309 {
9310 case TYPE_LEA:
9311 case TYPE_ISHIFTX:
9312 return "#";
9313
9314 case TYPE_ALU:
9315 gcc_assert (operands[2] == const1_rtx);
9316 return "add{l}\t%k0, %k0";
9317
9318 default:
9319 if (operands[2] == const1_rtx
9320 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9321 return "sal{l}\t%k0";
9322 else
9323 return "sal{l}\t{%2, %k0|%k0, %2}";
9324 }
9325 }
9326 [(set_attr "isa" "*,*,bmi2")
9327 (set (attr "type")
9328 (cond [(eq_attr "alternative" "1")
9329 (const_string "lea")
9330 (eq_attr "alternative" "2")
9331 (const_string "ishiftx")
9332 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9333 (match_operand 2 "const1_operand"))
9334 (const_string "alu")
9335 ]
9336 (const_string "ishift")))
9337 (set (attr "length_immediate")
9338 (if_then_else
9339 (ior (eq_attr "type" "alu")
9340 (and (eq_attr "type" "ishift")
9341 (and (match_operand 2 "const1_operand")
9342 (ior (match_test "TARGET_SHIFT1")
9343 (match_test "optimize_function_for_size_p (cfun)")))))
9344 (const_string "0")
9345 (const_string "*")))
9346 (set_attr "mode" "SI")])
9347
9348 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9349 (define_split
9350 [(set (match_operand:DI 0 "register_operand")
9351 (zero_extend:DI
9352 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9353 (match_operand:QI 2 "register_operand"))))
9354 (clobber (reg:CC FLAGS_REG))]
9355 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9356 [(set (match_dup 0)
9357 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9358 "operands[2] = gen_lowpart (SImode, operands[2]);")
9359
9360 (define_insn "*ashlhi3_1"
9361 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9362 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9363 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9364 (clobber (reg:CC FLAGS_REG))]
9365 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9366 {
9367 switch (get_attr_type (insn))
9368 {
9369 case TYPE_LEA:
9370 return "#";
9371
9372 case TYPE_ALU:
9373 gcc_assert (operands[2] == const1_rtx);
9374 return "add{w}\t%0, %0";
9375
9376 default:
9377 if (operands[2] == const1_rtx
9378 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9379 return "sal{w}\t%0";
9380 else
9381 return "sal{w}\t{%2, %0|%0, %2}";
9382 }
9383 }
9384 [(set (attr "type")
9385 (cond [(eq_attr "alternative" "1")
9386 (const_string "lea")
9387 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9388 (match_operand 0 "register_operand"))
9389 (match_operand 2 "const1_operand"))
9390 (const_string "alu")
9391 ]
9392 (const_string "ishift")))
9393 (set (attr "length_immediate")
9394 (if_then_else
9395 (ior (eq_attr "type" "alu")
9396 (and (eq_attr "type" "ishift")
9397 (and (match_operand 2 "const1_operand")
9398 (ior (match_test "TARGET_SHIFT1")
9399 (match_test "optimize_function_for_size_p (cfun)")))))
9400 (const_string "0")
9401 (const_string "*")))
9402 (set_attr "mode" "HI,SI")])
9403
9404 ;; %%% Potential partial reg stall on alternative 1. What to do?
9405 (define_insn "*ashlqi3_1"
9406 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9407 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9408 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9409 (clobber (reg:CC FLAGS_REG))]
9410 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9411 {
9412 switch (get_attr_type (insn))
9413 {
9414 case TYPE_LEA:
9415 return "#";
9416
9417 case TYPE_ALU:
9418 gcc_assert (operands[2] == const1_rtx);
9419 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9420 return "add{l}\t%k0, %k0";
9421 else
9422 return "add{b}\t%0, %0";
9423
9424 default:
9425 if (operands[2] == const1_rtx
9426 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9427 {
9428 if (get_attr_mode (insn) == MODE_SI)
9429 return "sal{l}\t%k0";
9430 else
9431 return "sal{b}\t%0";
9432 }
9433 else
9434 {
9435 if (get_attr_mode (insn) == MODE_SI)
9436 return "sal{l}\t{%2, %k0|%k0, %2}";
9437 else
9438 return "sal{b}\t{%2, %0|%0, %2}";
9439 }
9440 }
9441 }
9442 [(set (attr "type")
9443 (cond [(eq_attr "alternative" "2")
9444 (const_string "lea")
9445 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9446 (match_operand 0 "register_operand"))
9447 (match_operand 2 "const1_operand"))
9448 (const_string "alu")
9449 ]
9450 (const_string "ishift")))
9451 (set (attr "length_immediate")
9452 (if_then_else
9453 (ior (eq_attr "type" "alu")
9454 (and (eq_attr "type" "ishift")
9455 (and (match_operand 2 "const1_operand")
9456 (ior (match_test "TARGET_SHIFT1")
9457 (match_test "optimize_function_for_size_p (cfun)")))))
9458 (const_string "0")
9459 (const_string "*")))
9460 (set_attr "mode" "QI,SI,SI")])
9461
9462 (define_insn "*ashlqi3_1_slp"
9463 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9464 (ashift:QI (match_dup 0)
9465 (match_operand:QI 1 "nonmemory_operand" "cI")))
9466 (clobber (reg:CC FLAGS_REG))]
9467 "(optimize_function_for_size_p (cfun)
9468 || !TARGET_PARTIAL_FLAG_REG_STALL
9469 || (operands[1] == const1_rtx
9470 && (TARGET_SHIFT1
9471 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9472 {
9473 switch (get_attr_type (insn))
9474 {
9475 case TYPE_ALU:
9476 gcc_assert (operands[1] == const1_rtx);
9477 return "add{b}\t%0, %0";
9478
9479 default:
9480 if (operands[1] == const1_rtx
9481 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9482 return "sal{b}\t%0";
9483 else
9484 return "sal{b}\t{%1, %0|%0, %1}";
9485 }
9486 }
9487 [(set (attr "type")
9488 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9489 (match_operand 0 "register_operand"))
9490 (match_operand 1 "const1_operand"))
9491 (const_string "alu")
9492 ]
9493 (const_string "ishift1")))
9494 (set (attr "length_immediate")
9495 (if_then_else
9496 (ior (eq_attr "type" "alu")
9497 (and (eq_attr "type" "ishift1")
9498 (and (match_operand 1 "const1_operand")
9499 (ior (match_test "TARGET_SHIFT1")
9500 (match_test "optimize_function_for_size_p (cfun)")))))
9501 (const_string "0")
9502 (const_string "*")))
9503 (set_attr "mode" "QI")])
9504
9505 ;; Convert ashift to the lea pattern to avoid flags dependency.
9506 (define_split
9507 [(set (match_operand 0 "register_operand")
9508 (ashift (match_operand 1 "index_register_operand")
9509 (match_operand:QI 2 "const_int_operand")))
9510 (clobber (reg:CC FLAGS_REG))]
9511 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9512 && reload_completed
9513 && true_regnum (operands[0]) != true_regnum (operands[1])"
9514 [(const_int 0)]
9515 {
9516 enum machine_mode mode = GET_MODE (operands[0]);
9517 rtx pat;
9518
9519 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9520 {
9521 mode = SImode;
9522 operands[0] = gen_lowpart (mode, operands[0]);
9523 operands[1] = gen_lowpart (mode, operands[1]);
9524 }
9525
9526 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9527
9528 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9529
9530 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9531 DONE;
9532 })
9533
9534 ;; Convert ashift to the lea pattern to avoid flags dependency.
9535 (define_split
9536 [(set (match_operand:DI 0 "register_operand")
9537 (zero_extend:DI
9538 (ashift:SI (match_operand:SI 1 "index_register_operand")
9539 (match_operand:QI 2 "const_int_operand"))))
9540 (clobber (reg:CC FLAGS_REG))]
9541 "TARGET_64BIT && reload_completed
9542 && true_regnum (operands[0]) != true_regnum (operands[1])"
9543 [(set (match_dup 0)
9544 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9545 {
9546 operands[1] = gen_lowpart (DImode, operands[1]);
9547 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9548 })
9549
9550 ;; This pattern can't accept a variable shift count, since shifts by
9551 ;; zero don't affect the flags. We assume that shifts by constant
9552 ;; zero are optimized away.
9553 (define_insn "*ashl<mode>3_cmp"
9554 [(set (reg FLAGS_REG)
9555 (compare
9556 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9557 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9558 (const_int 0)))
9559 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9560 (ashift:SWI (match_dup 1) (match_dup 2)))]
9561 "(optimize_function_for_size_p (cfun)
9562 || !TARGET_PARTIAL_FLAG_REG_STALL
9563 || (operands[2] == const1_rtx
9564 && (TARGET_SHIFT1
9565 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9566 && ix86_match_ccmode (insn, CCGOCmode)
9567 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9568 {
9569 switch (get_attr_type (insn))
9570 {
9571 case TYPE_ALU:
9572 gcc_assert (operands[2] == const1_rtx);
9573 return "add{<imodesuffix>}\t%0, %0";
9574
9575 default:
9576 if (operands[2] == const1_rtx
9577 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9578 return "sal{<imodesuffix>}\t%0";
9579 else
9580 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9581 }
9582 }
9583 [(set (attr "type")
9584 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9585 (match_operand 0 "register_operand"))
9586 (match_operand 2 "const1_operand"))
9587 (const_string "alu")
9588 ]
9589 (const_string "ishift")))
9590 (set (attr "length_immediate")
9591 (if_then_else
9592 (ior (eq_attr "type" "alu")
9593 (and (eq_attr "type" "ishift")
9594 (and (match_operand 2 "const1_operand")
9595 (ior (match_test "TARGET_SHIFT1")
9596 (match_test "optimize_function_for_size_p (cfun)")))))
9597 (const_string "0")
9598 (const_string "*")))
9599 (set_attr "mode" "<MODE>")])
9600
9601 (define_insn "*ashlsi3_cmp_zext"
9602 [(set (reg FLAGS_REG)
9603 (compare
9604 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9605 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9606 (const_int 0)))
9607 (set (match_operand:DI 0 "register_operand" "=r")
9608 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9609 "TARGET_64BIT
9610 && (optimize_function_for_size_p (cfun)
9611 || !TARGET_PARTIAL_FLAG_REG_STALL
9612 || (operands[2] == const1_rtx
9613 && (TARGET_SHIFT1
9614 || TARGET_DOUBLE_WITH_ADD)))
9615 && ix86_match_ccmode (insn, CCGOCmode)
9616 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9617 {
9618 switch (get_attr_type (insn))
9619 {
9620 case TYPE_ALU:
9621 gcc_assert (operands[2] == const1_rtx);
9622 return "add{l}\t%k0, %k0";
9623
9624 default:
9625 if (operands[2] == const1_rtx
9626 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9627 return "sal{l}\t%k0";
9628 else
9629 return "sal{l}\t{%2, %k0|%k0, %2}";
9630 }
9631 }
9632 [(set (attr "type")
9633 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9634 (match_operand 2 "const1_operand"))
9635 (const_string "alu")
9636 ]
9637 (const_string "ishift")))
9638 (set (attr "length_immediate")
9639 (if_then_else
9640 (ior (eq_attr "type" "alu")
9641 (and (eq_attr "type" "ishift")
9642 (and (match_operand 2 "const1_operand")
9643 (ior (match_test "TARGET_SHIFT1")
9644 (match_test "optimize_function_for_size_p (cfun)")))))
9645 (const_string "0")
9646 (const_string "*")))
9647 (set_attr "mode" "SI")])
9648
9649 (define_insn "*ashl<mode>3_cconly"
9650 [(set (reg FLAGS_REG)
9651 (compare
9652 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9653 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9654 (const_int 0)))
9655 (clobber (match_scratch:SWI 0 "=<r>"))]
9656 "(optimize_function_for_size_p (cfun)
9657 || !TARGET_PARTIAL_FLAG_REG_STALL
9658 || (operands[2] == const1_rtx
9659 && (TARGET_SHIFT1
9660 || TARGET_DOUBLE_WITH_ADD)))
9661 && ix86_match_ccmode (insn, CCGOCmode)"
9662 {
9663 switch (get_attr_type (insn))
9664 {
9665 case TYPE_ALU:
9666 gcc_assert (operands[2] == const1_rtx);
9667 return "add{<imodesuffix>}\t%0, %0";
9668
9669 default:
9670 if (operands[2] == const1_rtx
9671 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9672 return "sal{<imodesuffix>}\t%0";
9673 else
9674 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9675 }
9676 }
9677 [(set (attr "type")
9678 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9679 (match_operand 0 "register_operand"))
9680 (match_operand 2 "const1_operand"))
9681 (const_string "alu")
9682 ]
9683 (const_string "ishift")))
9684 (set (attr "length_immediate")
9685 (if_then_else
9686 (ior (eq_attr "type" "alu")
9687 (and (eq_attr "type" "ishift")
9688 (and (match_operand 2 "const1_operand")
9689 (ior (match_test "TARGET_SHIFT1")
9690 (match_test "optimize_function_for_size_p (cfun)")))))
9691 (const_string "0")
9692 (const_string "*")))
9693 (set_attr "mode" "<MODE>")])
9694
9695 ;; See comment above `ashl<mode>3' about how this works.
9696
9697 (define_expand "<shift_insn><mode>3"
9698 [(set (match_operand:SDWIM 0 "<shift_operand>")
9699 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9700 (match_operand:QI 2 "nonmemory_operand")))]
9701 ""
9702 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9703
9704 ;; Avoid useless masking of count operand.
9705 (define_insn_and_split "*<shift_insn><mode>3_mask"
9706 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9707 (any_shiftrt:SWI48
9708 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9709 (subreg:QI
9710 (and:SI
9711 (match_operand:SI 2 "nonimmediate_operand" "c")
9712 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9713 (clobber (reg:CC FLAGS_REG))]
9714 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9715 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9716 == GET_MODE_BITSIZE (<MODE>mode)-1"
9717 "#"
9718 "&& 1"
9719 [(parallel [(set (match_dup 0)
9720 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9721 (clobber (reg:CC FLAGS_REG))])]
9722 {
9723 if (can_create_pseudo_p ())
9724 operands [2] = force_reg (SImode, operands[2]);
9725
9726 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9727 }
9728 [(set_attr "type" "ishift")
9729 (set_attr "mode" "<MODE>")])
9730
9731 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9732 [(set (match_operand:DWI 0 "register_operand" "=r")
9733 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9734 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9735 (clobber (reg:CC FLAGS_REG))]
9736 ""
9737 "#"
9738 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9739 [(const_int 0)]
9740 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9741 [(set_attr "type" "multi")])
9742
9743 ;; By default we don't ask for a scratch register, because when DWImode
9744 ;; values are manipulated, registers are already at a premium. But if
9745 ;; we have one handy, we won't turn it away.
9746
9747 (define_peephole2
9748 [(match_scratch:DWIH 3 "r")
9749 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9750 (any_shiftrt:<DWI>
9751 (match_operand:<DWI> 1 "register_operand")
9752 (match_operand:QI 2 "nonmemory_operand")))
9753 (clobber (reg:CC FLAGS_REG))])
9754 (match_dup 3)]
9755 "TARGET_CMOVE"
9756 [(const_int 0)]
9757 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9758
9759 (define_insn "x86_64_shrd"
9760 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9761 (ior:DI (ashiftrt:DI (match_dup 0)
9762 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9763 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9764 (minus:QI (const_int 64) (match_dup 2)))))
9765 (clobber (reg:CC FLAGS_REG))]
9766 "TARGET_64BIT"
9767 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9768 [(set_attr "type" "ishift")
9769 (set_attr "prefix_0f" "1")
9770 (set_attr "mode" "DI")
9771 (set_attr "athlon_decode" "vector")
9772 (set_attr "amdfam10_decode" "vector")
9773 (set_attr "bdver1_decode" "vector")])
9774
9775 (define_insn "x86_shrd"
9776 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9777 (ior:SI (ashiftrt:SI (match_dup 0)
9778 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9779 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9780 (minus:QI (const_int 32) (match_dup 2)))))
9781 (clobber (reg:CC FLAGS_REG))]
9782 ""
9783 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9784 [(set_attr "type" "ishift")
9785 (set_attr "prefix_0f" "1")
9786 (set_attr "mode" "SI")
9787 (set_attr "pent_pair" "np")
9788 (set_attr "athlon_decode" "vector")
9789 (set_attr "amdfam10_decode" "vector")
9790 (set_attr "bdver1_decode" "vector")])
9791
9792 (define_insn "ashrdi3_cvt"
9793 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9794 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9795 (match_operand:QI 2 "const_int_operand")))
9796 (clobber (reg:CC FLAGS_REG))]
9797 "TARGET_64BIT && INTVAL (operands[2]) == 63
9798 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9799 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9800 "@
9801 {cqto|cqo}
9802 sar{q}\t{%2, %0|%0, %2}"
9803 [(set_attr "type" "imovx,ishift")
9804 (set_attr "prefix_0f" "0,*")
9805 (set_attr "length_immediate" "0,*")
9806 (set_attr "modrm" "0,1")
9807 (set_attr "mode" "DI")])
9808
9809 (define_insn "ashrsi3_cvt"
9810 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9811 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9812 (match_operand:QI 2 "const_int_operand")))
9813 (clobber (reg:CC FLAGS_REG))]
9814 "INTVAL (operands[2]) == 31
9815 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9816 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9817 "@
9818 {cltd|cdq}
9819 sar{l}\t{%2, %0|%0, %2}"
9820 [(set_attr "type" "imovx,ishift")
9821 (set_attr "prefix_0f" "0,*")
9822 (set_attr "length_immediate" "0,*")
9823 (set_attr "modrm" "0,1")
9824 (set_attr "mode" "SI")])
9825
9826 (define_insn "*ashrsi3_cvt_zext"
9827 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9828 (zero_extend:DI
9829 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9830 (match_operand:QI 2 "const_int_operand"))))
9831 (clobber (reg:CC FLAGS_REG))]
9832 "TARGET_64BIT && INTVAL (operands[2]) == 31
9833 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9834 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9835 "@
9836 {cltd|cdq}
9837 sar{l}\t{%2, %k0|%k0, %2}"
9838 [(set_attr "type" "imovx,ishift")
9839 (set_attr "prefix_0f" "0,*")
9840 (set_attr "length_immediate" "0,*")
9841 (set_attr "modrm" "0,1")
9842 (set_attr "mode" "SI")])
9843
9844 (define_expand "x86_shift<mode>_adj_3"
9845 [(use (match_operand:SWI48 0 "register_operand"))
9846 (use (match_operand:SWI48 1 "register_operand"))
9847 (use (match_operand:QI 2 "register_operand"))]
9848 ""
9849 {
9850 rtx label = gen_label_rtx ();
9851 rtx tmp;
9852
9853 emit_insn (gen_testqi_ccz_1 (operands[2],
9854 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9855
9856 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9857 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9858 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9859 gen_rtx_LABEL_REF (VOIDmode, label),
9860 pc_rtx);
9861 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9862 JUMP_LABEL (tmp) = label;
9863
9864 emit_move_insn (operands[0], operands[1]);
9865 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9866 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9867 emit_label (label);
9868 LABEL_NUSES (label) = 1;
9869
9870 DONE;
9871 })
9872
9873 (define_insn "*bmi2_<shift_insn><mode>3_1"
9874 [(set (match_operand:SWI48 0 "register_operand" "=r")
9875 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9876 (match_operand:SWI48 2 "register_operand" "r")))]
9877 "TARGET_BMI2"
9878 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9879 [(set_attr "type" "ishiftx")
9880 (set_attr "mode" "<MODE>")])
9881
9882 (define_insn "*<shift_insn><mode>3_1"
9883 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9884 (any_shiftrt:SWI48
9885 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9886 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9887 (clobber (reg:CC FLAGS_REG))]
9888 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9889 {
9890 switch (get_attr_type (insn))
9891 {
9892 case TYPE_ISHIFTX:
9893 return "#";
9894
9895 default:
9896 if (operands[2] == const1_rtx
9897 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9898 return "<shift>{<imodesuffix>}\t%0";
9899 else
9900 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9901 }
9902 }
9903 [(set_attr "isa" "*,bmi2")
9904 (set_attr "type" "ishift,ishiftx")
9905 (set (attr "length_immediate")
9906 (if_then_else
9907 (and (match_operand 2 "const1_operand")
9908 (ior (match_test "TARGET_SHIFT1")
9909 (match_test "optimize_function_for_size_p (cfun)")))
9910 (const_string "0")
9911 (const_string "*")))
9912 (set_attr "mode" "<MODE>")])
9913
9914 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9915 (define_split
9916 [(set (match_operand:SWI48 0 "register_operand")
9917 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9918 (match_operand:QI 2 "register_operand")))
9919 (clobber (reg:CC FLAGS_REG))]
9920 "TARGET_BMI2 && reload_completed"
9921 [(set (match_dup 0)
9922 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9923 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9924
9925 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9926 [(set (match_operand:DI 0 "register_operand" "=r")
9927 (zero_extend:DI
9928 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9929 (match_operand:SI 2 "register_operand" "r"))))]
9930 "TARGET_64BIT && TARGET_BMI2"
9931 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9932 [(set_attr "type" "ishiftx")
9933 (set_attr "mode" "SI")])
9934
9935 (define_insn "*<shift_insn>si3_1_zext"
9936 [(set (match_operand:DI 0 "register_operand" "=r,r")
9937 (zero_extend:DI
9938 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9939 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9940 (clobber (reg:CC FLAGS_REG))]
9941 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9942 {
9943 switch (get_attr_type (insn))
9944 {
9945 case TYPE_ISHIFTX:
9946 return "#";
9947
9948 default:
9949 if (operands[2] == const1_rtx
9950 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9951 return "<shift>{l}\t%k0";
9952 else
9953 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9954 }
9955 }
9956 [(set_attr "isa" "*,bmi2")
9957 (set_attr "type" "ishift,ishiftx")
9958 (set (attr "length_immediate")
9959 (if_then_else
9960 (and (match_operand 2 "const1_operand")
9961 (ior (match_test "TARGET_SHIFT1")
9962 (match_test "optimize_function_for_size_p (cfun)")))
9963 (const_string "0")
9964 (const_string "*")))
9965 (set_attr "mode" "SI")])
9966
9967 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9968 (define_split
9969 [(set (match_operand:DI 0 "register_operand")
9970 (zero_extend:DI
9971 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9972 (match_operand:QI 2 "register_operand"))))
9973 (clobber (reg:CC FLAGS_REG))]
9974 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9975 [(set (match_dup 0)
9976 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9977 "operands[2] = gen_lowpart (SImode, operands[2]);")
9978
9979 (define_insn "*<shift_insn><mode>3_1"
9980 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9981 (any_shiftrt:SWI12
9982 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9983 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9984 (clobber (reg:CC FLAGS_REG))]
9985 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9986 {
9987 if (operands[2] == const1_rtx
9988 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9989 return "<shift>{<imodesuffix>}\t%0";
9990 else
9991 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9992 }
9993 [(set_attr "type" "ishift")
9994 (set (attr "length_immediate")
9995 (if_then_else
9996 (and (match_operand 2 "const1_operand")
9997 (ior (match_test "TARGET_SHIFT1")
9998 (match_test "optimize_function_for_size_p (cfun)")))
9999 (const_string "0")
10000 (const_string "*")))
10001 (set_attr "mode" "<MODE>")])
10002
10003 (define_insn "*<shift_insn>qi3_1_slp"
10004 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10005 (any_shiftrt:QI (match_dup 0)
10006 (match_operand:QI 1 "nonmemory_operand" "cI")))
10007 (clobber (reg:CC FLAGS_REG))]
10008 "(optimize_function_for_size_p (cfun)
10009 || !TARGET_PARTIAL_REG_STALL
10010 || (operands[1] == const1_rtx
10011 && TARGET_SHIFT1))"
10012 {
10013 if (operands[1] == const1_rtx
10014 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10015 return "<shift>{b}\t%0";
10016 else
10017 return "<shift>{b}\t{%1, %0|%0, %1}";
10018 }
10019 [(set_attr "type" "ishift1")
10020 (set (attr "length_immediate")
10021 (if_then_else
10022 (and (match_operand 1 "const1_operand")
10023 (ior (match_test "TARGET_SHIFT1")
10024 (match_test "optimize_function_for_size_p (cfun)")))
10025 (const_string "0")
10026 (const_string "*")))
10027 (set_attr "mode" "QI")])
10028
10029 ;; This pattern can't accept a variable shift count, since shifts by
10030 ;; zero don't affect the flags. We assume that shifts by constant
10031 ;; zero are optimized away.
10032 (define_insn "*<shift_insn><mode>3_cmp"
10033 [(set (reg FLAGS_REG)
10034 (compare
10035 (any_shiftrt:SWI
10036 (match_operand:SWI 1 "nonimmediate_operand" "0")
10037 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10038 (const_int 0)))
10039 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10040 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10041 "(optimize_function_for_size_p (cfun)
10042 || !TARGET_PARTIAL_FLAG_REG_STALL
10043 || (operands[2] == const1_rtx
10044 && TARGET_SHIFT1))
10045 && ix86_match_ccmode (insn, CCGOCmode)
10046 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10047 {
10048 if (operands[2] == const1_rtx
10049 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10050 return "<shift>{<imodesuffix>}\t%0";
10051 else
10052 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10053 }
10054 [(set_attr "type" "ishift")
10055 (set (attr "length_immediate")
10056 (if_then_else
10057 (and (match_operand 2 "const1_operand")
10058 (ior (match_test "TARGET_SHIFT1")
10059 (match_test "optimize_function_for_size_p (cfun)")))
10060 (const_string "0")
10061 (const_string "*")))
10062 (set_attr "mode" "<MODE>")])
10063
10064 (define_insn "*<shift_insn>si3_cmp_zext"
10065 [(set (reg FLAGS_REG)
10066 (compare
10067 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10068 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10069 (const_int 0)))
10070 (set (match_operand:DI 0 "register_operand" "=r")
10071 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10072 "TARGET_64BIT
10073 && (optimize_function_for_size_p (cfun)
10074 || !TARGET_PARTIAL_FLAG_REG_STALL
10075 || (operands[2] == const1_rtx
10076 && TARGET_SHIFT1))
10077 && ix86_match_ccmode (insn, CCGOCmode)
10078 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10079 {
10080 if (operands[2] == const1_rtx
10081 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10082 return "<shift>{l}\t%k0";
10083 else
10084 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10085 }
10086 [(set_attr "type" "ishift")
10087 (set (attr "length_immediate")
10088 (if_then_else
10089 (and (match_operand 2 "const1_operand")
10090 (ior (match_test "TARGET_SHIFT1")
10091 (match_test "optimize_function_for_size_p (cfun)")))
10092 (const_string "0")
10093 (const_string "*")))
10094 (set_attr "mode" "SI")])
10095
10096 (define_insn "*<shift_insn><mode>3_cconly"
10097 [(set (reg FLAGS_REG)
10098 (compare
10099 (any_shiftrt:SWI
10100 (match_operand:SWI 1 "register_operand" "0")
10101 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10102 (const_int 0)))
10103 (clobber (match_scratch:SWI 0 "=<r>"))]
10104 "(optimize_function_for_size_p (cfun)
10105 || !TARGET_PARTIAL_FLAG_REG_STALL
10106 || (operands[2] == const1_rtx
10107 && TARGET_SHIFT1))
10108 && ix86_match_ccmode (insn, CCGOCmode)"
10109 {
10110 if (operands[2] == const1_rtx
10111 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10112 return "<shift>{<imodesuffix>}\t%0";
10113 else
10114 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10115 }
10116 [(set_attr "type" "ishift")
10117 (set (attr "length_immediate")
10118 (if_then_else
10119 (and (match_operand 2 "const1_operand")
10120 (ior (match_test "TARGET_SHIFT1")
10121 (match_test "optimize_function_for_size_p (cfun)")))
10122 (const_string "0")
10123 (const_string "*")))
10124 (set_attr "mode" "<MODE>")])
10125 \f
10126 ;; Rotate instructions
10127
10128 (define_expand "<rotate_insn>ti3"
10129 [(set (match_operand:TI 0 "register_operand")
10130 (any_rotate:TI (match_operand:TI 1 "register_operand")
10131 (match_operand:QI 2 "nonmemory_operand")))]
10132 "TARGET_64BIT"
10133 {
10134 if (const_1_to_63_operand (operands[2], VOIDmode))
10135 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10136 (operands[0], operands[1], operands[2]));
10137 else
10138 FAIL;
10139
10140 DONE;
10141 })
10142
10143 (define_expand "<rotate_insn>di3"
10144 [(set (match_operand:DI 0 "shiftdi_operand")
10145 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10146 (match_operand:QI 2 "nonmemory_operand")))]
10147 ""
10148 {
10149 if (TARGET_64BIT)
10150 ix86_expand_binary_operator (<CODE>, DImode, operands);
10151 else if (const_1_to_31_operand (operands[2], VOIDmode))
10152 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10153 (operands[0], operands[1], operands[2]));
10154 else
10155 FAIL;
10156
10157 DONE;
10158 })
10159
10160 (define_expand "<rotate_insn><mode>3"
10161 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10162 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10163 (match_operand:QI 2 "nonmemory_operand")))]
10164 ""
10165 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10166
10167 ;; Avoid useless masking of count operand.
10168 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10169 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10170 (any_rotate:SWI48
10171 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10172 (subreg:QI
10173 (and:SI
10174 (match_operand:SI 2 "nonimmediate_operand" "c")
10175 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10176 (clobber (reg:CC FLAGS_REG))]
10177 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10178 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10179 == GET_MODE_BITSIZE (<MODE>mode)-1"
10180 "#"
10181 "&& 1"
10182 [(parallel [(set (match_dup 0)
10183 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10184 (clobber (reg:CC FLAGS_REG))])]
10185 {
10186 if (can_create_pseudo_p ())
10187 operands [2] = force_reg (SImode, operands[2]);
10188
10189 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10190 }
10191 [(set_attr "type" "rotate")
10192 (set_attr "mode" "<MODE>")])
10193
10194 ;; Implement rotation using two double-precision
10195 ;; shift instructions and a scratch register.
10196
10197 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10198 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10199 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10200 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10201 (clobber (reg:CC FLAGS_REG))
10202 (clobber (match_scratch:DWIH 3 "=&r"))]
10203 ""
10204 "#"
10205 "reload_completed"
10206 [(set (match_dup 3) (match_dup 4))
10207 (parallel
10208 [(set (match_dup 4)
10209 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10210 (lshiftrt:DWIH (match_dup 5)
10211 (minus:QI (match_dup 6) (match_dup 2)))))
10212 (clobber (reg:CC FLAGS_REG))])
10213 (parallel
10214 [(set (match_dup 5)
10215 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10216 (lshiftrt:DWIH (match_dup 3)
10217 (minus:QI (match_dup 6) (match_dup 2)))))
10218 (clobber (reg:CC FLAGS_REG))])]
10219 {
10220 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10221
10222 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10223 })
10224
10225 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10226 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10227 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10228 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10229 (clobber (reg:CC FLAGS_REG))
10230 (clobber (match_scratch:DWIH 3 "=&r"))]
10231 ""
10232 "#"
10233 "reload_completed"
10234 [(set (match_dup 3) (match_dup 4))
10235 (parallel
10236 [(set (match_dup 4)
10237 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10238 (ashift:DWIH (match_dup 5)
10239 (minus:QI (match_dup 6) (match_dup 2)))))
10240 (clobber (reg:CC FLAGS_REG))])
10241 (parallel
10242 [(set (match_dup 5)
10243 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10244 (ashift:DWIH (match_dup 3)
10245 (minus:QI (match_dup 6) (match_dup 2)))))
10246 (clobber (reg:CC FLAGS_REG))])]
10247 {
10248 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10249
10250 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10251 })
10252
10253 (define_insn "*bmi2_rorx<mode>3_1"
10254 [(set (match_operand:SWI48 0 "register_operand" "=r")
10255 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10256 (match_operand:QI 2 "immediate_operand" "<S>")))]
10257 "TARGET_BMI2"
10258 "rorx\t{%2, %1, %0|%0, %1, %2}"
10259 [(set_attr "type" "rotatex")
10260 (set_attr "mode" "<MODE>")])
10261
10262 (define_insn "*<rotate_insn><mode>3_1"
10263 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10264 (any_rotate:SWI48
10265 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10266 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10267 (clobber (reg:CC FLAGS_REG))]
10268 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10269 {
10270 switch (get_attr_type (insn))
10271 {
10272 case TYPE_ROTATEX:
10273 return "#";
10274
10275 default:
10276 if (operands[2] == const1_rtx
10277 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10278 return "<rotate>{<imodesuffix>}\t%0";
10279 else
10280 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10281 }
10282 }
10283 [(set_attr "isa" "*,bmi2")
10284 (set_attr "type" "rotate,rotatex")
10285 (set (attr "length_immediate")
10286 (if_then_else
10287 (and (eq_attr "type" "rotate")
10288 (and (match_operand 2 "const1_operand")
10289 (ior (match_test "TARGET_SHIFT1")
10290 (match_test "optimize_function_for_size_p (cfun)"))))
10291 (const_string "0")
10292 (const_string "*")))
10293 (set_attr "mode" "<MODE>")])
10294
10295 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10296 (define_split
10297 [(set (match_operand:SWI48 0 "register_operand")
10298 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10299 (match_operand:QI 2 "immediate_operand")))
10300 (clobber (reg:CC FLAGS_REG))]
10301 "TARGET_BMI2 && reload_completed"
10302 [(set (match_dup 0)
10303 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10304 {
10305 operands[2]
10306 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10307 })
10308
10309 (define_split
10310 [(set (match_operand:SWI48 0 "register_operand")
10311 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10312 (match_operand:QI 2 "immediate_operand")))
10313 (clobber (reg:CC FLAGS_REG))]
10314 "TARGET_BMI2 && reload_completed"
10315 [(set (match_dup 0)
10316 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10317
10318 (define_insn "*bmi2_rorxsi3_1_zext"
10319 [(set (match_operand:DI 0 "register_operand" "=r")
10320 (zero_extend:DI
10321 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10322 (match_operand:QI 2 "immediate_operand" "I"))))]
10323 "TARGET_64BIT && TARGET_BMI2"
10324 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10325 [(set_attr "type" "rotatex")
10326 (set_attr "mode" "SI")])
10327
10328 (define_insn "*<rotate_insn>si3_1_zext"
10329 [(set (match_operand:DI 0 "register_operand" "=r,r")
10330 (zero_extend:DI
10331 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10332 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10333 (clobber (reg:CC FLAGS_REG))]
10334 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10335 {
10336 switch (get_attr_type (insn))
10337 {
10338 case TYPE_ROTATEX:
10339 return "#";
10340
10341 default:
10342 if (operands[2] == const1_rtx
10343 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10344 return "<rotate>{l}\t%k0";
10345 else
10346 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10347 }
10348 }
10349 [(set_attr "isa" "*,bmi2")
10350 (set_attr "type" "rotate,rotatex")
10351 (set (attr "length_immediate")
10352 (if_then_else
10353 (and (eq_attr "type" "rotate")
10354 (and (match_operand 2 "const1_operand")
10355 (ior (match_test "TARGET_SHIFT1")
10356 (match_test "optimize_function_for_size_p (cfun)"))))
10357 (const_string "0")
10358 (const_string "*")))
10359 (set_attr "mode" "SI")])
10360
10361 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10362 (define_split
10363 [(set (match_operand:DI 0 "register_operand")
10364 (zero_extend:DI
10365 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10366 (match_operand:QI 2 "immediate_operand"))))
10367 (clobber (reg:CC FLAGS_REG))]
10368 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10369 [(set (match_dup 0)
10370 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10371 {
10372 operands[2]
10373 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10374 })
10375
10376 (define_split
10377 [(set (match_operand:DI 0 "register_operand")
10378 (zero_extend:DI
10379 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10380 (match_operand:QI 2 "immediate_operand"))))
10381 (clobber (reg:CC FLAGS_REG))]
10382 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10383 [(set (match_dup 0)
10384 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10385
10386 (define_insn "*<rotate_insn><mode>3_1"
10387 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10388 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10389 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10390 (clobber (reg:CC FLAGS_REG))]
10391 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10392 {
10393 if (operands[2] == const1_rtx
10394 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10395 return "<rotate>{<imodesuffix>}\t%0";
10396 else
10397 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10398 }
10399 [(set_attr "type" "rotate")
10400 (set (attr "length_immediate")
10401 (if_then_else
10402 (and (match_operand 2 "const1_operand")
10403 (ior (match_test "TARGET_SHIFT1")
10404 (match_test "optimize_function_for_size_p (cfun)")))
10405 (const_string "0")
10406 (const_string "*")))
10407 (set_attr "mode" "<MODE>")])
10408
10409 (define_insn "*<rotate_insn>qi3_1_slp"
10410 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10411 (any_rotate:QI (match_dup 0)
10412 (match_operand:QI 1 "nonmemory_operand" "cI")))
10413 (clobber (reg:CC FLAGS_REG))]
10414 "(optimize_function_for_size_p (cfun)
10415 || !TARGET_PARTIAL_REG_STALL
10416 || (operands[1] == const1_rtx
10417 && TARGET_SHIFT1))"
10418 {
10419 if (operands[1] == const1_rtx
10420 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10421 return "<rotate>{b}\t%0";
10422 else
10423 return "<rotate>{b}\t{%1, %0|%0, %1}";
10424 }
10425 [(set_attr "type" "rotate1")
10426 (set (attr "length_immediate")
10427 (if_then_else
10428 (and (match_operand 1 "const1_operand")
10429 (ior (match_test "TARGET_SHIFT1")
10430 (match_test "optimize_function_for_size_p (cfun)")))
10431 (const_string "0")
10432 (const_string "*")))
10433 (set_attr "mode" "QI")])
10434
10435 (define_split
10436 [(set (match_operand:HI 0 "register_operand")
10437 (any_rotate:HI (match_dup 0) (const_int 8)))
10438 (clobber (reg:CC FLAGS_REG))]
10439 "reload_completed
10440 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10441 [(parallel [(set (strict_low_part (match_dup 0))
10442 (bswap:HI (match_dup 0)))
10443 (clobber (reg:CC FLAGS_REG))])])
10444 \f
10445 ;; Bit set / bit test instructions
10446
10447 (define_expand "extv"
10448 [(set (match_operand:SI 0 "register_operand")
10449 (sign_extract:SI (match_operand:SI 1 "register_operand")
10450 (match_operand:SI 2 "const8_operand")
10451 (match_operand:SI 3 "const8_operand")))]
10452 ""
10453 {
10454 /* Handle extractions from %ah et al. */
10455 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10456 FAIL;
10457
10458 /* From mips.md: extract_bit_field doesn't verify that our source
10459 matches the predicate, so check it again here. */
10460 if (! ext_register_operand (operands[1], VOIDmode))
10461 FAIL;
10462 })
10463
10464 (define_expand "extzv"
10465 [(set (match_operand:SI 0 "register_operand")
10466 (zero_extract:SI (match_operand 1 "ext_register_operand")
10467 (match_operand:SI 2 "const8_operand")
10468 (match_operand:SI 3 "const8_operand")))]
10469 ""
10470 {
10471 /* Handle extractions from %ah et al. */
10472 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10473 FAIL;
10474
10475 /* From mips.md: extract_bit_field doesn't verify that our source
10476 matches the predicate, so check it again here. */
10477 if (! ext_register_operand (operands[1], VOIDmode))
10478 FAIL;
10479 })
10480
10481 (define_expand "insv"
10482 [(set (zero_extract (match_operand 0 "register_operand")
10483 (match_operand 1 "const_int_operand")
10484 (match_operand 2 "const_int_operand"))
10485 (match_operand 3 "register_operand"))]
10486 ""
10487 {
10488 rtx (*gen_mov_insv_1) (rtx, rtx);
10489
10490 if (ix86_expand_pinsr (operands))
10491 DONE;
10492
10493 /* Handle insertions to %ah et al. */
10494 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10495 FAIL;
10496
10497 /* From mips.md: insert_bit_field doesn't verify that our source
10498 matches the predicate, so check it again here. */
10499 if (! ext_register_operand (operands[0], VOIDmode))
10500 FAIL;
10501
10502 gen_mov_insv_1 = (TARGET_64BIT
10503 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10504
10505 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10506 DONE;
10507 })
10508
10509 ;; %%% bts, btr, btc, bt.
10510 ;; In general these instructions are *slow* when applied to memory,
10511 ;; since they enforce atomic operation. When applied to registers,
10512 ;; it depends on the cpu implementation. They're never faster than
10513 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10514 ;; no point. But in 64-bit, we can't hold the relevant immediates
10515 ;; within the instruction itself, so operating on bits in the high
10516 ;; 32-bits of a register becomes easier.
10517 ;;
10518 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10519 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10520 ;; negdf respectively, so they can never be disabled entirely.
10521
10522 (define_insn "*btsq"
10523 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10524 (const_int 1)
10525 (match_operand:DI 1 "const_0_to_63_operand"))
10526 (const_int 1))
10527 (clobber (reg:CC FLAGS_REG))]
10528 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10529 "bts{q}\t{%1, %0|%0, %1}"
10530 [(set_attr "type" "alu1")
10531 (set_attr "prefix_0f" "1")
10532 (set_attr "mode" "DI")])
10533
10534 (define_insn "*btrq"
10535 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10536 (const_int 1)
10537 (match_operand:DI 1 "const_0_to_63_operand"))
10538 (const_int 0))
10539 (clobber (reg:CC FLAGS_REG))]
10540 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10541 "btr{q}\t{%1, %0|%0, %1}"
10542 [(set_attr "type" "alu1")
10543 (set_attr "prefix_0f" "1")
10544 (set_attr "mode" "DI")])
10545
10546 (define_insn "*btcq"
10547 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10548 (const_int 1)
10549 (match_operand:DI 1 "const_0_to_63_operand"))
10550 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10551 (clobber (reg:CC FLAGS_REG))]
10552 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10553 "btc{q}\t{%1, %0|%0, %1}"
10554 [(set_attr "type" "alu1")
10555 (set_attr "prefix_0f" "1")
10556 (set_attr "mode" "DI")])
10557
10558 ;; Allow Nocona to avoid these instructions if a register is available.
10559
10560 (define_peephole2
10561 [(match_scratch:DI 2 "r")
10562 (parallel [(set (zero_extract:DI
10563 (match_operand:DI 0 "register_operand")
10564 (const_int 1)
10565 (match_operand:DI 1 "const_0_to_63_operand"))
10566 (const_int 1))
10567 (clobber (reg:CC FLAGS_REG))])]
10568 "TARGET_64BIT && !TARGET_USE_BT"
10569 [(const_int 0)]
10570 {
10571 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10572 rtx op1;
10573
10574 if (HOST_BITS_PER_WIDE_INT >= 64)
10575 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10576 else if (i < HOST_BITS_PER_WIDE_INT)
10577 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10578 else
10579 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10580
10581 op1 = immed_double_const (lo, hi, DImode);
10582 if (i >= 31)
10583 {
10584 emit_move_insn (operands[2], op1);
10585 op1 = operands[2];
10586 }
10587
10588 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10589 DONE;
10590 })
10591
10592 (define_peephole2
10593 [(match_scratch:DI 2 "r")
10594 (parallel [(set (zero_extract:DI
10595 (match_operand:DI 0 "register_operand")
10596 (const_int 1)
10597 (match_operand:DI 1 "const_0_to_63_operand"))
10598 (const_int 0))
10599 (clobber (reg:CC FLAGS_REG))])]
10600 "TARGET_64BIT && !TARGET_USE_BT"
10601 [(const_int 0)]
10602 {
10603 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10604 rtx op1;
10605
10606 if (HOST_BITS_PER_WIDE_INT >= 64)
10607 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10608 else if (i < HOST_BITS_PER_WIDE_INT)
10609 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10610 else
10611 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10612
10613 op1 = immed_double_const (~lo, ~hi, DImode);
10614 if (i >= 32)
10615 {
10616 emit_move_insn (operands[2], op1);
10617 op1 = operands[2];
10618 }
10619
10620 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10621 DONE;
10622 })
10623
10624 (define_peephole2
10625 [(match_scratch:DI 2 "r")
10626 (parallel [(set (zero_extract:DI
10627 (match_operand:DI 0 "register_operand")
10628 (const_int 1)
10629 (match_operand:DI 1 "const_0_to_63_operand"))
10630 (not:DI (zero_extract:DI
10631 (match_dup 0) (const_int 1) (match_dup 1))))
10632 (clobber (reg:CC FLAGS_REG))])]
10633 "TARGET_64BIT && !TARGET_USE_BT"
10634 [(const_int 0)]
10635 {
10636 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10637 rtx op1;
10638
10639 if (HOST_BITS_PER_WIDE_INT >= 64)
10640 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10641 else if (i < HOST_BITS_PER_WIDE_INT)
10642 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10643 else
10644 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10645
10646 op1 = immed_double_const (lo, hi, DImode);
10647 if (i >= 31)
10648 {
10649 emit_move_insn (operands[2], op1);
10650 op1 = operands[2];
10651 }
10652
10653 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10654 DONE;
10655 })
10656
10657 (define_insn "*bt<mode>"
10658 [(set (reg:CCC FLAGS_REG)
10659 (compare:CCC
10660 (zero_extract:SWI48
10661 (match_operand:SWI48 0 "register_operand" "r")
10662 (const_int 1)
10663 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10664 (const_int 0)))]
10665 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10666 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10667 [(set_attr "type" "alu1")
10668 (set_attr "prefix_0f" "1")
10669 (set_attr "mode" "<MODE>")])
10670 \f
10671 ;; Store-flag instructions.
10672
10673 ;; For all sCOND expanders, also expand the compare or test insn that
10674 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10675
10676 (define_insn_and_split "*setcc_di_1"
10677 [(set (match_operand:DI 0 "register_operand" "=q")
10678 (match_operator:DI 1 "ix86_comparison_operator"
10679 [(reg FLAGS_REG) (const_int 0)]))]
10680 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10681 "#"
10682 "&& reload_completed"
10683 [(set (match_dup 2) (match_dup 1))
10684 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10685 {
10686 PUT_MODE (operands[1], QImode);
10687 operands[2] = gen_lowpart (QImode, operands[0]);
10688 })
10689
10690 (define_insn_and_split "*setcc_si_1_and"
10691 [(set (match_operand:SI 0 "register_operand" "=q")
10692 (match_operator:SI 1 "ix86_comparison_operator"
10693 [(reg FLAGS_REG) (const_int 0)]))
10694 (clobber (reg:CC FLAGS_REG))]
10695 "!TARGET_PARTIAL_REG_STALL
10696 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10697 "#"
10698 "&& reload_completed"
10699 [(set (match_dup 2) (match_dup 1))
10700 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10701 (clobber (reg:CC FLAGS_REG))])]
10702 {
10703 PUT_MODE (operands[1], QImode);
10704 operands[2] = gen_lowpart (QImode, operands[0]);
10705 })
10706
10707 (define_insn_and_split "*setcc_si_1_movzbl"
10708 [(set (match_operand:SI 0 "register_operand" "=q")
10709 (match_operator:SI 1 "ix86_comparison_operator"
10710 [(reg FLAGS_REG) (const_int 0)]))]
10711 "!TARGET_PARTIAL_REG_STALL
10712 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10713 "#"
10714 "&& reload_completed"
10715 [(set (match_dup 2) (match_dup 1))
10716 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10717 {
10718 PUT_MODE (operands[1], QImode);
10719 operands[2] = gen_lowpart (QImode, operands[0]);
10720 })
10721
10722 (define_insn "*setcc_qi"
10723 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10724 (match_operator:QI 1 "ix86_comparison_operator"
10725 [(reg FLAGS_REG) (const_int 0)]))]
10726 ""
10727 "set%C1\t%0"
10728 [(set_attr "type" "setcc")
10729 (set_attr "mode" "QI")])
10730
10731 (define_insn "*setcc_qi_slp"
10732 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10733 (match_operator:QI 1 "ix86_comparison_operator"
10734 [(reg FLAGS_REG) (const_int 0)]))]
10735 ""
10736 "set%C1\t%0"
10737 [(set_attr "type" "setcc")
10738 (set_attr "mode" "QI")])
10739
10740 ;; In general it is not safe to assume too much about CCmode registers,
10741 ;; so simplify-rtx stops when it sees a second one. Under certain
10742 ;; conditions this is safe on x86, so help combine not create
10743 ;;
10744 ;; seta %al
10745 ;; testb %al, %al
10746 ;; sete %al
10747
10748 (define_split
10749 [(set (match_operand:QI 0 "nonimmediate_operand")
10750 (ne:QI (match_operator 1 "ix86_comparison_operator"
10751 [(reg FLAGS_REG) (const_int 0)])
10752 (const_int 0)))]
10753 ""
10754 [(set (match_dup 0) (match_dup 1))]
10755 "PUT_MODE (operands[1], QImode);")
10756
10757 (define_split
10758 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10759 (ne:QI (match_operator 1 "ix86_comparison_operator"
10760 [(reg FLAGS_REG) (const_int 0)])
10761 (const_int 0)))]
10762 ""
10763 [(set (match_dup 0) (match_dup 1))]
10764 "PUT_MODE (operands[1], QImode);")
10765
10766 (define_split
10767 [(set (match_operand:QI 0 "nonimmediate_operand")
10768 (eq:QI (match_operator 1 "ix86_comparison_operator"
10769 [(reg FLAGS_REG) (const_int 0)])
10770 (const_int 0)))]
10771 ""
10772 [(set (match_dup 0) (match_dup 1))]
10773 {
10774 rtx new_op1 = copy_rtx (operands[1]);
10775 operands[1] = new_op1;
10776 PUT_MODE (new_op1, QImode);
10777 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10778 GET_MODE (XEXP (new_op1, 0))));
10779
10780 /* Make sure that (a) the CCmode we have for the flags is strong
10781 enough for the reversed compare or (b) we have a valid FP compare. */
10782 if (! ix86_comparison_operator (new_op1, VOIDmode))
10783 FAIL;
10784 })
10785
10786 (define_split
10787 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10788 (eq:QI (match_operator 1 "ix86_comparison_operator"
10789 [(reg FLAGS_REG) (const_int 0)])
10790 (const_int 0)))]
10791 ""
10792 [(set (match_dup 0) (match_dup 1))]
10793 {
10794 rtx new_op1 = copy_rtx (operands[1]);
10795 operands[1] = new_op1;
10796 PUT_MODE (new_op1, QImode);
10797 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10798 GET_MODE (XEXP (new_op1, 0))));
10799
10800 /* Make sure that (a) the CCmode we have for the flags is strong
10801 enough for the reversed compare or (b) we have a valid FP compare. */
10802 if (! ix86_comparison_operator (new_op1, VOIDmode))
10803 FAIL;
10804 })
10805
10806 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10807 ;; subsequent logical operations are used to imitate conditional moves.
10808 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10809 ;; it directly.
10810
10811 (define_insn "setcc_<mode>_sse"
10812 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10813 (match_operator:MODEF 3 "sse_comparison_operator"
10814 [(match_operand:MODEF 1 "register_operand" "0,x")
10815 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10816 "SSE_FLOAT_MODE_P (<MODE>mode)"
10817 "@
10818 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10819 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10820 [(set_attr "isa" "noavx,avx")
10821 (set_attr "type" "ssecmp")
10822 (set_attr "length_immediate" "1")
10823 (set_attr "prefix" "orig,vex")
10824 (set_attr "mode" "<MODE>")])
10825 \f
10826 ;; Basic conditional jump instructions.
10827 ;; We ignore the overflow flag for signed branch instructions.
10828
10829 (define_insn "*jcc_1"
10830 [(set (pc)
10831 (if_then_else (match_operator 1 "ix86_comparison_operator"
10832 [(reg FLAGS_REG) (const_int 0)])
10833 (label_ref (match_operand 0))
10834 (pc)))]
10835 ""
10836 "%+j%C1\t%l0"
10837 [(set_attr "type" "ibr")
10838 (set_attr "modrm" "0")
10839 (set (attr "length")
10840 (if_then_else (and (ge (minus (match_dup 0) (pc))
10841 (const_int -126))
10842 (lt (minus (match_dup 0) (pc))
10843 (const_int 128)))
10844 (const_int 2)
10845 (const_int 6)))])
10846
10847 (define_insn "*jcc_2"
10848 [(set (pc)
10849 (if_then_else (match_operator 1 "ix86_comparison_operator"
10850 [(reg FLAGS_REG) (const_int 0)])
10851 (pc)
10852 (label_ref (match_operand 0))))]
10853 ""
10854 "%+j%c1\t%l0"
10855 [(set_attr "type" "ibr")
10856 (set_attr "modrm" "0")
10857 (set (attr "length")
10858 (if_then_else (and (ge (minus (match_dup 0) (pc))
10859 (const_int -126))
10860 (lt (minus (match_dup 0) (pc))
10861 (const_int 128)))
10862 (const_int 2)
10863 (const_int 6)))])
10864
10865 ;; In general it is not safe to assume too much about CCmode registers,
10866 ;; so simplify-rtx stops when it sees a second one. Under certain
10867 ;; conditions this is safe on x86, so help combine not create
10868 ;;
10869 ;; seta %al
10870 ;; testb %al, %al
10871 ;; je Lfoo
10872
10873 (define_split
10874 [(set (pc)
10875 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10876 [(reg FLAGS_REG) (const_int 0)])
10877 (const_int 0))
10878 (label_ref (match_operand 1))
10879 (pc)))]
10880 ""
10881 [(set (pc)
10882 (if_then_else (match_dup 0)
10883 (label_ref (match_dup 1))
10884 (pc)))]
10885 "PUT_MODE (operands[0], VOIDmode);")
10886
10887 (define_split
10888 [(set (pc)
10889 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10890 [(reg FLAGS_REG) (const_int 0)])
10891 (const_int 0))
10892 (label_ref (match_operand 1))
10893 (pc)))]
10894 ""
10895 [(set (pc)
10896 (if_then_else (match_dup 0)
10897 (label_ref (match_dup 1))
10898 (pc)))]
10899 {
10900 rtx new_op0 = copy_rtx (operands[0]);
10901 operands[0] = new_op0;
10902 PUT_MODE (new_op0, VOIDmode);
10903 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10904 GET_MODE (XEXP (new_op0, 0))));
10905
10906 /* Make sure that (a) the CCmode we have for the flags is strong
10907 enough for the reversed compare or (b) we have a valid FP compare. */
10908 if (! ix86_comparison_operator (new_op0, VOIDmode))
10909 FAIL;
10910 })
10911
10912 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10913 ;; pass generates from shift insn with QImode operand. Actually, the mode
10914 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10915 ;; appropriate modulo of the bit offset value.
10916
10917 (define_insn_and_split "*jcc_bt<mode>"
10918 [(set (pc)
10919 (if_then_else (match_operator 0 "bt_comparison_operator"
10920 [(zero_extract:SWI48
10921 (match_operand:SWI48 1 "register_operand" "r")
10922 (const_int 1)
10923 (zero_extend:SI
10924 (match_operand:QI 2 "register_operand" "r")))
10925 (const_int 0)])
10926 (label_ref (match_operand 3))
10927 (pc)))
10928 (clobber (reg:CC FLAGS_REG))]
10929 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10930 "#"
10931 "&& 1"
10932 [(set (reg:CCC FLAGS_REG)
10933 (compare:CCC
10934 (zero_extract:SWI48
10935 (match_dup 1)
10936 (const_int 1)
10937 (match_dup 2))
10938 (const_int 0)))
10939 (set (pc)
10940 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10941 (label_ref (match_dup 3))
10942 (pc)))]
10943 {
10944 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10945
10946 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10947 })
10948
10949 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10950 ;; also for DImode, this is what combine produces.
10951 (define_insn_and_split "*jcc_bt<mode>_mask"
10952 [(set (pc)
10953 (if_then_else (match_operator 0 "bt_comparison_operator"
10954 [(zero_extract:SWI48
10955 (match_operand:SWI48 1 "register_operand" "r")
10956 (const_int 1)
10957 (and:SI
10958 (match_operand:SI 2 "register_operand" "r")
10959 (match_operand:SI 3 "const_int_operand" "n")))])
10960 (label_ref (match_operand 4))
10961 (pc)))
10962 (clobber (reg:CC FLAGS_REG))]
10963 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10964 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10965 == GET_MODE_BITSIZE (<MODE>mode)-1"
10966 "#"
10967 "&& 1"
10968 [(set (reg:CCC FLAGS_REG)
10969 (compare:CCC
10970 (zero_extract:SWI48
10971 (match_dup 1)
10972 (const_int 1)
10973 (match_dup 2))
10974 (const_int 0)))
10975 (set (pc)
10976 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10977 (label_ref (match_dup 4))
10978 (pc)))]
10979 {
10980 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10981
10982 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10983 })
10984
10985 (define_insn_and_split "*jcc_btsi_1"
10986 [(set (pc)
10987 (if_then_else (match_operator 0 "bt_comparison_operator"
10988 [(and:SI
10989 (lshiftrt:SI
10990 (match_operand:SI 1 "register_operand" "r")
10991 (match_operand:QI 2 "register_operand" "r"))
10992 (const_int 1))
10993 (const_int 0)])
10994 (label_ref (match_operand 3))
10995 (pc)))
10996 (clobber (reg:CC FLAGS_REG))]
10997 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10998 "#"
10999 "&& 1"
11000 [(set (reg:CCC FLAGS_REG)
11001 (compare:CCC
11002 (zero_extract:SI
11003 (match_dup 1)
11004 (const_int 1)
11005 (match_dup 2))
11006 (const_int 0)))
11007 (set (pc)
11008 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11009 (label_ref (match_dup 3))
11010 (pc)))]
11011 {
11012 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11013
11014 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11015 })
11016
11017 ;; avoid useless masking of bit offset operand
11018 (define_insn_and_split "*jcc_btsi_mask_1"
11019 [(set (pc)
11020 (if_then_else
11021 (match_operator 0 "bt_comparison_operator"
11022 [(and:SI
11023 (lshiftrt:SI
11024 (match_operand:SI 1 "register_operand" "r")
11025 (subreg:QI
11026 (and:SI
11027 (match_operand:SI 2 "register_operand" "r")
11028 (match_operand:SI 3 "const_int_operand" "n")) 0))
11029 (const_int 1))
11030 (const_int 0)])
11031 (label_ref (match_operand 4))
11032 (pc)))
11033 (clobber (reg:CC FLAGS_REG))]
11034 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11035 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11036 "#"
11037 "&& 1"
11038 [(set (reg:CCC FLAGS_REG)
11039 (compare:CCC
11040 (zero_extract:SI
11041 (match_dup 1)
11042 (const_int 1)
11043 (match_dup 2))
11044 (const_int 0)))
11045 (set (pc)
11046 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11047 (label_ref (match_dup 4))
11048 (pc)))]
11049 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11050
11051 ;; Define combination compare-and-branch fp compare instructions to help
11052 ;; combine.
11053
11054 (define_insn "*fp_jcc_1_387"
11055 [(set (pc)
11056 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11057 [(match_operand 1 "register_operand" "f")
11058 (match_operand 2 "nonimmediate_operand" "fm")])
11059 (label_ref (match_operand 3))
11060 (pc)))
11061 (clobber (reg:CCFP FPSR_REG))
11062 (clobber (reg:CCFP FLAGS_REG))
11063 (clobber (match_scratch:HI 4 "=a"))]
11064 "TARGET_80387
11065 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11066 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11067 && SELECT_CC_MODE (GET_CODE (operands[0]),
11068 operands[1], operands[2]) == CCFPmode
11069 && !TARGET_CMOVE"
11070 "#")
11071
11072 (define_insn "*fp_jcc_1r_387"
11073 [(set (pc)
11074 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11075 [(match_operand 1 "register_operand" "f")
11076 (match_operand 2 "nonimmediate_operand" "fm")])
11077 (pc)
11078 (label_ref (match_operand 3))))
11079 (clobber (reg:CCFP FPSR_REG))
11080 (clobber (reg:CCFP FLAGS_REG))
11081 (clobber (match_scratch:HI 4 "=a"))]
11082 "TARGET_80387
11083 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11084 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11085 && SELECT_CC_MODE (GET_CODE (operands[0]),
11086 operands[1], operands[2]) == CCFPmode
11087 && !TARGET_CMOVE"
11088 "#")
11089
11090 (define_insn "*fp_jcc_2_387"
11091 [(set (pc)
11092 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11093 [(match_operand 1 "register_operand" "f")
11094 (match_operand 2 "register_operand" "f")])
11095 (label_ref (match_operand 3))
11096 (pc)))
11097 (clobber (reg:CCFP FPSR_REG))
11098 (clobber (reg:CCFP FLAGS_REG))
11099 (clobber (match_scratch:HI 4 "=a"))]
11100 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11101 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11102 && !TARGET_CMOVE"
11103 "#")
11104
11105 (define_insn "*fp_jcc_2r_387"
11106 [(set (pc)
11107 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11108 [(match_operand 1 "register_operand" "f")
11109 (match_operand 2 "register_operand" "f")])
11110 (pc)
11111 (label_ref (match_operand 3))))
11112 (clobber (reg:CCFP FPSR_REG))
11113 (clobber (reg:CCFP FLAGS_REG))
11114 (clobber (match_scratch:HI 4 "=a"))]
11115 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11116 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11117 && !TARGET_CMOVE"
11118 "#")
11119
11120 (define_insn "*fp_jcc_3_387"
11121 [(set (pc)
11122 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11123 [(match_operand 1 "register_operand" "f")
11124 (match_operand 2 "const0_operand")])
11125 (label_ref (match_operand 3))
11126 (pc)))
11127 (clobber (reg:CCFP FPSR_REG))
11128 (clobber (reg:CCFP FLAGS_REG))
11129 (clobber (match_scratch:HI 4 "=a"))]
11130 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11131 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11132 && SELECT_CC_MODE (GET_CODE (operands[0]),
11133 operands[1], operands[2]) == CCFPmode
11134 && !TARGET_CMOVE"
11135 "#")
11136
11137 (define_split
11138 [(set (pc)
11139 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11140 [(match_operand 1 "register_operand")
11141 (match_operand 2 "nonimmediate_operand")])
11142 (match_operand 3)
11143 (match_operand 4)))
11144 (clobber (reg:CCFP FPSR_REG))
11145 (clobber (reg:CCFP FLAGS_REG))]
11146 "reload_completed"
11147 [(const_int 0)]
11148 {
11149 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11150 operands[3], operands[4], NULL_RTX, NULL_RTX);
11151 DONE;
11152 })
11153
11154 (define_split
11155 [(set (pc)
11156 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11157 [(match_operand 1 "register_operand")
11158 (match_operand 2 "general_operand")])
11159 (match_operand 3)
11160 (match_operand 4)))
11161 (clobber (reg:CCFP FPSR_REG))
11162 (clobber (reg:CCFP FLAGS_REG))
11163 (clobber (match_scratch:HI 5 "=a"))]
11164 "reload_completed"
11165 [(const_int 0)]
11166 {
11167 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11168 operands[3], operands[4], operands[5], NULL_RTX);
11169 DONE;
11170 })
11171
11172 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11173 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11174 ;; with a precedence over other operators and is always put in the first
11175 ;; place. Swap condition and operands to match ficom instruction.
11176
11177 (define_insn "*fp_jcc_4_<mode>_387"
11178 [(set (pc)
11179 (if_then_else
11180 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11181 [(match_operator 1 "float_operator"
11182 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11183 (match_operand 3 "register_operand" "f,f")])
11184 (label_ref (match_operand 4))
11185 (pc)))
11186 (clobber (reg:CCFP FPSR_REG))
11187 (clobber (reg:CCFP FLAGS_REG))
11188 (clobber (match_scratch:HI 5 "=a,a"))]
11189 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11190 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11191 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11192 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11193 && !TARGET_CMOVE"
11194 "#")
11195
11196 (define_split
11197 [(set (pc)
11198 (if_then_else
11199 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11200 [(match_operator 1 "float_operator"
11201 [(match_operand:SWI24 2 "memory_operand")])
11202 (match_operand 3 "register_operand")])
11203 (match_operand 4)
11204 (match_operand 5)))
11205 (clobber (reg:CCFP FPSR_REG))
11206 (clobber (reg:CCFP FLAGS_REG))
11207 (clobber (match_scratch:HI 6 "=a"))]
11208 "reload_completed"
11209 [(const_int 0)]
11210 {
11211 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11212
11213 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11214 operands[3], operands[7],
11215 operands[4], operands[5], operands[6], NULL_RTX);
11216 DONE;
11217 })
11218
11219 ;; %%% Kill this when reload knows how to do it.
11220 (define_split
11221 [(set (pc)
11222 (if_then_else
11223 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11224 [(match_operator 1 "float_operator"
11225 [(match_operand:SWI24 2 "register_operand")])
11226 (match_operand 3 "register_operand")])
11227 (match_operand 4)
11228 (match_operand 5)))
11229 (clobber (reg:CCFP FPSR_REG))
11230 (clobber (reg:CCFP FLAGS_REG))
11231 (clobber (match_scratch:HI 6 "=a"))]
11232 "reload_completed"
11233 [(const_int 0)]
11234 {
11235 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11236 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11237
11238 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11239 operands[3], operands[7],
11240 operands[4], operands[5], operands[6], operands[2]);
11241 DONE;
11242 })
11243 \f
11244 ;; Unconditional and other jump instructions
11245
11246 (define_insn "jump"
11247 [(set (pc)
11248 (label_ref (match_operand 0)))]
11249 ""
11250 "jmp\t%l0"
11251 [(set_attr "type" "ibr")
11252 (set (attr "length")
11253 (if_then_else (and (ge (minus (match_dup 0) (pc))
11254 (const_int -126))
11255 (lt (minus (match_dup 0) (pc))
11256 (const_int 128)))
11257 (const_int 2)
11258 (const_int 5)))
11259 (set_attr "modrm" "0")])
11260
11261 (define_expand "indirect_jump"
11262 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11263 ""
11264 {
11265 if (TARGET_X32)
11266 operands[0] = convert_memory_address (word_mode, operands[0]);
11267 })
11268
11269 (define_insn "*indirect_jump"
11270 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11271 ""
11272 "jmp\t%A0"
11273 [(set_attr "type" "ibr")
11274 (set_attr "length_immediate" "0")])
11275
11276 (define_expand "tablejump"
11277 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11278 (use (label_ref (match_operand 1)))])]
11279 ""
11280 {
11281 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11282 relative. Convert the relative address to an absolute address. */
11283 if (flag_pic)
11284 {
11285 rtx op0, op1;
11286 enum rtx_code code;
11287
11288 /* We can't use @GOTOFF for text labels on VxWorks;
11289 see gotoff_operand. */
11290 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11291 {
11292 code = PLUS;
11293 op0 = operands[0];
11294 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11295 }
11296 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11297 {
11298 code = PLUS;
11299 op0 = operands[0];
11300 op1 = pic_offset_table_rtx;
11301 }
11302 else
11303 {
11304 code = MINUS;
11305 op0 = pic_offset_table_rtx;
11306 op1 = operands[0];
11307 }
11308
11309 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11310 OPTAB_DIRECT);
11311 }
11312
11313 if (TARGET_X32)
11314 operands[0] = convert_memory_address (word_mode, operands[0]);
11315 })
11316
11317 (define_insn "*tablejump_1"
11318 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11319 (use (label_ref (match_operand 1)))]
11320 ""
11321 "jmp\t%A0"
11322 [(set_attr "type" "ibr")
11323 (set_attr "length_immediate" "0")])
11324 \f
11325 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11326
11327 (define_peephole2
11328 [(set (reg FLAGS_REG) (match_operand 0))
11329 (set (match_operand:QI 1 "register_operand")
11330 (match_operator:QI 2 "ix86_comparison_operator"
11331 [(reg FLAGS_REG) (const_int 0)]))
11332 (set (match_operand 3 "q_regs_operand")
11333 (zero_extend (match_dup 1)))]
11334 "(peep2_reg_dead_p (3, operands[1])
11335 || operands_match_p (operands[1], operands[3]))
11336 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11337 [(set (match_dup 4) (match_dup 0))
11338 (set (strict_low_part (match_dup 5))
11339 (match_dup 2))]
11340 {
11341 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11342 operands[5] = gen_lowpart (QImode, operands[3]);
11343 ix86_expand_clear (operands[3]);
11344 })
11345
11346 (define_peephole2
11347 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11348 (match_operand 4)])
11349 (set (match_operand:QI 1 "register_operand")
11350 (match_operator:QI 2 "ix86_comparison_operator"
11351 [(reg FLAGS_REG) (const_int 0)]))
11352 (set (match_operand 3 "q_regs_operand")
11353 (zero_extend (match_dup 1)))]
11354 "(peep2_reg_dead_p (3, operands[1])
11355 || operands_match_p (operands[1], operands[3]))
11356 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11357 [(parallel [(set (match_dup 5) (match_dup 0))
11358 (match_dup 4)])
11359 (set (strict_low_part (match_dup 6))
11360 (match_dup 2))]
11361 {
11362 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11363 operands[6] = gen_lowpart (QImode, operands[3]);
11364 ix86_expand_clear (operands[3]);
11365 })
11366
11367 ;; Similar, but match zero extend with andsi3.
11368
11369 (define_peephole2
11370 [(set (reg FLAGS_REG) (match_operand 0))
11371 (set (match_operand:QI 1 "register_operand")
11372 (match_operator:QI 2 "ix86_comparison_operator"
11373 [(reg FLAGS_REG) (const_int 0)]))
11374 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11375 (and:SI (match_dup 3) (const_int 255)))
11376 (clobber (reg:CC FLAGS_REG))])]
11377 "REGNO (operands[1]) == REGNO (operands[3])
11378 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11379 [(set (match_dup 4) (match_dup 0))
11380 (set (strict_low_part (match_dup 5))
11381 (match_dup 2))]
11382 {
11383 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11384 operands[5] = gen_lowpart (QImode, operands[3]);
11385 ix86_expand_clear (operands[3]);
11386 })
11387
11388 (define_peephole2
11389 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11390 (match_operand 4)])
11391 (set (match_operand:QI 1 "register_operand")
11392 (match_operator:QI 2 "ix86_comparison_operator"
11393 [(reg FLAGS_REG) (const_int 0)]))
11394 (parallel [(set (match_operand 3 "q_regs_operand")
11395 (zero_extend (match_dup 1)))
11396 (clobber (reg:CC FLAGS_REG))])]
11397 "(peep2_reg_dead_p (3, operands[1])
11398 || operands_match_p (operands[1], operands[3]))
11399 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11400 [(parallel [(set (match_dup 5) (match_dup 0))
11401 (match_dup 4)])
11402 (set (strict_low_part (match_dup 6))
11403 (match_dup 2))]
11404 {
11405 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11406 operands[6] = gen_lowpart (QImode, operands[3]);
11407 ix86_expand_clear (operands[3]);
11408 })
11409 \f
11410 ;; Call instructions.
11411
11412 ;; The predicates normally associated with named expanders are not properly
11413 ;; checked for calls. This is a bug in the generic code, but it isn't that
11414 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11415
11416 ;; P6 processors will jump to the address after the decrement when %esp
11417 ;; is used as a call operand, so they will execute return address as a code.
11418 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11419
11420 ;; Register constraint for call instruction.
11421 (define_mode_attr c [(SI "l") (DI "r")])
11422
11423 ;; Call subroutine returning no value.
11424
11425 (define_expand "call"
11426 [(call (match_operand:QI 0)
11427 (match_operand 1))
11428 (use (match_operand 2))]
11429 ""
11430 {
11431 ix86_expand_call (NULL, operands[0], operands[1],
11432 operands[2], NULL, false);
11433 DONE;
11434 })
11435
11436 (define_expand "sibcall"
11437 [(call (match_operand:QI 0)
11438 (match_operand 1))
11439 (use (match_operand 2))]
11440 ""
11441 {
11442 ix86_expand_call (NULL, operands[0], operands[1],
11443 operands[2], NULL, true);
11444 DONE;
11445 })
11446
11447 (define_insn_and_split "*call_vzeroupper"
11448 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11449 (match_operand 1))
11450 (unspec [(match_operand 2 "const_int_operand")]
11451 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11452 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11453 "#"
11454 "&& reload_completed"
11455 [(const_int 0)]
11456 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11457 [(set_attr "type" "call")])
11458
11459 (define_insn "*call"
11460 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11461 (match_operand 1))]
11462 "!SIBLING_CALL_P (insn)"
11463 "* return ix86_output_call_insn (insn, operands[0]);"
11464 [(set_attr "type" "call")])
11465
11466 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11467 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11468 (match_operand 1))
11469 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11470 (clobber (reg:TI XMM6_REG))
11471 (clobber (reg:TI XMM7_REG))
11472 (clobber (reg:TI XMM8_REG))
11473 (clobber (reg:TI XMM9_REG))
11474 (clobber (reg:TI XMM10_REG))
11475 (clobber (reg:TI XMM11_REG))
11476 (clobber (reg:TI XMM12_REG))
11477 (clobber (reg:TI XMM13_REG))
11478 (clobber (reg:TI XMM14_REG))
11479 (clobber (reg:TI XMM15_REG))
11480 (clobber (reg:DI SI_REG))
11481 (clobber (reg:DI DI_REG))
11482 (unspec [(match_operand 2 "const_int_operand")]
11483 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11484 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11485 "#"
11486 "&& reload_completed"
11487 [(const_int 0)]
11488 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11489 [(set_attr "type" "call")])
11490
11491 (define_insn "*call_rex64_ms_sysv"
11492 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11493 (match_operand 1))
11494 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11495 (clobber (reg:TI XMM6_REG))
11496 (clobber (reg:TI XMM7_REG))
11497 (clobber (reg:TI XMM8_REG))
11498 (clobber (reg:TI XMM9_REG))
11499 (clobber (reg:TI XMM10_REG))
11500 (clobber (reg:TI XMM11_REG))
11501 (clobber (reg:TI XMM12_REG))
11502 (clobber (reg:TI XMM13_REG))
11503 (clobber (reg:TI XMM14_REG))
11504 (clobber (reg:TI XMM15_REG))
11505 (clobber (reg:DI SI_REG))
11506 (clobber (reg:DI DI_REG))]
11507 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11508 "* return ix86_output_call_insn (insn, operands[0]);"
11509 [(set_attr "type" "call")])
11510
11511 (define_insn_and_split "*sibcall_vzeroupper"
11512 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11513 (match_operand 1))
11514 (unspec [(match_operand 2 "const_int_operand")]
11515 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11516 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11517 "#"
11518 "&& reload_completed"
11519 [(const_int 0)]
11520 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11521 [(set_attr "type" "call")])
11522
11523 (define_insn "*sibcall"
11524 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11525 (match_operand 1))]
11526 "SIBLING_CALL_P (insn)"
11527 "* return ix86_output_call_insn (insn, operands[0]);"
11528 [(set_attr "type" "call")])
11529
11530 (define_expand "call_pop"
11531 [(parallel [(call (match_operand:QI 0)
11532 (match_operand:SI 1))
11533 (set (reg:SI SP_REG)
11534 (plus:SI (reg:SI SP_REG)
11535 (match_operand:SI 3)))])]
11536 "!TARGET_64BIT"
11537 {
11538 ix86_expand_call (NULL, operands[0], operands[1],
11539 operands[2], operands[3], false);
11540 DONE;
11541 })
11542
11543 (define_insn_and_split "*call_pop_vzeroupper"
11544 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11545 (match_operand 1))
11546 (set (reg:SI SP_REG)
11547 (plus:SI (reg:SI SP_REG)
11548 (match_operand:SI 2 "immediate_operand" "i")))
11549 (unspec [(match_operand 3 "const_int_operand")]
11550 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11551 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11552 "#"
11553 "&& reload_completed"
11554 [(const_int 0)]
11555 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11556 [(set_attr "type" "call")])
11557
11558 (define_insn "*call_pop"
11559 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11560 (match_operand 1))
11561 (set (reg:SI SP_REG)
11562 (plus:SI (reg:SI SP_REG)
11563 (match_operand:SI 2 "immediate_operand" "i")))]
11564 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11565 "* return ix86_output_call_insn (insn, operands[0]);"
11566 [(set_attr "type" "call")])
11567
11568 (define_insn_and_split "*sibcall_pop_vzeroupper"
11569 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11570 (match_operand 1))
11571 (set (reg:SI SP_REG)
11572 (plus:SI (reg:SI SP_REG)
11573 (match_operand:SI 2 "immediate_operand" "i")))
11574 (unspec [(match_operand 3 "const_int_operand")]
11575 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11576 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11577 "#"
11578 "&& reload_completed"
11579 [(const_int 0)]
11580 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11581 [(set_attr "type" "call")])
11582
11583 (define_insn "*sibcall_pop"
11584 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11585 (match_operand 1))
11586 (set (reg:SI SP_REG)
11587 (plus:SI (reg:SI SP_REG)
11588 (match_operand:SI 2 "immediate_operand" "i")))]
11589 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11590 "* return ix86_output_call_insn (insn, operands[0]);"
11591 [(set_attr "type" "call")])
11592
11593 ;; Call subroutine, returning value in operand 0
11594
11595 (define_expand "call_value"
11596 [(set (match_operand 0)
11597 (call (match_operand:QI 1)
11598 (match_operand 2)))
11599 (use (match_operand 3))]
11600 ""
11601 {
11602 ix86_expand_call (operands[0], operands[1], operands[2],
11603 operands[3], NULL, false);
11604 DONE;
11605 })
11606
11607 (define_expand "sibcall_value"
11608 [(set (match_operand 0)
11609 (call (match_operand:QI 1)
11610 (match_operand 2)))
11611 (use (match_operand 3))]
11612 ""
11613 {
11614 ix86_expand_call (operands[0], operands[1], operands[2],
11615 operands[3], NULL, true);
11616 DONE;
11617 })
11618
11619 (define_insn_and_split "*call_value_vzeroupper"
11620 [(set (match_operand 0)
11621 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11622 (match_operand 2)))
11623 (unspec [(match_operand 3 "const_int_operand")]
11624 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11625 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11626 "#"
11627 "&& reload_completed"
11628 [(const_int 0)]
11629 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11630 [(set_attr "type" "callv")])
11631
11632 (define_insn "*call_value"
11633 [(set (match_operand 0)
11634 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11635 (match_operand 2)))]
11636 "!SIBLING_CALL_P (insn)"
11637 "* return ix86_output_call_insn (insn, operands[1]);"
11638 [(set_attr "type" "callv")])
11639
11640 (define_insn_and_split "*sibcall_value_vzeroupper"
11641 [(set (match_operand 0)
11642 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11643 (match_operand 2)))
11644 (unspec [(match_operand 3 "const_int_operand")]
11645 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11646 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11647 "#"
11648 "&& reload_completed"
11649 [(const_int 0)]
11650 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11651 [(set_attr "type" "callv")])
11652
11653 (define_insn "*sibcall_value"
11654 [(set (match_operand 0)
11655 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11656 (match_operand 2)))]
11657 "SIBLING_CALL_P (insn)"
11658 "* return ix86_output_call_insn (insn, operands[1]);"
11659 [(set_attr "type" "callv")])
11660
11661 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11662 [(set (match_operand 0)
11663 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11664 (match_operand 2)))
11665 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11666 (clobber (reg:TI XMM6_REG))
11667 (clobber (reg:TI XMM7_REG))
11668 (clobber (reg:TI XMM8_REG))
11669 (clobber (reg:TI XMM9_REG))
11670 (clobber (reg:TI XMM10_REG))
11671 (clobber (reg:TI XMM11_REG))
11672 (clobber (reg:TI XMM12_REG))
11673 (clobber (reg:TI XMM13_REG))
11674 (clobber (reg:TI XMM14_REG))
11675 (clobber (reg:TI XMM15_REG))
11676 (clobber (reg:DI SI_REG))
11677 (clobber (reg:DI DI_REG))
11678 (unspec [(match_operand 3 "const_int_operand")]
11679 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11680 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11681 "#"
11682 "&& reload_completed"
11683 [(const_int 0)]
11684 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11685 [(set_attr "type" "callv")])
11686
11687 (define_insn "*call_value_rex64_ms_sysv"
11688 [(set (match_operand 0)
11689 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11690 (match_operand 2)))
11691 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11692 (clobber (reg:TI XMM6_REG))
11693 (clobber (reg:TI XMM7_REG))
11694 (clobber (reg:TI XMM8_REG))
11695 (clobber (reg:TI XMM9_REG))
11696 (clobber (reg:TI XMM10_REG))
11697 (clobber (reg:TI XMM11_REG))
11698 (clobber (reg:TI XMM12_REG))
11699 (clobber (reg:TI XMM13_REG))
11700 (clobber (reg:TI XMM14_REG))
11701 (clobber (reg:TI XMM15_REG))
11702 (clobber (reg:DI SI_REG))
11703 (clobber (reg:DI DI_REG))]
11704 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11705 "* return ix86_output_call_insn (insn, operands[1]);"
11706 [(set_attr "type" "callv")])
11707
11708 (define_expand "call_value_pop"
11709 [(parallel [(set (match_operand 0)
11710 (call (match_operand:QI 1)
11711 (match_operand:SI 2)))
11712 (set (reg:SI SP_REG)
11713 (plus:SI (reg:SI SP_REG)
11714 (match_operand:SI 4)))])]
11715 "!TARGET_64BIT"
11716 {
11717 ix86_expand_call (operands[0], operands[1], operands[2],
11718 operands[3], operands[4], false);
11719 DONE;
11720 })
11721
11722 (define_insn_and_split "*call_value_pop_vzeroupper"
11723 [(set (match_operand 0)
11724 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11725 (match_operand 2)))
11726 (set (reg:SI SP_REG)
11727 (plus:SI (reg:SI SP_REG)
11728 (match_operand:SI 3 "immediate_operand" "i")))
11729 (unspec [(match_operand 4 "const_int_operand")]
11730 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11731 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11732 "#"
11733 "&& reload_completed"
11734 [(const_int 0)]
11735 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11736 [(set_attr "type" "callv")])
11737
11738 (define_insn "*call_value_pop"
11739 [(set (match_operand 0)
11740 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11741 (match_operand 2)))
11742 (set (reg:SI SP_REG)
11743 (plus:SI (reg:SI SP_REG)
11744 (match_operand:SI 3 "immediate_operand" "i")))]
11745 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11746 "* return ix86_output_call_insn (insn, operands[1]);"
11747 [(set_attr "type" "callv")])
11748
11749 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11750 [(set (match_operand 0)
11751 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11752 (match_operand 2)))
11753 (set (reg:SI SP_REG)
11754 (plus:SI (reg:SI SP_REG)
11755 (match_operand:SI 3 "immediate_operand" "i")))
11756 (unspec [(match_operand 4 "const_int_operand")]
11757 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11758 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11759 "#"
11760 "&& reload_completed"
11761 [(const_int 0)]
11762 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11763 [(set_attr "type" "callv")])
11764
11765 (define_insn "*sibcall_value_pop"
11766 [(set (match_operand 0)
11767 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11768 (match_operand 2)))
11769 (set (reg:SI SP_REG)
11770 (plus:SI (reg:SI SP_REG)
11771 (match_operand:SI 3 "immediate_operand" "i")))]
11772 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11773 "* return ix86_output_call_insn (insn, operands[1]);"
11774 [(set_attr "type" "callv")])
11775
11776 ;; Call subroutine returning any type.
11777
11778 (define_expand "untyped_call"
11779 [(parallel [(call (match_operand 0)
11780 (const_int 0))
11781 (match_operand 1)
11782 (match_operand 2)])]
11783 ""
11784 {
11785 int i;
11786
11787 /* In order to give reg-stack an easier job in validating two
11788 coprocessor registers as containing a possible return value,
11789 simply pretend the untyped call returns a complex long double
11790 value.
11791
11792 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11793 and should have the default ABI. */
11794
11795 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11796 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11797 operands[0], const0_rtx,
11798 GEN_INT ((TARGET_64BIT
11799 ? (ix86_abi == SYSV_ABI
11800 ? X86_64_SSE_REGPARM_MAX
11801 : X86_64_MS_SSE_REGPARM_MAX)
11802 : X86_32_SSE_REGPARM_MAX)
11803 - 1),
11804 NULL, false);
11805
11806 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11807 {
11808 rtx set = XVECEXP (operands[2], 0, i);
11809 emit_move_insn (SET_DEST (set), SET_SRC (set));
11810 }
11811
11812 /* The optimizer does not know that the call sets the function value
11813 registers we stored in the result block. We avoid problems by
11814 claiming that all hard registers are used and clobbered at this
11815 point. */
11816 emit_insn (gen_blockage ());
11817
11818 DONE;
11819 })
11820 \f
11821 ;; Prologue and epilogue instructions
11822
11823 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11824 ;; all of memory. This blocks insns from being moved across this point.
11825
11826 (define_insn "blockage"
11827 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11828 ""
11829 ""
11830 [(set_attr "length" "0")])
11831
11832 ;; Do not schedule instructions accessing memory across this point.
11833
11834 (define_expand "memory_blockage"
11835 [(set (match_dup 0)
11836 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11837 ""
11838 {
11839 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11840 MEM_VOLATILE_P (operands[0]) = 1;
11841 })
11842
11843 (define_insn "*memory_blockage"
11844 [(set (match_operand:BLK 0)
11845 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11846 ""
11847 ""
11848 [(set_attr "length" "0")])
11849
11850 ;; As USE insns aren't meaningful after reload, this is used instead
11851 ;; to prevent deleting instructions setting registers for PIC code
11852 (define_insn "prologue_use"
11853 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11854 ""
11855 ""
11856 [(set_attr "length" "0")])
11857
11858 ;; Insn emitted into the body of a function to return from a function.
11859 ;; This is only done if the function's epilogue is known to be simple.
11860 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11861
11862 (define_expand "return"
11863 [(simple_return)]
11864 "ix86_can_use_return_insn_p ()"
11865 {
11866 ix86_maybe_emit_epilogue_vzeroupper ();
11867 if (crtl->args.pops_args)
11868 {
11869 rtx popc = GEN_INT (crtl->args.pops_args);
11870 emit_jump_insn (gen_simple_return_pop_internal (popc));
11871 DONE;
11872 }
11873 })
11874
11875 ;; We need to disable this for TARGET_SEH, as otherwise
11876 ;; shrink-wrapped prologue gets enabled too. This might exceed
11877 ;; the maximum size of prologue in unwind information.
11878
11879 (define_expand "simple_return"
11880 [(simple_return)]
11881 "!TARGET_SEH"
11882 {
11883 ix86_maybe_emit_epilogue_vzeroupper ();
11884 if (crtl->args.pops_args)
11885 {
11886 rtx popc = GEN_INT (crtl->args.pops_args);
11887 emit_jump_insn (gen_simple_return_pop_internal (popc));
11888 DONE;
11889 }
11890 })
11891
11892 (define_insn "simple_return_internal"
11893 [(simple_return)]
11894 "reload_completed"
11895 "ret"
11896 [(set_attr "length" "1")
11897 (set_attr "atom_unit" "jeu")
11898 (set_attr "length_immediate" "0")
11899 (set_attr "modrm" "0")])
11900
11901 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11902 ;; instruction Athlon and K8 have.
11903
11904 (define_insn "simple_return_internal_long"
11905 [(simple_return)
11906 (unspec [(const_int 0)] UNSPEC_REP)]
11907 "reload_completed"
11908 "rep\;ret"
11909 [(set_attr "length" "2")
11910 (set_attr "atom_unit" "jeu")
11911 (set_attr "length_immediate" "0")
11912 (set_attr "prefix_rep" "1")
11913 (set_attr "modrm" "0")])
11914
11915 (define_insn "simple_return_pop_internal"
11916 [(simple_return)
11917 (use (match_operand:SI 0 "const_int_operand"))]
11918 "reload_completed"
11919 "ret\t%0"
11920 [(set_attr "length" "3")
11921 (set_attr "atom_unit" "jeu")
11922 (set_attr "length_immediate" "2")
11923 (set_attr "modrm" "0")])
11924
11925 (define_insn "simple_return_indirect_internal"
11926 [(simple_return)
11927 (use (match_operand:SI 0 "register_operand" "r"))]
11928 "reload_completed"
11929 "jmp\t%A0"
11930 [(set_attr "type" "ibr")
11931 (set_attr "length_immediate" "0")])
11932
11933 (define_insn "nop"
11934 [(const_int 0)]
11935 ""
11936 "nop"
11937 [(set_attr "length" "1")
11938 (set_attr "length_immediate" "0")
11939 (set_attr "modrm" "0")])
11940
11941 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11942 (define_insn "nops"
11943 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11944 UNSPECV_NOPS)]
11945 "reload_completed"
11946 {
11947 int num = INTVAL (operands[0]);
11948
11949 gcc_assert (num >= 1 && num <= 8);
11950
11951 while (num--)
11952 fputs ("\tnop\n", asm_out_file);
11953
11954 return "";
11955 }
11956 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11957 (set_attr "length_immediate" "0")
11958 (set_attr "modrm" "0")])
11959
11960 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11961 ;; branch prediction penalty for the third jump in a 16-byte
11962 ;; block on K8.
11963
11964 (define_insn "pad"
11965 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11966 ""
11967 {
11968 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11969 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11970 #else
11971 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11972 The align insn is used to avoid 3 jump instructions in the row to improve
11973 branch prediction and the benefits hardly outweigh the cost of extra 8
11974 nops on the average inserted by full alignment pseudo operation. */
11975 #endif
11976 return "";
11977 }
11978 [(set_attr "length" "16")])
11979
11980 (define_expand "prologue"
11981 [(const_int 0)]
11982 ""
11983 "ix86_expand_prologue (); DONE;")
11984
11985 (define_insn "set_got"
11986 [(set (match_operand:SI 0 "register_operand" "=r")
11987 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11988 (clobber (reg:CC FLAGS_REG))]
11989 "!TARGET_64BIT"
11990 "* return output_set_got (operands[0], NULL_RTX);"
11991 [(set_attr "type" "multi")
11992 (set_attr "length" "12")])
11993
11994 (define_insn "set_got_labelled"
11995 [(set (match_operand:SI 0 "register_operand" "=r")
11996 (unspec:SI [(label_ref (match_operand 1))]
11997 UNSPEC_SET_GOT))
11998 (clobber (reg:CC FLAGS_REG))]
11999 "!TARGET_64BIT"
12000 "* return output_set_got (operands[0], operands[1]);"
12001 [(set_attr "type" "multi")
12002 (set_attr "length" "12")])
12003
12004 (define_insn "set_got_rex64"
12005 [(set (match_operand:DI 0 "register_operand" "=r")
12006 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12007 "TARGET_64BIT"
12008 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12009 [(set_attr "type" "lea")
12010 (set_attr "length_address" "4")
12011 (set_attr "mode" "DI")])
12012
12013 (define_insn "set_rip_rex64"
12014 [(set (match_operand:DI 0 "register_operand" "=r")
12015 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12016 "TARGET_64BIT"
12017 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12018 [(set_attr "type" "lea")
12019 (set_attr "length_address" "4")
12020 (set_attr "mode" "DI")])
12021
12022 (define_insn "set_got_offset_rex64"
12023 [(set (match_operand:DI 0 "register_operand" "=r")
12024 (unspec:DI
12025 [(label_ref (match_operand 1))]
12026 UNSPEC_SET_GOT_OFFSET))]
12027 "TARGET_LP64"
12028 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12029 [(set_attr "type" "imov")
12030 (set_attr "length_immediate" "0")
12031 (set_attr "length_address" "8")
12032 (set_attr "mode" "DI")])
12033
12034 (define_expand "epilogue"
12035 [(const_int 0)]
12036 ""
12037 "ix86_expand_epilogue (1); DONE;")
12038
12039 (define_expand "sibcall_epilogue"
12040 [(const_int 0)]
12041 ""
12042 "ix86_expand_epilogue (0); DONE;")
12043
12044 (define_expand "eh_return"
12045 [(use (match_operand 0 "register_operand"))]
12046 ""
12047 {
12048 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12049
12050 /* Tricky bit: we write the address of the handler to which we will
12051 be returning into someone else's stack frame, one word below the
12052 stack address we wish to restore. */
12053 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12054 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12055 tmp = gen_rtx_MEM (Pmode, tmp);
12056 emit_move_insn (tmp, ra);
12057
12058 emit_jump_insn (gen_eh_return_internal ());
12059 emit_barrier ();
12060 DONE;
12061 })
12062
12063 (define_insn_and_split "eh_return_internal"
12064 [(eh_return)]
12065 ""
12066 "#"
12067 "epilogue_completed"
12068 [(const_int 0)]
12069 "ix86_expand_epilogue (2); DONE;")
12070
12071 (define_insn "leave"
12072 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12073 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12074 (clobber (mem:BLK (scratch)))]
12075 "!TARGET_64BIT"
12076 "leave"
12077 [(set_attr "type" "leave")])
12078
12079 (define_insn "leave_rex64"
12080 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12081 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12082 (clobber (mem:BLK (scratch)))]
12083 "TARGET_64BIT"
12084 "leave"
12085 [(set_attr "type" "leave")])
12086 \f
12087 ;; Handle -fsplit-stack.
12088
12089 (define_expand "split_stack_prologue"
12090 [(const_int 0)]
12091 ""
12092 {
12093 ix86_expand_split_stack_prologue ();
12094 DONE;
12095 })
12096
12097 ;; In order to support the call/return predictor, we use a return
12098 ;; instruction which the middle-end doesn't see.
12099 (define_insn "split_stack_return"
12100 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12101 UNSPECV_SPLIT_STACK_RETURN)]
12102 ""
12103 {
12104 if (operands[0] == const0_rtx)
12105 return "ret";
12106 else
12107 return "ret\t%0";
12108 }
12109 [(set_attr "atom_unit" "jeu")
12110 (set_attr "modrm" "0")
12111 (set (attr "length")
12112 (if_then_else (match_operand:SI 0 "const0_operand")
12113 (const_int 1)
12114 (const_int 3)))
12115 (set (attr "length_immediate")
12116 (if_then_else (match_operand:SI 0 "const0_operand")
12117 (const_int 0)
12118 (const_int 2)))])
12119
12120 ;; If there are operand 0 bytes available on the stack, jump to
12121 ;; operand 1.
12122
12123 (define_expand "split_stack_space_check"
12124 [(set (pc) (if_then_else
12125 (ltu (minus (reg SP_REG)
12126 (match_operand 0 "register_operand"))
12127 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12128 (label_ref (match_operand 1))
12129 (pc)))]
12130 ""
12131 {
12132 rtx reg, size, limit;
12133
12134 reg = gen_reg_rtx (Pmode);
12135 size = force_reg (Pmode, operands[0]);
12136 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12137 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12138 UNSPEC_STACK_CHECK);
12139 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12140 ix86_expand_branch (GEU, reg, limit, operands[1]);
12141
12142 DONE;
12143 })
12144 \f
12145 ;; Bit manipulation instructions.
12146
12147 (define_expand "ffs<mode>2"
12148 [(set (match_dup 2) (const_int -1))
12149 (parallel [(set (match_dup 3) (match_dup 4))
12150 (set (match_operand:SWI48 0 "register_operand")
12151 (ctz:SWI48
12152 (match_operand:SWI48 1 "nonimmediate_operand")))])
12153 (set (match_dup 0) (if_then_else:SWI48
12154 (eq (match_dup 3) (const_int 0))
12155 (match_dup 2)
12156 (match_dup 0)))
12157 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12158 (clobber (reg:CC FLAGS_REG))])]
12159 ""
12160 {
12161 enum machine_mode flags_mode;
12162
12163 if (<MODE>mode == SImode && !TARGET_CMOVE)
12164 {
12165 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12166 DONE;
12167 }
12168
12169 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12170
12171 operands[2] = gen_reg_rtx (<MODE>mode);
12172 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12173 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12174 })
12175
12176 (define_insn_and_split "ffssi2_no_cmove"
12177 [(set (match_operand:SI 0 "register_operand" "=r")
12178 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12179 (clobber (match_scratch:SI 2 "=&q"))
12180 (clobber (reg:CC FLAGS_REG))]
12181 "!TARGET_CMOVE"
12182 "#"
12183 "&& reload_completed"
12184 [(parallel [(set (match_dup 4) (match_dup 5))
12185 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12186 (set (strict_low_part (match_dup 3))
12187 (eq:QI (match_dup 4) (const_int 0)))
12188 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12189 (clobber (reg:CC FLAGS_REG))])
12190 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12191 (clobber (reg:CC FLAGS_REG))])
12192 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12193 (clobber (reg:CC FLAGS_REG))])]
12194 {
12195 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12196
12197 operands[3] = gen_lowpart (QImode, operands[2]);
12198 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12199 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12200
12201 ix86_expand_clear (operands[2]);
12202 })
12203
12204 (define_insn "*tzcnt<mode>_1"
12205 [(set (reg:CCC FLAGS_REG)
12206 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12207 (const_int 0)))
12208 (set (match_operand:SWI48 0 "register_operand" "=r")
12209 (ctz:SWI48 (match_dup 1)))]
12210 "TARGET_BMI"
12211 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12212 [(set_attr "type" "alu1")
12213 (set_attr "prefix_0f" "1")
12214 (set_attr "prefix_rep" "1")
12215 (set_attr "mode" "<MODE>")])
12216
12217 (define_insn "*bsf<mode>_1"
12218 [(set (reg:CCZ FLAGS_REG)
12219 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12220 (const_int 0)))
12221 (set (match_operand:SWI48 0 "register_operand" "=r")
12222 (ctz:SWI48 (match_dup 1)))]
12223 ""
12224 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12225 [(set_attr "type" "alu1")
12226 (set_attr "prefix_0f" "1")
12227 (set_attr "mode" "<MODE>")])
12228
12229 (define_insn "ctz<mode>2"
12230 [(set (match_operand:SWI248 0 "register_operand" "=r")
12231 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12232 (clobber (reg:CC FLAGS_REG))]
12233 ""
12234 {
12235 if (TARGET_BMI)
12236 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12237 else if (optimize_function_for_size_p (cfun))
12238 ;
12239 else if (TARGET_GENERIC)
12240 /* tzcnt expands to rep;bsf and we can use it even if !TARGET_BMI. */
12241 return "rep; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12242
12243 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12244 }
12245 [(set_attr "type" "alu1")
12246 (set_attr "prefix_0f" "1")
12247 (set (attr "prefix_rep")
12248 (if_then_else
12249 (ior (match_test "TARGET_BMI")
12250 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12251 (match_test "TARGET_GENERIC")))
12252 (const_string "1")
12253 (const_string "0")))
12254 (set_attr "mode" "<MODE>")])
12255
12256 (define_expand "clz<mode>2"
12257 [(parallel
12258 [(set (match_operand:SWI248 0 "register_operand")
12259 (minus:SWI248
12260 (match_dup 2)
12261 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12262 (clobber (reg:CC FLAGS_REG))])
12263 (parallel
12264 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12265 (clobber (reg:CC FLAGS_REG))])]
12266 ""
12267 {
12268 if (TARGET_LZCNT)
12269 {
12270 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12271 DONE;
12272 }
12273 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12274 })
12275
12276 (define_insn "clz<mode>2_lzcnt"
12277 [(set (match_operand:SWI248 0 "register_operand" "=r")
12278 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12279 (clobber (reg:CC FLAGS_REG))]
12280 "TARGET_LZCNT"
12281 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12282 [(set_attr "prefix_rep" "1")
12283 (set_attr "type" "bitmanip")
12284 (set_attr "mode" "<MODE>")])
12285
12286 ;; BMI instructions.
12287 (define_insn "*bmi_andn_<mode>"
12288 [(set (match_operand:SWI48 0 "register_operand" "=r")
12289 (and:SWI48
12290 (not:SWI48
12291 (match_operand:SWI48 1 "register_operand" "r"))
12292 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12293 (clobber (reg:CC FLAGS_REG))]
12294 "TARGET_BMI"
12295 "andn\t{%2, %1, %0|%0, %1, %2}"
12296 [(set_attr "type" "bitmanip")
12297 (set_attr "mode" "<MODE>")])
12298
12299 (define_insn "bmi_bextr_<mode>"
12300 [(set (match_operand:SWI48 0 "register_operand" "=r")
12301 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12302 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12303 UNSPEC_BEXTR))
12304 (clobber (reg:CC FLAGS_REG))]
12305 "TARGET_BMI"
12306 "bextr\t{%2, %1, %0|%0, %1, %2}"
12307 [(set_attr "type" "bitmanip")
12308 (set_attr "mode" "<MODE>")])
12309
12310 (define_insn "*bmi_blsi_<mode>"
12311 [(set (match_operand:SWI48 0 "register_operand" "=r")
12312 (and:SWI48
12313 (neg:SWI48
12314 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12315 (match_dup 1)))
12316 (clobber (reg:CC FLAGS_REG))]
12317 "TARGET_BMI"
12318 "blsi\t{%1, %0|%0, %1}"
12319 [(set_attr "type" "bitmanip")
12320 (set_attr "mode" "<MODE>")])
12321
12322 (define_insn "*bmi_blsmsk_<mode>"
12323 [(set (match_operand:SWI48 0 "register_operand" "=r")
12324 (xor:SWI48
12325 (plus:SWI48
12326 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12327 (const_int -1))
12328 (match_dup 1)))
12329 (clobber (reg:CC FLAGS_REG))]
12330 "TARGET_BMI"
12331 "blsmsk\t{%1, %0|%0, %1}"
12332 [(set_attr "type" "bitmanip")
12333 (set_attr "mode" "<MODE>")])
12334
12335 (define_insn "*bmi_blsr_<mode>"
12336 [(set (match_operand:SWI48 0 "register_operand" "=r")
12337 (and:SWI48
12338 (plus:SWI48
12339 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12340 (const_int -1))
12341 (match_dup 1)))
12342 (clobber (reg:CC FLAGS_REG))]
12343 "TARGET_BMI"
12344 "blsr\t{%1, %0|%0, %1}"
12345 [(set_attr "type" "bitmanip")
12346 (set_attr "mode" "<MODE>")])
12347
12348 ;; BMI2 instructions.
12349 (define_insn "bmi2_bzhi_<mode>3"
12350 [(set (match_operand:SWI48 0 "register_operand" "=r")
12351 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12352 (lshiftrt:SWI48 (const_int -1)
12353 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12354 (clobber (reg:CC FLAGS_REG))]
12355 "TARGET_BMI2"
12356 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12357 [(set_attr "type" "bitmanip")
12358 (set_attr "prefix" "vex")
12359 (set_attr "mode" "<MODE>")])
12360
12361 (define_insn "bmi2_pdep_<mode>3"
12362 [(set (match_operand:SWI48 0 "register_operand" "=r")
12363 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12364 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12365 UNSPEC_PDEP))]
12366 "TARGET_BMI2"
12367 "pdep\t{%2, %1, %0|%0, %1, %2}"
12368 [(set_attr "type" "bitmanip")
12369 (set_attr "prefix" "vex")
12370 (set_attr "mode" "<MODE>")])
12371
12372 (define_insn "bmi2_pext_<mode>3"
12373 [(set (match_operand:SWI48 0 "register_operand" "=r")
12374 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12375 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12376 UNSPEC_PEXT))]
12377 "TARGET_BMI2"
12378 "pext\t{%2, %1, %0|%0, %1, %2}"
12379 [(set_attr "type" "bitmanip")
12380 (set_attr "prefix" "vex")
12381 (set_attr "mode" "<MODE>")])
12382
12383 ;; TBM instructions.
12384 (define_insn "tbm_bextri_<mode>"
12385 [(set (match_operand:SWI48 0 "register_operand" "=r")
12386 (zero_extract:SWI48
12387 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12388 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12389 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12390 (clobber (reg:CC FLAGS_REG))]
12391 "TARGET_TBM"
12392 {
12393 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12394 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12395 }
12396 [(set_attr "type" "bitmanip")
12397 (set_attr "mode" "<MODE>")])
12398
12399 (define_insn "*tbm_blcfill_<mode>"
12400 [(set (match_operand:SWI48 0 "register_operand" "=r")
12401 (and:SWI48
12402 (plus:SWI48
12403 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12404 (const_int 1))
12405 (match_dup 1)))
12406 (clobber (reg:CC FLAGS_REG))]
12407 "TARGET_TBM"
12408 "blcfill\t{%1, %0|%0, %1}"
12409 [(set_attr "type" "bitmanip")
12410 (set_attr "mode" "<MODE>")])
12411
12412 (define_insn "*tbm_blci_<mode>"
12413 [(set (match_operand:SWI48 0 "register_operand" "=r")
12414 (ior:SWI48
12415 (not:SWI48
12416 (plus:SWI48
12417 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12418 (const_int 1)))
12419 (match_dup 1)))
12420 (clobber (reg:CC FLAGS_REG))]
12421 "TARGET_TBM"
12422 "blci\t{%1, %0|%0, %1}"
12423 [(set_attr "type" "bitmanip")
12424 (set_attr "mode" "<MODE>")])
12425
12426 (define_insn "*tbm_blcic_<mode>"
12427 [(set (match_operand:SWI48 0 "register_operand" "=r")
12428 (and:SWI48
12429 (plus:SWI48
12430 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12431 (const_int 1))
12432 (not:SWI48
12433 (match_dup 1))))
12434 (clobber (reg:CC FLAGS_REG))]
12435 "TARGET_TBM"
12436 "blcic\t{%1, %0|%0, %1}"
12437 [(set_attr "type" "bitmanip")
12438 (set_attr "mode" "<MODE>")])
12439
12440 (define_insn "*tbm_blcmsk_<mode>"
12441 [(set (match_operand:SWI48 0 "register_operand" "=r")
12442 (xor:SWI48
12443 (plus:SWI48
12444 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12445 (const_int 1))
12446 (match_dup 1)))
12447 (clobber (reg:CC FLAGS_REG))]
12448 "TARGET_TBM"
12449 "blcmsk\t{%1, %0|%0, %1}"
12450 [(set_attr "type" "bitmanip")
12451 (set_attr "mode" "<MODE>")])
12452
12453 (define_insn "*tbm_blcs_<mode>"
12454 [(set (match_operand:SWI48 0 "register_operand" "=r")
12455 (ior:SWI48
12456 (plus:SWI48
12457 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12458 (const_int 1))
12459 (match_dup 1)))
12460 (clobber (reg:CC FLAGS_REG))]
12461 "TARGET_TBM"
12462 "blcs\t{%1, %0|%0, %1}"
12463 [(set_attr "type" "bitmanip")
12464 (set_attr "mode" "<MODE>")])
12465
12466 (define_insn "*tbm_blsfill_<mode>"
12467 [(set (match_operand:SWI48 0 "register_operand" "=r")
12468 (ior:SWI48
12469 (plus:SWI48
12470 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12471 (const_int -1))
12472 (match_dup 1)))
12473 (clobber (reg:CC FLAGS_REG))]
12474 "TARGET_TBM"
12475 "blsfill\t{%1, %0|%0, %1}"
12476 [(set_attr "type" "bitmanip")
12477 (set_attr "mode" "<MODE>")])
12478
12479 (define_insn "*tbm_blsic_<mode>"
12480 [(set (match_operand:SWI48 0 "register_operand" "=r")
12481 (ior:SWI48
12482 (plus:SWI48
12483 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12484 (const_int -1))
12485 (not:SWI48
12486 (match_dup 1))))
12487 (clobber (reg:CC FLAGS_REG))]
12488 "TARGET_TBM"
12489 "blsic\t{%1, %0|%0, %1}"
12490 [(set_attr "type" "bitmanip")
12491 (set_attr "mode" "<MODE>")])
12492
12493 (define_insn "*tbm_t1mskc_<mode>"
12494 [(set (match_operand:SWI48 0 "register_operand" "=r")
12495 (ior:SWI48
12496 (plus:SWI48
12497 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12498 (const_int 1))
12499 (not:SWI48
12500 (match_dup 1))))
12501 (clobber (reg:CC FLAGS_REG))]
12502 "TARGET_TBM"
12503 "t1mskc\t{%1, %0|%0, %1}"
12504 [(set_attr "type" "bitmanip")
12505 (set_attr "mode" "<MODE>")])
12506
12507 (define_insn "*tbm_tzmsk_<mode>"
12508 [(set (match_operand:SWI48 0 "register_operand" "=r")
12509 (and:SWI48
12510 (plus:SWI48
12511 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12512 (const_int -1))
12513 (not:SWI48
12514 (match_dup 1))))
12515 (clobber (reg:CC FLAGS_REG))]
12516 "TARGET_TBM"
12517 "tzmsk\t{%1, %0|%0, %1}"
12518 [(set_attr "type" "bitmanip")
12519 (set_attr "mode" "<MODE>")])
12520
12521 (define_insn "bsr_rex64"
12522 [(set (match_operand:DI 0 "register_operand" "=r")
12523 (minus:DI (const_int 63)
12524 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12525 (clobber (reg:CC FLAGS_REG))]
12526 "TARGET_64BIT"
12527 "bsr{q}\t{%1, %0|%0, %1}"
12528 [(set_attr "type" "alu1")
12529 (set_attr "prefix_0f" "1")
12530 (set_attr "mode" "DI")])
12531
12532 (define_insn "bsr"
12533 [(set (match_operand:SI 0 "register_operand" "=r")
12534 (minus:SI (const_int 31)
12535 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12536 (clobber (reg:CC FLAGS_REG))]
12537 ""
12538 "bsr{l}\t{%1, %0|%0, %1}"
12539 [(set_attr "type" "alu1")
12540 (set_attr "prefix_0f" "1")
12541 (set_attr "mode" "SI")])
12542
12543 (define_insn "*bsrhi"
12544 [(set (match_operand:HI 0 "register_operand" "=r")
12545 (minus:HI (const_int 15)
12546 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12547 (clobber (reg:CC FLAGS_REG))]
12548 ""
12549 "bsr{w}\t{%1, %0|%0, %1}"
12550 [(set_attr "type" "alu1")
12551 (set_attr "prefix_0f" "1")
12552 (set_attr "mode" "HI")])
12553
12554 (define_insn "popcount<mode>2"
12555 [(set (match_operand:SWI248 0 "register_operand" "=r")
12556 (popcount:SWI248
12557 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12558 (clobber (reg:CC FLAGS_REG))]
12559 "TARGET_POPCNT"
12560 {
12561 #if TARGET_MACHO
12562 return "popcnt\t{%1, %0|%0, %1}";
12563 #else
12564 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12565 #endif
12566 }
12567 [(set_attr "prefix_rep" "1")
12568 (set_attr "type" "bitmanip")
12569 (set_attr "mode" "<MODE>")])
12570
12571 (define_insn "*popcount<mode>2_cmp"
12572 [(set (reg FLAGS_REG)
12573 (compare
12574 (popcount:SWI248
12575 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12576 (const_int 0)))
12577 (set (match_operand:SWI248 0 "register_operand" "=r")
12578 (popcount:SWI248 (match_dup 1)))]
12579 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12580 {
12581 #if TARGET_MACHO
12582 return "popcnt\t{%1, %0|%0, %1}";
12583 #else
12584 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12585 #endif
12586 }
12587 [(set_attr "prefix_rep" "1")
12588 (set_attr "type" "bitmanip")
12589 (set_attr "mode" "<MODE>")])
12590
12591 (define_insn "*popcountsi2_cmp_zext"
12592 [(set (reg FLAGS_REG)
12593 (compare
12594 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12595 (const_int 0)))
12596 (set (match_operand:DI 0 "register_operand" "=r")
12597 (zero_extend:DI(popcount:SI (match_dup 1))))]
12598 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12599 {
12600 #if TARGET_MACHO
12601 return "popcnt\t{%1, %0|%0, %1}";
12602 #else
12603 return "popcnt{l}\t{%1, %0|%0, %1}";
12604 #endif
12605 }
12606 [(set_attr "prefix_rep" "1")
12607 (set_attr "type" "bitmanip")
12608 (set_attr "mode" "SI")])
12609
12610 (define_expand "bswapdi2"
12611 [(set (match_operand:DI 0 "register_operand")
12612 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12613 ""
12614 {
12615 if (TARGET_64BIT && !TARGET_MOVBE)
12616 operands[1] = force_reg (DImode, operands[1]);
12617 })
12618
12619 (define_insn_and_split "*bswapdi2_doubleword"
12620 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12621 (bswap:DI
12622 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12623 "!TARGET_64BIT
12624 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12625 "#"
12626 "&& reload_completed"
12627 [(set (match_dup 2)
12628 (bswap:SI (match_dup 1)))
12629 (set (match_dup 0)
12630 (bswap:SI (match_dup 3)))]
12631 {
12632 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12633
12634 if (REG_P (operands[0]) && REG_P (operands[1]))
12635 {
12636 emit_insn (gen_swapsi (operands[0], operands[2]));
12637 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12638 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12639 DONE;
12640 }
12641
12642 if (!TARGET_MOVBE)
12643 {
12644 if (MEM_P (operands[0]))
12645 {
12646 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12647 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12648
12649 emit_move_insn (operands[0], operands[3]);
12650 emit_move_insn (operands[2], operands[1]);
12651 }
12652 if (MEM_P (operands[1]))
12653 {
12654 emit_move_insn (operands[2], operands[1]);
12655 emit_move_insn (operands[0], operands[3]);
12656
12657 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12658 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12659 }
12660 DONE;
12661 }
12662 })
12663
12664 (define_expand "bswapsi2"
12665 [(set (match_operand:SI 0 "register_operand")
12666 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12667 ""
12668 {
12669 if (TARGET_MOVBE)
12670 ;
12671 else if (TARGET_BSWAP)
12672 operands[1] = force_reg (SImode, operands[1]);
12673 else
12674 {
12675 rtx x = operands[0];
12676
12677 emit_move_insn (x, operands[1]);
12678 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12679 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12680 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12681 DONE;
12682 }
12683 })
12684
12685 (define_insn "*bswap<mode>2_movbe"
12686 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12687 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12688 "TARGET_MOVBE
12689 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12690 "@
12691 bswap\t%0
12692 movbe\t{%1, %0|%0, %1}
12693 movbe\t{%1, %0|%0, %1}"
12694 [(set_attr "type" "bitmanip,imov,imov")
12695 (set_attr "modrm" "0,1,1")
12696 (set_attr "prefix_0f" "*,1,1")
12697 (set_attr "prefix_extra" "*,1,1")
12698 (set_attr "mode" "<MODE>")])
12699
12700 (define_insn "*bswap<mode>2"
12701 [(set (match_operand:SWI48 0 "register_operand" "=r")
12702 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12703 "TARGET_BSWAP"
12704 "bswap\t%0"
12705 [(set_attr "type" "bitmanip")
12706 (set_attr "modrm" "0")
12707 (set_attr "mode" "<MODE>")])
12708
12709 (define_insn "*bswaphi_lowpart_1"
12710 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12711 (bswap:HI (match_dup 0)))
12712 (clobber (reg:CC FLAGS_REG))]
12713 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12714 "@
12715 xchg{b}\t{%h0, %b0|%b0, %h0}
12716 rol{w}\t{$8, %0|%0, 8}"
12717 [(set_attr "length" "2,4")
12718 (set_attr "mode" "QI,HI")])
12719
12720 (define_insn "bswaphi_lowpart"
12721 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12722 (bswap:HI (match_dup 0)))
12723 (clobber (reg:CC FLAGS_REG))]
12724 ""
12725 "rol{w}\t{$8, %0|%0, 8}"
12726 [(set_attr "length" "4")
12727 (set_attr "mode" "HI")])
12728
12729 (define_expand "paritydi2"
12730 [(set (match_operand:DI 0 "register_operand")
12731 (parity:DI (match_operand:DI 1 "register_operand")))]
12732 "! TARGET_POPCNT"
12733 {
12734 rtx scratch = gen_reg_rtx (QImode);
12735 rtx cond;
12736
12737 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12738 NULL_RTX, operands[1]));
12739
12740 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12741 gen_rtx_REG (CCmode, FLAGS_REG),
12742 const0_rtx);
12743 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12744
12745 if (TARGET_64BIT)
12746 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12747 else
12748 {
12749 rtx tmp = gen_reg_rtx (SImode);
12750
12751 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12752 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12753 }
12754 DONE;
12755 })
12756
12757 (define_expand "paritysi2"
12758 [(set (match_operand:SI 0 "register_operand")
12759 (parity:SI (match_operand:SI 1 "register_operand")))]
12760 "! TARGET_POPCNT"
12761 {
12762 rtx scratch = gen_reg_rtx (QImode);
12763 rtx cond;
12764
12765 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12766
12767 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12768 gen_rtx_REG (CCmode, FLAGS_REG),
12769 const0_rtx);
12770 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12771
12772 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12773 DONE;
12774 })
12775
12776 (define_insn_and_split "paritydi2_cmp"
12777 [(set (reg:CC FLAGS_REG)
12778 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12779 UNSPEC_PARITY))
12780 (clobber (match_scratch:DI 0 "=r"))
12781 (clobber (match_scratch:SI 1 "=&r"))
12782 (clobber (match_scratch:HI 2 "=Q"))]
12783 "! TARGET_POPCNT"
12784 "#"
12785 "&& reload_completed"
12786 [(parallel
12787 [(set (match_dup 1)
12788 (xor:SI (match_dup 1) (match_dup 4)))
12789 (clobber (reg:CC FLAGS_REG))])
12790 (parallel
12791 [(set (reg:CC FLAGS_REG)
12792 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12793 (clobber (match_dup 1))
12794 (clobber (match_dup 2))])]
12795 {
12796 operands[4] = gen_lowpart (SImode, operands[3]);
12797
12798 if (TARGET_64BIT)
12799 {
12800 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12801 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12802 }
12803 else
12804 operands[1] = gen_highpart (SImode, operands[3]);
12805 })
12806
12807 (define_insn_and_split "paritysi2_cmp"
12808 [(set (reg:CC FLAGS_REG)
12809 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12810 UNSPEC_PARITY))
12811 (clobber (match_scratch:SI 0 "=r"))
12812 (clobber (match_scratch:HI 1 "=&Q"))]
12813 "! TARGET_POPCNT"
12814 "#"
12815 "&& reload_completed"
12816 [(parallel
12817 [(set (match_dup 1)
12818 (xor:HI (match_dup 1) (match_dup 3)))
12819 (clobber (reg:CC FLAGS_REG))])
12820 (parallel
12821 [(set (reg:CC FLAGS_REG)
12822 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12823 (clobber (match_dup 1))])]
12824 {
12825 operands[3] = gen_lowpart (HImode, operands[2]);
12826
12827 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12828 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12829 })
12830
12831 (define_insn "*parityhi2_cmp"
12832 [(set (reg:CC FLAGS_REG)
12833 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12834 UNSPEC_PARITY))
12835 (clobber (match_scratch:HI 0 "=Q"))]
12836 "! TARGET_POPCNT"
12837 "xor{b}\t{%h0, %b0|%b0, %h0}"
12838 [(set_attr "length" "2")
12839 (set_attr "mode" "HI")])
12840
12841 \f
12842 ;; Thread-local storage patterns for ELF.
12843 ;;
12844 ;; Note that these code sequences must appear exactly as shown
12845 ;; in order to allow linker relaxation.
12846
12847 (define_insn "*tls_global_dynamic_32_gnu"
12848 [(set (match_operand:SI 0 "register_operand" "=a")
12849 (unspec:SI
12850 [(match_operand:SI 1 "register_operand" "b")
12851 (match_operand 2 "tls_symbolic_operand")
12852 (match_operand 3 "constant_call_address_operand" "z")]
12853 UNSPEC_TLS_GD))
12854 (clobber (match_scratch:SI 4 "=d"))
12855 (clobber (match_scratch:SI 5 "=c"))
12856 (clobber (reg:CC FLAGS_REG))]
12857 "!TARGET_64BIT && TARGET_GNU_TLS"
12858 {
12859 output_asm_insn
12860 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12861 if (TARGET_SUN_TLS)
12862 #ifdef HAVE_AS_IX86_TLSGDPLT
12863 return "call\t%a2@tlsgdplt";
12864 #else
12865 return "call\t%p3@plt";
12866 #endif
12867 return "call\t%P3";
12868 }
12869 [(set_attr "type" "multi")
12870 (set_attr "length" "12")])
12871
12872 (define_expand "tls_global_dynamic_32"
12873 [(parallel
12874 [(set (match_operand:SI 0 "register_operand")
12875 (unspec:SI [(match_operand:SI 2 "register_operand")
12876 (match_operand 1 "tls_symbolic_operand")
12877 (match_operand 3 "constant_call_address_operand")]
12878 UNSPEC_TLS_GD))
12879 (clobber (match_scratch:SI 4))
12880 (clobber (match_scratch:SI 5))
12881 (clobber (reg:CC FLAGS_REG))])])
12882
12883 (define_insn "*tls_global_dynamic_64_<mode>"
12884 [(set (match_operand:P 0 "register_operand" "=a")
12885 (call:P
12886 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12887 (match_operand 3)))
12888 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12889 UNSPEC_TLS_GD)]
12890 "TARGET_64BIT"
12891 {
12892 if (!TARGET_X32)
12893 fputs (ASM_BYTE "0x66\n", asm_out_file);
12894 output_asm_insn
12895 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12896 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12897 fputs ("\trex64\n", asm_out_file);
12898 if (TARGET_SUN_TLS)
12899 return "call\t%p2@plt";
12900 return "call\t%P2";
12901 }
12902 [(set_attr "type" "multi")
12903 (set (attr "length")
12904 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12905
12906 (define_expand "tls_global_dynamic_64_<mode>"
12907 [(parallel
12908 [(set (match_operand:P 0 "register_operand")
12909 (call:P
12910 (mem:QI (match_operand 2 "constant_call_address_operand"))
12911 (const_int 0)))
12912 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12913 UNSPEC_TLS_GD)])]
12914 "TARGET_64BIT")
12915
12916 (define_insn "*tls_local_dynamic_base_32_gnu"
12917 [(set (match_operand:SI 0 "register_operand" "=a")
12918 (unspec:SI
12919 [(match_operand:SI 1 "register_operand" "b")
12920 (match_operand 2 "constant_call_address_operand" "z")]
12921 UNSPEC_TLS_LD_BASE))
12922 (clobber (match_scratch:SI 3 "=d"))
12923 (clobber (match_scratch:SI 4 "=c"))
12924 (clobber (reg:CC FLAGS_REG))]
12925 "!TARGET_64BIT && TARGET_GNU_TLS"
12926 {
12927 output_asm_insn
12928 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12929 if (TARGET_SUN_TLS)
12930 #ifdef HAVE_AS_IX86_TLSLDMPLT
12931 return "call\t%&@tlsldmplt";
12932 #else
12933 return "call\t%p2@plt";
12934 #endif
12935 return "call\t%P2";
12936 }
12937 [(set_attr "type" "multi")
12938 (set_attr "length" "11")])
12939
12940 (define_expand "tls_local_dynamic_base_32"
12941 [(parallel
12942 [(set (match_operand:SI 0 "register_operand")
12943 (unspec:SI
12944 [(match_operand:SI 1 "register_operand")
12945 (match_operand 2 "constant_call_address_operand")]
12946 UNSPEC_TLS_LD_BASE))
12947 (clobber (match_scratch:SI 3))
12948 (clobber (match_scratch:SI 4))
12949 (clobber (reg:CC FLAGS_REG))])])
12950
12951 (define_insn "*tls_local_dynamic_base_64_<mode>"
12952 [(set (match_operand:P 0 "register_operand" "=a")
12953 (call:P
12954 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12955 (match_operand 2)))
12956 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12957 "TARGET_64BIT"
12958 {
12959 output_asm_insn
12960 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12961 if (TARGET_SUN_TLS)
12962 return "call\t%p1@plt";
12963 return "call\t%P1";
12964 }
12965 [(set_attr "type" "multi")
12966 (set_attr "length" "12")])
12967
12968 (define_expand "tls_local_dynamic_base_64_<mode>"
12969 [(parallel
12970 [(set (match_operand:P 0 "register_operand")
12971 (call:P
12972 (mem:QI (match_operand 1 "constant_call_address_operand"))
12973 (const_int 0)))
12974 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12975 "TARGET_64BIT")
12976
12977 ;; Local dynamic of a single variable is a lose. Show combine how
12978 ;; to convert that back to global dynamic.
12979
12980 (define_insn_and_split "*tls_local_dynamic_32_once"
12981 [(set (match_operand:SI 0 "register_operand" "=a")
12982 (plus:SI
12983 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12984 (match_operand 2 "constant_call_address_operand" "z")]
12985 UNSPEC_TLS_LD_BASE)
12986 (const:SI (unspec:SI
12987 [(match_operand 3 "tls_symbolic_operand")]
12988 UNSPEC_DTPOFF))))
12989 (clobber (match_scratch:SI 4 "=d"))
12990 (clobber (match_scratch:SI 5 "=c"))
12991 (clobber (reg:CC FLAGS_REG))]
12992 ""
12993 "#"
12994 ""
12995 [(parallel
12996 [(set (match_dup 0)
12997 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12998 UNSPEC_TLS_GD))
12999 (clobber (match_dup 4))
13000 (clobber (match_dup 5))
13001 (clobber (reg:CC FLAGS_REG))])])
13002
13003 ;; Segment register for the thread base ptr load
13004 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13005
13006 ;; Load and add the thread base pointer from %<tp_seg>:0.
13007 (define_insn "*load_tp_x32"
13008 [(set (match_operand:SI 0 "register_operand" "=r")
13009 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13010 "TARGET_X32"
13011 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13012 [(set_attr "type" "imov")
13013 (set_attr "modrm" "0")
13014 (set_attr "length" "7")
13015 (set_attr "memory" "load")
13016 (set_attr "imm_disp" "false")])
13017
13018 (define_insn "*load_tp_x32_zext"
13019 [(set (match_operand:DI 0 "register_operand" "=r")
13020 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13021 "TARGET_X32"
13022 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13023 [(set_attr "type" "imov")
13024 (set_attr "modrm" "0")
13025 (set_attr "length" "7")
13026 (set_attr "memory" "load")
13027 (set_attr "imm_disp" "false")])
13028
13029 (define_insn "*load_tp_<mode>"
13030 [(set (match_operand:P 0 "register_operand" "=r")
13031 (unspec:P [(const_int 0)] UNSPEC_TP))]
13032 "!TARGET_X32"
13033 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13034 [(set_attr "type" "imov")
13035 (set_attr "modrm" "0")
13036 (set_attr "length" "7")
13037 (set_attr "memory" "load")
13038 (set_attr "imm_disp" "false")])
13039
13040 (define_insn "*add_tp_x32"
13041 [(set (match_operand:SI 0 "register_operand" "=r")
13042 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13043 (match_operand:SI 1 "register_operand" "0")))
13044 (clobber (reg:CC FLAGS_REG))]
13045 "TARGET_X32"
13046 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13047 [(set_attr "type" "alu")
13048 (set_attr "modrm" "0")
13049 (set_attr "length" "7")
13050 (set_attr "memory" "load")
13051 (set_attr "imm_disp" "false")])
13052
13053 (define_insn "*add_tp_x32_zext"
13054 [(set (match_operand:DI 0 "register_operand" "=r")
13055 (zero_extend:DI
13056 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13057 (match_operand:SI 1 "register_operand" "0"))))
13058 (clobber (reg:CC FLAGS_REG))]
13059 "TARGET_X32"
13060 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13061 [(set_attr "type" "alu")
13062 (set_attr "modrm" "0")
13063 (set_attr "length" "7")
13064 (set_attr "memory" "load")
13065 (set_attr "imm_disp" "false")])
13066
13067 (define_insn "*add_tp_<mode>"
13068 [(set (match_operand:P 0 "register_operand" "=r")
13069 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13070 (match_operand:P 1 "register_operand" "0")))
13071 (clobber (reg:CC FLAGS_REG))]
13072 "!TARGET_X32"
13073 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13074 [(set_attr "type" "alu")
13075 (set_attr "modrm" "0")
13076 (set_attr "length" "7")
13077 (set_attr "memory" "load")
13078 (set_attr "imm_disp" "false")])
13079
13080 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13081 ;; %rax as destination of the initial executable code sequence.
13082 (define_insn "tls_initial_exec_64_sun"
13083 [(set (match_operand:DI 0 "register_operand" "=a")
13084 (unspec:DI
13085 [(match_operand 1 "tls_symbolic_operand")]
13086 UNSPEC_TLS_IE_SUN))
13087 (clobber (reg:CC FLAGS_REG))]
13088 "TARGET_64BIT && TARGET_SUN_TLS"
13089 {
13090 output_asm_insn
13091 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13092 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13093 }
13094 [(set_attr "type" "multi")])
13095
13096 ;; GNU2 TLS patterns can be split.
13097
13098 (define_expand "tls_dynamic_gnu2_32"
13099 [(set (match_dup 3)
13100 (plus:SI (match_operand:SI 2 "register_operand")
13101 (const:SI
13102 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13103 UNSPEC_TLSDESC))))
13104 (parallel
13105 [(set (match_operand:SI 0 "register_operand")
13106 (unspec:SI [(match_dup 1) (match_dup 3)
13107 (match_dup 2) (reg:SI SP_REG)]
13108 UNSPEC_TLSDESC))
13109 (clobber (reg:CC FLAGS_REG))])]
13110 "!TARGET_64BIT && TARGET_GNU2_TLS"
13111 {
13112 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13113 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13114 })
13115
13116 (define_insn "*tls_dynamic_gnu2_lea_32"
13117 [(set (match_operand:SI 0 "register_operand" "=r")
13118 (plus:SI (match_operand:SI 1 "register_operand" "b")
13119 (const:SI
13120 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13121 UNSPEC_TLSDESC))))]
13122 "!TARGET_64BIT && TARGET_GNU2_TLS"
13123 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13124 [(set_attr "type" "lea")
13125 (set_attr "mode" "SI")
13126 (set_attr "length" "6")
13127 (set_attr "length_address" "4")])
13128
13129 (define_insn "*tls_dynamic_gnu2_call_32"
13130 [(set (match_operand:SI 0 "register_operand" "=a")
13131 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13132 (match_operand:SI 2 "register_operand" "0")
13133 ;; we have to make sure %ebx still points to the GOT
13134 (match_operand:SI 3 "register_operand" "b")
13135 (reg:SI SP_REG)]
13136 UNSPEC_TLSDESC))
13137 (clobber (reg:CC FLAGS_REG))]
13138 "!TARGET_64BIT && TARGET_GNU2_TLS"
13139 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13140 [(set_attr "type" "call")
13141 (set_attr "length" "2")
13142 (set_attr "length_address" "0")])
13143
13144 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13145 [(set (match_operand:SI 0 "register_operand" "=&a")
13146 (plus:SI
13147 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13148 (match_operand:SI 4)
13149 (match_operand:SI 2 "register_operand" "b")
13150 (reg:SI SP_REG)]
13151 UNSPEC_TLSDESC)
13152 (const:SI (unspec:SI
13153 [(match_operand 1 "tls_symbolic_operand")]
13154 UNSPEC_DTPOFF))))
13155 (clobber (reg:CC FLAGS_REG))]
13156 "!TARGET_64BIT && TARGET_GNU2_TLS"
13157 "#"
13158 ""
13159 [(set (match_dup 0) (match_dup 5))]
13160 {
13161 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13162 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13163 })
13164
13165 (define_expand "tls_dynamic_gnu2_64"
13166 [(set (match_dup 2)
13167 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13168 UNSPEC_TLSDESC))
13169 (parallel
13170 [(set (match_operand:DI 0 "register_operand")
13171 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13172 UNSPEC_TLSDESC))
13173 (clobber (reg:CC FLAGS_REG))])]
13174 "TARGET_64BIT && TARGET_GNU2_TLS"
13175 {
13176 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13177 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13178 })
13179
13180 (define_insn "*tls_dynamic_gnu2_lea_64"
13181 [(set (match_operand:DI 0 "register_operand" "=r")
13182 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13183 UNSPEC_TLSDESC))]
13184 "TARGET_64BIT && TARGET_GNU2_TLS"
13185 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13186 [(set_attr "type" "lea")
13187 (set_attr "mode" "DI")
13188 (set_attr "length" "7")
13189 (set_attr "length_address" "4")])
13190
13191 (define_insn "*tls_dynamic_gnu2_call_64"
13192 [(set (match_operand:DI 0 "register_operand" "=a")
13193 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13194 (match_operand:DI 2 "register_operand" "0")
13195 (reg:DI SP_REG)]
13196 UNSPEC_TLSDESC))
13197 (clobber (reg:CC FLAGS_REG))]
13198 "TARGET_64BIT && TARGET_GNU2_TLS"
13199 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13200 [(set_attr "type" "call")
13201 (set_attr "length" "2")
13202 (set_attr "length_address" "0")])
13203
13204 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13205 [(set (match_operand:DI 0 "register_operand" "=&a")
13206 (plus:DI
13207 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13208 (match_operand:DI 3)
13209 (reg:DI SP_REG)]
13210 UNSPEC_TLSDESC)
13211 (const:DI (unspec:DI
13212 [(match_operand 1 "tls_symbolic_operand")]
13213 UNSPEC_DTPOFF))))
13214 (clobber (reg:CC FLAGS_REG))]
13215 "TARGET_64BIT && TARGET_GNU2_TLS"
13216 "#"
13217 ""
13218 [(set (match_dup 0) (match_dup 4))]
13219 {
13220 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13221 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13222 })
13223 \f
13224 ;; These patterns match the binary 387 instructions for addM3, subM3,
13225 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13226 ;; SFmode. The first is the normal insn, the second the same insn but
13227 ;; with one operand a conversion, and the third the same insn but with
13228 ;; the other operand a conversion. The conversion may be SFmode or
13229 ;; SImode if the target mode DFmode, but only SImode if the target mode
13230 ;; is SFmode.
13231
13232 ;; Gcc is slightly more smart about handling normal two address instructions
13233 ;; so use special patterns for add and mull.
13234
13235 (define_insn "*fop_<mode>_comm_mixed"
13236 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13237 (match_operator:MODEF 3 "binary_fp_operator"
13238 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13239 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13240 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13241 && COMMUTATIVE_ARITH_P (operands[3])
13242 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13243 "* return output_387_binary_op (insn, operands);"
13244 [(set (attr "type")
13245 (if_then_else (eq_attr "alternative" "1,2")
13246 (if_then_else (match_operand:MODEF 3 "mult_operator")
13247 (const_string "ssemul")
13248 (const_string "sseadd"))
13249 (if_then_else (match_operand:MODEF 3 "mult_operator")
13250 (const_string "fmul")
13251 (const_string "fop"))))
13252 (set_attr "isa" "*,noavx,avx")
13253 (set_attr "prefix" "orig,orig,vex")
13254 (set_attr "mode" "<MODE>")])
13255
13256 (define_insn "*fop_<mode>_comm_sse"
13257 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13258 (match_operator:MODEF 3 "binary_fp_operator"
13259 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13260 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13261 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13262 && COMMUTATIVE_ARITH_P (operands[3])
13263 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13264 "* return output_387_binary_op (insn, operands);"
13265 [(set (attr "type")
13266 (if_then_else (match_operand:MODEF 3 "mult_operator")
13267 (const_string "ssemul")
13268 (const_string "sseadd")))
13269 (set_attr "isa" "noavx,avx")
13270 (set_attr "prefix" "orig,vex")
13271 (set_attr "mode" "<MODE>")])
13272
13273 (define_insn "*fop_<mode>_comm_i387"
13274 [(set (match_operand:MODEF 0 "register_operand" "=f")
13275 (match_operator:MODEF 3 "binary_fp_operator"
13276 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13277 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13278 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13279 && COMMUTATIVE_ARITH_P (operands[3])
13280 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13281 "* return output_387_binary_op (insn, operands);"
13282 [(set (attr "type")
13283 (if_then_else (match_operand:MODEF 3 "mult_operator")
13284 (const_string "fmul")
13285 (const_string "fop")))
13286 (set_attr "mode" "<MODE>")])
13287
13288 (define_insn "*fop_<mode>_1_mixed"
13289 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13290 (match_operator:MODEF 3 "binary_fp_operator"
13291 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13292 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13293 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13294 && !COMMUTATIVE_ARITH_P (operands[3])
13295 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13296 "* return output_387_binary_op (insn, operands);"
13297 [(set (attr "type")
13298 (cond [(and (eq_attr "alternative" "2,3")
13299 (match_operand:MODEF 3 "mult_operator"))
13300 (const_string "ssemul")
13301 (and (eq_attr "alternative" "2,3")
13302 (match_operand:MODEF 3 "div_operator"))
13303 (const_string "ssediv")
13304 (eq_attr "alternative" "2,3")
13305 (const_string "sseadd")
13306 (match_operand:MODEF 3 "mult_operator")
13307 (const_string "fmul")
13308 (match_operand:MODEF 3 "div_operator")
13309 (const_string "fdiv")
13310 ]
13311 (const_string "fop")))
13312 (set_attr "isa" "*,*,noavx,avx")
13313 (set_attr "prefix" "orig,orig,orig,vex")
13314 (set_attr "mode" "<MODE>")])
13315
13316 (define_insn "*rcpsf2_sse"
13317 [(set (match_operand:SF 0 "register_operand" "=x")
13318 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13319 UNSPEC_RCP))]
13320 "TARGET_SSE_MATH"
13321 "%vrcpss\t{%1, %d0|%d0, %1}"
13322 [(set_attr "type" "sse")
13323 (set_attr "atom_sse_attr" "rcp")
13324 (set_attr "prefix" "maybe_vex")
13325 (set_attr "mode" "SF")])
13326
13327 (define_insn "*fop_<mode>_1_sse"
13328 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13329 (match_operator:MODEF 3 "binary_fp_operator"
13330 [(match_operand:MODEF 1 "register_operand" "0,x")
13331 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13332 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13333 && !COMMUTATIVE_ARITH_P (operands[3])"
13334 "* return output_387_binary_op (insn, operands);"
13335 [(set (attr "type")
13336 (cond [(match_operand:MODEF 3 "mult_operator")
13337 (const_string "ssemul")
13338 (match_operand:MODEF 3 "div_operator")
13339 (const_string "ssediv")
13340 ]
13341 (const_string "sseadd")))
13342 (set_attr "isa" "noavx,avx")
13343 (set_attr "prefix" "orig,vex")
13344 (set_attr "mode" "<MODE>")])
13345
13346 ;; This pattern is not fully shadowed by the pattern above.
13347 (define_insn "*fop_<mode>_1_i387"
13348 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13349 (match_operator:MODEF 3 "binary_fp_operator"
13350 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13351 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13352 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13353 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13354 && !COMMUTATIVE_ARITH_P (operands[3])
13355 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13356 "* return output_387_binary_op (insn, operands);"
13357 [(set (attr "type")
13358 (cond [(match_operand:MODEF 3 "mult_operator")
13359 (const_string "fmul")
13360 (match_operand:MODEF 3 "div_operator")
13361 (const_string "fdiv")
13362 ]
13363 (const_string "fop")))
13364 (set_attr "mode" "<MODE>")])
13365
13366 ;; ??? Add SSE splitters for these!
13367 (define_insn "*fop_<MODEF:mode>_2_i387"
13368 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13369 (match_operator:MODEF 3 "binary_fp_operator"
13370 [(float:MODEF
13371 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13372 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13373 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13374 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13375 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13376 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13377 [(set (attr "type")
13378 (cond [(match_operand:MODEF 3 "mult_operator")
13379 (const_string "fmul")
13380 (match_operand:MODEF 3 "div_operator")
13381 (const_string "fdiv")
13382 ]
13383 (const_string "fop")))
13384 (set_attr "fp_int_src" "true")
13385 (set_attr "mode" "<SWI24:MODE>")])
13386
13387 (define_insn "*fop_<MODEF:mode>_3_i387"
13388 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13389 (match_operator:MODEF 3 "binary_fp_operator"
13390 [(match_operand:MODEF 1 "register_operand" "0,0")
13391 (float:MODEF
13392 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13393 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13394 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13395 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13396 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13397 [(set (attr "type")
13398 (cond [(match_operand:MODEF 3 "mult_operator")
13399 (const_string "fmul")
13400 (match_operand:MODEF 3 "div_operator")
13401 (const_string "fdiv")
13402 ]
13403 (const_string "fop")))
13404 (set_attr "fp_int_src" "true")
13405 (set_attr "mode" "<MODE>")])
13406
13407 (define_insn "*fop_df_4_i387"
13408 [(set (match_operand:DF 0 "register_operand" "=f,f")
13409 (match_operator:DF 3 "binary_fp_operator"
13410 [(float_extend:DF
13411 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13412 (match_operand:DF 2 "register_operand" "0,f")]))]
13413 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13414 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13415 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13416 "* return output_387_binary_op (insn, operands);"
13417 [(set (attr "type")
13418 (cond [(match_operand:DF 3 "mult_operator")
13419 (const_string "fmul")
13420 (match_operand:DF 3 "div_operator")
13421 (const_string "fdiv")
13422 ]
13423 (const_string "fop")))
13424 (set_attr "mode" "SF")])
13425
13426 (define_insn "*fop_df_5_i387"
13427 [(set (match_operand:DF 0 "register_operand" "=f,f")
13428 (match_operator:DF 3 "binary_fp_operator"
13429 [(match_operand:DF 1 "register_operand" "0,f")
13430 (float_extend:DF
13431 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13432 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13433 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13434 "* return output_387_binary_op (insn, operands);"
13435 [(set (attr "type")
13436 (cond [(match_operand:DF 3 "mult_operator")
13437 (const_string "fmul")
13438 (match_operand:DF 3 "div_operator")
13439 (const_string "fdiv")
13440 ]
13441 (const_string "fop")))
13442 (set_attr "mode" "SF")])
13443
13444 (define_insn "*fop_df_6_i387"
13445 [(set (match_operand:DF 0 "register_operand" "=f,f")
13446 (match_operator:DF 3 "binary_fp_operator"
13447 [(float_extend:DF
13448 (match_operand:SF 1 "register_operand" "0,f"))
13449 (float_extend:DF
13450 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13451 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13452 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13453 "* return output_387_binary_op (insn, operands);"
13454 [(set (attr "type")
13455 (cond [(match_operand:DF 3 "mult_operator")
13456 (const_string "fmul")
13457 (match_operand:DF 3 "div_operator")
13458 (const_string "fdiv")
13459 ]
13460 (const_string "fop")))
13461 (set_attr "mode" "SF")])
13462
13463 (define_insn "*fop_xf_comm_i387"
13464 [(set (match_operand:XF 0 "register_operand" "=f")
13465 (match_operator:XF 3 "binary_fp_operator"
13466 [(match_operand:XF 1 "register_operand" "%0")
13467 (match_operand:XF 2 "register_operand" "f")]))]
13468 "TARGET_80387
13469 && COMMUTATIVE_ARITH_P (operands[3])"
13470 "* return output_387_binary_op (insn, operands);"
13471 [(set (attr "type")
13472 (if_then_else (match_operand:XF 3 "mult_operator")
13473 (const_string "fmul")
13474 (const_string "fop")))
13475 (set_attr "mode" "XF")])
13476
13477 (define_insn "*fop_xf_1_i387"
13478 [(set (match_operand:XF 0 "register_operand" "=f,f")
13479 (match_operator:XF 3 "binary_fp_operator"
13480 [(match_operand:XF 1 "register_operand" "0,f")
13481 (match_operand:XF 2 "register_operand" "f,0")]))]
13482 "TARGET_80387
13483 && !COMMUTATIVE_ARITH_P (operands[3])"
13484 "* return output_387_binary_op (insn, operands);"
13485 [(set (attr "type")
13486 (cond [(match_operand:XF 3 "mult_operator")
13487 (const_string "fmul")
13488 (match_operand:XF 3 "div_operator")
13489 (const_string "fdiv")
13490 ]
13491 (const_string "fop")))
13492 (set_attr "mode" "XF")])
13493
13494 (define_insn "*fop_xf_2_i387"
13495 [(set (match_operand:XF 0 "register_operand" "=f,f")
13496 (match_operator:XF 3 "binary_fp_operator"
13497 [(float:XF
13498 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13499 (match_operand:XF 2 "register_operand" "0,0")]))]
13500 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13501 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13502 [(set (attr "type")
13503 (cond [(match_operand:XF 3 "mult_operator")
13504 (const_string "fmul")
13505 (match_operand:XF 3 "div_operator")
13506 (const_string "fdiv")
13507 ]
13508 (const_string "fop")))
13509 (set_attr "fp_int_src" "true")
13510 (set_attr "mode" "<MODE>")])
13511
13512 (define_insn "*fop_xf_3_i387"
13513 [(set (match_operand:XF 0 "register_operand" "=f,f")
13514 (match_operator:XF 3 "binary_fp_operator"
13515 [(match_operand:XF 1 "register_operand" "0,0")
13516 (float:XF
13517 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13518 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13519 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13520 [(set (attr "type")
13521 (cond [(match_operand:XF 3 "mult_operator")
13522 (const_string "fmul")
13523 (match_operand:XF 3 "div_operator")
13524 (const_string "fdiv")
13525 ]
13526 (const_string "fop")))
13527 (set_attr "fp_int_src" "true")
13528 (set_attr "mode" "<MODE>")])
13529
13530 (define_insn "*fop_xf_4_i387"
13531 [(set (match_operand:XF 0 "register_operand" "=f,f")
13532 (match_operator:XF 3 "binary_fp_operator"
13533 [(float_extend:XF
13534 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13535 (match_operand:XF 2 "register_operand" "0,f")]))]
13536 "TARGET_80387"
13537 "* return output_387_binary_op (insn, operands);"
13538 [(set (attr "type")
13539 (cond [(match_operand:XF 3 "mult_operator")
13540 (const_string "fmul")
13541 (match_operand:XF 3 "div_operator")
13542 (const_string "fdiv")
13543 ]
13544 (const_string "fop")))
13545 (set_attr "mode" "<MODE>")])
13546
13547 (define_insn "*fop_xf_5_i387"
13548 [(set (match_operand:XF 0 "register_operand" "=f,f")
13549 (match_operator:XF 3 "binary_fp_operator"
13550 [(match_operand:XF 1 "register_operand" "0,f")
13551 (float_extend:XF
13552 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13553 "TARGET_80387"
13554 "* return output_387_binary_op (insn, operands);"
13555 [(set (attr "type")
13556 (cond [(match_operand:XF 3 "mult_operator")
13557 (const_string "fmul")
13558 (match_operand:XF 3 "div_operator")
13559 (const_string "fdiv")
13560 ]
13561 (const_string "fop")))
13562 (set_attr "mode" "<MODE>")])
13563
13564 (define_insn "*fop_xf_6_i387"
13565 [(set (match_operand:XF 0 "register_operand" "=f,f")
13566 (match_operator:XF 3 "binary_fp_operator"
13567 [(float_extend:XF
13568 (match_operand:MODEF 1 "register_operand" "0,f"))
13569 (float_extend:XF
13570 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13571 "TARGET_80387"
13572 "* return output_387_binary_op (insn, operands);"
13573 [(set (attr "type")
13574 (cond [(match_operand:XF 3 "mult_operator")
13575 (const_string "fmul")
13576 (match_operand:XF 3 "div_operator")
13577 (const_string "fdiv")
13578 ]
13579 (const_string "fop")))
13580 (set_attr "mode" "<MODE>")])
13581
13582 (define_split
13583 [(set (match_operand 0 "register_operand")
13584 (match_operator 3 "binary_fp_operator"
13585 [(float (match_operand:SWI24 1 "register_operand"))
13586 (match_operand 2 "register_operand")]))]
13587 "reload_completed
13588 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13589 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13590 [(const_int 0)]
13591 {
13592 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13593 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13594 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13595 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13596 GET_MODE (operands[3]),
13597 operands[4],
13598 operands[2])));
13599 ix86_free_from_memory (GET_MODE (operands[1]));
13600 DONE;
13601 })
13602
13603 (define_split
13604 [(set (match_operand 0 "register_operand")
13605 (match_operator 3 "binary_fp_operator"
13606 [(match_operand 1 "register_operand")
13607 (float (match_operand:SWI24 2 "register_operand"))]))]
13608 "reload_completed
13609 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13610 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13611 [(const_int 0)]
13612 {
13613 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13614 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13615 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13616 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13617 GET_MODE (operands[3]),
13618 operands[1],
13619 operands[4])));
13620 ix86_free_from_memory (GET_MODE (operands[2]));
13621 DONE;
13622 })
13623 \f
13624 ;; FPU special functions.
13625
13626 ;; This pattern implements a no-op XFmode truncation for
13627 ;; all fancy i386 XFmode math functions.
13628
13629 (define_insn "truncxf<mode>2_i387_noop_unspec"
13630 [(set (match_operand:MODEF 0 "register_operand" "=f")
13631 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13632 UNSPEC_TRUNC_NOOP))]
13633 "TARGET_USE_FANCY_MATH_387"
13634 "* return output_387_reg_move (insn, operands);"
13635 [(set_attr "type" "fmov")
13636 (set_attr "mode" "<MODE>")])
13637
13638 (define_insn "sqrtxf2"
13639 [(set (match_operand:XF 0 "register_operand" "=f")
13640 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13641 "TARGET_USE_FANCY_MATH_387"
13642 "fsqrt"
13643 [(set_attr "type" "fpspc")
13644 (set_attr "mode" "XF")
13645 (set_attr "athlon_decode" "direct")
13646 (set_attr "amdfam10_decode" "direct")
13647 (set_attr "bdver1_decode" "direct")])
13648
13649 (define_insn "sqrt_extend<mode>xf2_i387"
13650 [(set (match_operand:XF 0 "register_operand" "=f")
13651 (sqrt:XF
13652 (float_extend:XF
13653 (match_operand:MODEF 1 "register_operand" "0"))))]
13654 "TARGET_USE_FANCY_MATH_387"
13655 "fsqrt"
13656 [(set_attr "type" "fpspc")
13657 (set_attr "mode" "XF")
13658 (set_attr "athlon_decode" "direct")
13659 (set_attr "amdfam10_decode" "direct")
13660 (set_attr "bdver1_decode" "direct")])
13661
13662 (define_insn "*rsqrtsf2_sse"
13663 [(set (match_operand:SF 0 "register_operand" "=x")
13664 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13665 UNSPEC_RSQRT))]
13666 "TARGET_SSE_MATH"
13667 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13668 [(set_attr "type" "sse")
13669 (set_attr "atom_sse_attr" "rcp")
13670 (set_attr "prefix" "maybe_vex")
13671 (set_attr "mode" "SF")])
13672
13673 (define_expand "rsqrtsf2"
13674 [(set (match_operand:SF 0 "register_operand")
13675 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13676 UNSPEC_RSQRT))]
13677 "TARGET_SSE_MATH"
13678 {
13679 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13680 DONE;
13681 })
13682
13683 (define_insn "*sqrt<mode>2_sse"
13684 [(set (match_operand:MODEF 0 "register_operand" "=x")
13685 (sqrt:MODEF
13686 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13687 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13688 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13689 [(set_attr "type" "sse")
13690 (set_attr "atom_sse_attr" "sqrt")
13691 (set_attr "prefix" "maybe_vex")
13692 (set_attr "mode" "<MODE>")
13693 (set_attr "athlon_decode" "*")
13694 (set_attr "amdfam10_decode" "*")
13695 (set_attr "bdver1_decode" "*")])
13696
13697 (define_expand "sqrt<mode>2"
13698 [(set (match_operand:MODEF 0 "register_operand")
13699 (sqrt:MODEF
13700 (match_operand:MODEF 1 "nonimmediate_operand")))]
13701 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13702 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13703 {
13704 if (<MODE>mode == SFmode
13705 && TARGET_SSE_MATH
13706 && TARGET_RECIP_SQRT
13707 && !optimize_function_for_size_p (cfun)
13708 && flag_finite_math_only && !flag_trapping_math
13709 && flag_unsafe_math_optimizations)
13710 {
13711 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13712 DONE;
13713 }
13714
13715 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13716 {
13717 rtx op0 = gen_reg_rtx (XFmode);
13718 rtx op1 = force_reg (<MODE>mode, operands[1]);
13719
13720 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13721 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13722 DONE;
13723 }
13724 })
13725
13726 (define_insn "fpremxf4_i387"
13727 [(set (match_operand:XF 0 "register_operand" "=f")
13728 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13729 (match_operand:XF 3 "register_operand" "1")]
13730 UNSPEC_FPREM_F))
13731 (set (match_operand:XF 1 "register_operand" "=u")
13732 (unspec:XF [(match_dup 2) (match_dup 3)]
13733 UNSPEC_FPREM_U))
13734 (set (reg:CCFP FPSR_REG)
13735 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13736 UNSPEC_C2_FLAG))]
13737 "TARGET_USE_FANCY_MATH_387"
13738 "fprem"
13739 [(set_attr "type" "fpspc")
13740 (set_attr "mode" "XF")])
13741
13742 (define_expand "fmodxf3"
13743 [(use (match_operand:XF 0 "register_operand"))
13744 (use (match_operand:XF 1 "general_operand"))
13745 (use (match_operand:XF 2 "general_operand"))]
13746 "TARGET_USE_FANCY_MATH_387"
13747 {
13748 rtx label = gen_label_rtx ();
13749
13750 rtx op1 = gen_reg_rtx (XFmode);
13751 rtx op2 = gen_reg_rtx (XFmode);
13752
13753 emit_move_insn (op2, operands[2]);
13754 emit_move_insn (op1, operands[1]);
13755
13756 emit_label (label);
13757 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13758 ix86_emit_fp_unordered_jump (label);
13759 LABEL_NUSES (label) = 1;
13760
13761 emit_move_insn (operands[0], op1);
13762 DONE;
13763 })
13764
13765 (define_expand "fmod<mode>3"
13766 [(use (match_operand:MODEF 0 "register_operand"))
13767 (use (match_operand:MODEF 1 "general_operand"))
13768 (use (match_operand:MODEF 2 "general_operand"))]
13769 "TARGET_USE_FANCY_MATH_387"
13770 {
13771 rtx (*gen_truncxf) (rtx, rtx);
13772
13773 rtx label = gen_label_rtx ();
13774
13775 rtx op1 = gen_reg_rtx (XFmode);
13776 rtx op2 = gen_reg_rtx (XFmode);
13777
13778 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13779 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13780
13781 emit_label (label);
13782 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13783 ix86_emit_fp_unordered_jump (label);
13784 LABEL_NUSES (label) = 1;
13785
13786 /* Truncate the result properly for strict SSE math. */
13787 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13788 && !TARGET_MIX_SSE_I387)
13789 gen_truncxf = gen_truncxf<mode>2;
13790 else
13791 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13792
13793 emit_insn (gen_truncxf (operands[0], op1));
13794 DONE;
13795 })
13796
13797 (define_insn "fprem1xf4_i387"
13798 [(set (match_operand:XF 0 "register_operand" "=f")
13799 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13800 (match_operand:XF 3 "register_operand" "1")]
13801 UNSPEC_FPREM1_F))
13802 (set (match_operand:XF 1 "register_operand" "=u")
13803 (unspec:XF [(match_dup 2) (match_dup 3)]
13804 UNSPEC_FPREM1_U))
13805 (set (reg:CCFP FPSR_REG)
13806 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13807 UNSPEC_C2_FLAG))]
13808 "TARGET_USE_FANCY_MATH_387"
13809 "fprem1"
13810 [(set_attr "type" "fpspc")
13811 (set_attr "mode" "XF")])
13812
13813 (define_expand "remainderxf3"
13814 [(use (match_operand:XF 0 "register_operand"))
13815 (use (match_operand:XF 1 "general_operand"))
13816 (use (match_operand:XF 2 "general_operand"))]
13817 "TARGET_USE_FANCY_MATH_387"
13818 {
13819 rtx label = gen_label_rtx ();
13820
13821 rtx op1 = gen_reg_rtx (XFmode);
13822 rtx op2 = gen_reg_rtx (XFmode);
13823
13824 emit_move_insn (op2, operands[2]);
13825 emit_move_insn (op1, operands[1]);
13826
13827 emit_label (label);
13828 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13829 ix86_emit_fp_unordered_jump (label);
13830 LABEL_NUSES (label) = 1;
13831
13832 emit_move_insn (operands[0], op1);
13833 DONE;
13834 })
13835
13836 (define_expand "remainder<mode>3"
13837 [(use (match_operand:MODEF 0 "register_operand"))
13838 (use (match_operand:MODEF 1 "general_operand"))
13839 (use (match_operand:MODEF 2 "general_operand"))]
13840 "TARGET_USE_FANCY_MATH_387"
13841 {
13842 rtx (*gen_truncxf) (rtx, rtx);
13843
13844 rtx label = gen_label_rtx ();
13845
13846 rtx op1 = gen_reg_rtx (XFmode);
13847 rtx op2 = gen_reg_rtx (XFmode);
13848
13849 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13850 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13851
13852 emit_label (label);
13853
13854 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13855 ix86_emit_fp_unordered_jump (label);
13856 LABEL_NUSES (label) = 1;
13857
13858 /* Truncate the result properly for strict SSE math. */
13859 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13860 && !TARGET_MIX_SSE_I387)
13861 gen_truncxf = gen_truncxf<mode>2;
13862 else
13863 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13864
13865 emit_insn (gen_truncxf (operands[0], op1));
13866 DONE;
13867 })
13868
13869 (define_int_iterator SINCOS
13870 [UNSPEC_SIN
13871 UNSPEC_COS])
13872
13873 (define_int_attr sincos
13874 [(UNSPEC_SIN "sin")
13875 (UNSPEC_COS "cos")])
13876
13877 (define_insn "*<sincos>xf2_i387"
13878 [(set (match_operand:XF 0 "register_operand" "=f")
13879 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13880 SINCOS))]
13881 "TARGET_USE_FANCY_MATH_387
13882 && flag_unsafe_math_optimizations"
13883 "f<sincos>"
13884 [(set_attr "type" "fpspc")
13885 (set_attr "mode" "XF")])
13886
13887 (define_insn "*<sincos>_extend<mode>xf2_i387"
13888 [(set (match_operand:XF 0 "register_operand" "=f")
13889 (unspec:XF [(float_extend:XF
13890 (match_operand:MODEF 1 "register_operand" "0"))]
13891 SINCOS))]
13892 "TARGET_USE_FANCY_MATH_387
13893 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13894 || TARGET_MIX_SSE_I387)
13895 && flag_unsafe_math_optimizations"
13896 "f<sincos>"
13897 [(set_attr "type" "fpspc")
13898 (set_attr "mode" "XF")])
13899
13900 ;; When sincos pattern is defined, sin and cos builtin functions will be
13901 ;; expanded to sincos pattern with one of its outputs left unused.
13902 ;; CSE pass will figure out if two sincos patterns can be combined,
13903 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13904 ;; depending on the unused output.
13905
13906 (define_insn "sincosxf3"
13907 [(set (match_operand:XF 0 "register_operand" "=f")
13908 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13909 UNSPEC_SINCOS_COS))
13910 (set (match_operand:XF 1 "register_operand" "=u")
13911 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13912 "TARGET_USE_FANCY_MATH_387
13913 && flag_unsafe_math_optimizations"
13914 "fsincos"
13915 [(set_attr "type" "fpspc")
13916 (set_attr "mode" "XF")])
13917
13918 (define_split
13919 [(set (match_operand:XF 0 "register_operand")
13920 (unspec:XF [(match_operand:XF 2 "register_operand")]
13921 UNSPEC_SINCOS_COS))
13922 (set (match_operand:XF 1 "register_operand")
13923 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13924 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13925 && can_create_pseudo_p ()"
13926 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13927
13928 (define_split
13929 [(set (match_operand:XF 0 "register_operand")
13930 (unspec:XF [(match_operand:XF 2 "register_operand")]
13931 UNSPEC_SINCOS_COS))
13932 (set (match_operand:XF 1 "register_operand")
13933 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13934 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13935 && can_create_pseudo_p ()"
13936 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13937
13938 (define_insn "sincos_extend<mode>xf3_i387"
13939 [(set (match_operand:XF 0 "register_operand" "=f")
13940 (unspec:XF [(float_extend:XF
13941 (match_operand:MODEF 2 "register_operand" "0"))]
13942 UNSPEC_SINCOS_COS))
13943 (set (match_operand:XF 1 "register_operand" "=u")
13944 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13945 "TARGET_USE_FANCY_MATH_387
13946 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13947 || TARGET_MIX_SSE_I387)
13948 && flag_unsafe_math_optimizations"
13949 "fsincos"
13950 [(set_attr "type" "fpspc")
13951 (set_attr "mode" "XF")])
13952
13953 (define_split
13954 [(set (match_operand:XF 0 "register_operand")
13955 (unspec:XF [(float_extend:XF
13956 (match_operand:MODEF 2 "register_operand"))]
13957 UNSPEC_SINCOS_COS))
13958 (set (match_operand:XF 1 "register_operand")
13959 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13960 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13961 && can_create_pseudo_p ()"
13962 [(set (match_dup 1)
13963 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13964
13965 (define_split
13966 [(set (match_operand:XF 0 "register_operand")
13967 (unspec:XF [(float_extend:XF
13968 (match_operand:MODEF 2 "register_operand"))]
13969 UNSPEC_SINCOS_COS))
13970 (set (match_operand:XF 1 "register_operand")
13971 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13972 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13973 && can_create_pseudo_p ()"
13974 [(set (match_dup 0)
13975 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13976
13977 (define_expand "sincos<mode>3"
13978 [(use (match_operand:MODEF 0 "register_operand"))
13979 (use (match_operand:MODEF 1 "register_operand"))
13980 (use (match_operand:MODEF 2 "register_operand"))]
13981 "TARGET_USE_FANCY_MATH_387
13982 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13983 || TARGET_MIX_SSE_I387)
13984 && flag_unsafe_math_optimizations"
13985 {
13986 rtx op0 = gen_reg_rtx (XFmode);
13987 rtx op1 = gen_reg_rtx (XFmode);
13988
13989 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13990 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13991 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13992 DONE;
13993 })
13994
13995 (define_insn "fptanxf4_i387"
13996 [(set (match_operand:XF 0 "register_operand" "=f")
13997 (match_operand:XF 3 "const_double_operand" "F"))
13998 (set (match_operand:XF 1 "register_operand" "=u")
13999 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14000 UNSPEC_TAN))]
14001 "TARGET_USE_FANCY_MATH_387
14002 && flag_unsafe_math_optimizations
14003 && standard_80387_constant_p (operands[3]) == 2"
14004 "fptan"
14005 [(set_attr "type" "fpspc")
14006 (set_attr "mode" "XF")])
14007
14008 (define_insn "fptan_extend<mode>xf4_i387"
14009 [(set (match_operand:MODEF 0 "register_operand" "=f")
14010 (match_operand:MODEF 3 "const_double_operand" "F"))
14011 (set (match_operand:XF 1 "register_operand" "=u")
14012 (unspec:XF [(float_extend:XF
14013 (match_operand:MODEF 2 "register_operand" "0"))]
14014 UNSPEC_TAN))]
14015 "TARGET_USE_FANCY_MATH_387
14016 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14017 || TARGET_MIX_SSE_I387)
14018 && flag_unsafe_math_optimizations
14019 && standard_80387_constant_p (operands[3]) == 2"
14020 "fptan"
14021 [(set_attr "type" "fpspc")
14022 (set_attr "mode" "XF")])
14023
14024 (define_expand "tanxf2"
14025 [(use (match_operand:XF 0 "register_operand"))
14026 (use (match_operand:XF 1 "register_operand"))]
14027 "TARGET_USE_FANCY_MATH_387
14028 && flag_unsafe_math_optimizations"
14029 {
14030 rtx one = gen_reg_rtx (XFmode);
14031 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14032
14033 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14034 DONE;
14035 })
14036
14037 (define_expand "tan<mode>2"
14038 [(use (match_operand:MODEF 0 "register_operand"))
14039 (use (match_operand:MODEF 1 "register_operand"))]
14040 "TARGET_USE_FANCY_MATH_387
14041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14042 || TARGET_MIX_SSE_I387)
14043 && flag_unsafe_math_optimizations"
14044 {
14045 rtx op0 = gen_reg_rtx (XFmode);
14046
14047 rtx one = gen_reg_rtx (<MODE>mode);
14048 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14049
14050 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14051 operands[1], op2));
14052 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14053 DONE;
14054 })
14055
14056 (define_insn "*fpatanxf3_i387"
14057 [(set (match_operand:XF 0 "register_operand" "=f")
14058 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14059 (match_operand:XF 2 "register_operand" "u")]
14060 UNSPEC_FPATAN))
14061 (clobber (match_scratch:XF 3 "=2"))]
14062 "TARGET_USE_FANCY_MATH_387
14063 && flag_unsafe_math_optimizations"
14064 "fpatan"
14065 [(set_attr "type" "fpspc")
14066 (set_attr "mode" "XF")])
14067
14068 (define_insn "fpatan_extend<mode>xf3_i387"
14069 [(set (match_operand:XF 0 "register_operand" "=f")
14070 (unspec:XF [(float_extend:XF
14071 (match_operand:MODEF 1 "register_operand" "0"))
14072 (float_extend:XF
14073 (match_operand:MODEF 2 "register_operand" "u"))]
14074 UNSPEC_FPATAN))
14075 (clobber (match_scratch:XF 3 "=2"))]
14076 "TARGET_USE_FANCY_MATH_387
14077 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14078 || TARGET_MIX_SSE_I387)
14079 && flag_unsafe_math_optimizations"
14080 "fpatan"
14081 [(set_attr "type" "fpspc")
14082 (set_attr "mode" "XF")])
14083
14084 (define_expand "atan2xf3"
14085 [(parallel [(set (match_operand:XF 0 "register_operand")
14086 (unspec:XF [(match_operand:XF 2 "register_operand")
14087 (match_operand:XF 1 "register_operand")]
14088 UNSPEC_FPATAN))
14089 (clobber (match_scratch:XF 3))])]
14090 "TARGET_USE_FANCY_MATH_387
14091 && flag_unsafe_math_optimizations")
14092
14093 (define_expand "atan2<mode>3"
14094 [(use (match_operand:MODEF 0 "register_operand"))
14095 (use (match_operand:MODEF 1 "register_operand"))
14096 (use (match_operand:MODEF 2 "register_operand"))]
14097 "TARGET_USE_FANCY_MATH_387
14098 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14099 || TARGET_MIX_SSE_I387)
14100 && flag_unsafe_math_optimizations"
14101 {
14102 rtx op0 = gen_reg_rtx (XFmode);
14103
14104 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14105 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14106 DONE;
14107 })
14108
14109 (define_expand "atanxf2"
14110 [(parallel [(set (match_operand:XF 0 "register_operand")
14111 (unspec:XF [(match_dup 2)
14112 (match_operand:XF 1 "register_operand")]
14113 UNSPEC_FPATAN))
14114 (clobber (match_scratch:XF 3))])]
14115 "TARGET_USE_FANCY_MATH_387
14116 && flag_unsafe_math_optimizations"
14117 {
14118 operands[2] = gen_reg_rtx (XFmode);
14119 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14120 })
14121
14122 (define_expand "atan<mode>2"
14123 [(use (match_operand:MODEF 0 "register_operand"))
14124 (use (match_operand:MODEF 1 "register_operand"))]
14125 "TARGET_USE_FANCY_MATH_387
14126 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14127 || TARGET_MIX_SSE_I387)
14128 && flag_unsafe_math_optimizations"
14129 {
14130 rtx op0 = gen_reg_rtx (XFmode);
14131
14132 rtx op2 = gen_reg_rtx (<MODE>mode);
14133 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14134
14135 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14136 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14137 DONE;
14138 })
14139
14140 (define_expand "asinxf2"
14141 [(set (match_dup 2)
14142 (mult:XF (match_operand:XF 1 "register_operand")
14143 (match_dup 1)))
14144 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14145 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14146 (parallel [(set (match_operand:XF 0 "register_operand")
14147 (unspec:XF [(match_dup 5) (match_dup 1)]
14148 UNSPEC_FPATAN))
14149 (clobber (match_scratch:XF 6))])]
14150 "TARGET_USE_FANCY_MATH_387
14151 && flag_unsafe_math_optimizations"
14152 {
14153 int i;
14154
14155 if (optimize_insn_for_size_p ())
14156 FAIL;
14157
14158 for (i = 2; i < 6; i++)
14159 operands[i] = gen_reg_rtx (XFmode);
14160
14161 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14162 })
14163
14164 (define_expand "asin<mode>2"
14165 [(use (match_operand:MODEF 0 "register_operand"))
14166 (use (match_operand:MODEF 1 "general_operand"))]
14167 "TARGET_USE_FANCY_MATH_387
14168 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14169 || TARGET_MIX_SSE_I387)
14170 && flag_unsafe_math_optimizations"
14171 {
14172 rtx op0 = gen_reg_rtx (XFmode);
14173 rtx op1 = gen_reg_rtx (XFmode);
14174
14175 if (optimize_insn_for_size_p ())
14176 FAIL;
14177
14178 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14179 emit_insn (gen_asinxf2 (op0, op1));
14180 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14181 DONE;
14182 })
14183
14184 (define_expand "acosxf2"
14185 [(set (match_dup 2)
14186 (mult:XF (match_operand:XF 1 "register_operand")
14187 (match_dup 1)))
14188 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14189 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14190 (parallel [(set (match_operand:XF 0 "register_operand")
14191 (unspec:XF [(match_dup 1) (match_dup 5)]
14192 UNSPEC_FPATAN))
14193 (clobber (match_scratch:XF 6))])]
14194 "TARGET_USE_FANCY_MATH_387
14195 && flag_unsafe_math_optimizations"
14196 {
14197 int i;
14198
14199 if (optimize_insn_for_size_p ())
14200 FAIL;
14201
14202 for (i = 2; i < 6; i++)
14203 operands[i] = gen_reg_rtx (XFmode);
14204
14205 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14206 })
14207
14208 (define_expand "acos<mode>2"
14209 [(use (match_operand:MODEF 0 "register_operand"))
14210 (use (match_operand:MODEF 1 "general_operand"))]
14211 "TARGET_USE_FANCY_MATH_387
14212 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14213 || TARGET_MIX_SSE_I387)
14214 && flag_unsafe_math_optimizations"
14215 {
14216 rtx op0 = gen_reg_rtx (XFmode);
14217 rtx op1 = gen_reg_rtx (XFmode);
14218
14219 if (optimize_insn_for_size_p ())
14220 FAIL;
14221
14222 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14223 emit_insn (gen_acosxf2 (op0, op1));
14224 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14225 DONE;
14226 })
14227
14228 (define_insn "fyl2xxf3_i387"
14229 [(set (match_operand:XF 0 "register_operand" "=f")
14230 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14231 (match_operand:XF 2 "register_operand" "u")]
14232 UNSPEC_FYL2X))
14233 (clobber (match_scratch:XF 3 "=2"))]
14234 "TARGET_USE_FANCY_MATH_387
14235 && flag_unsafe_math_optimizations"
14236 "fyl2x"
14237 [(set_attr "type" "fpspc")
14238 (set_attr "mode" "XF")])
14239
14240 (define_insn "fyl2x_extend<mode>xf3_i387"
14241 [(set (match_operand:XF 0 "register_operand" "=f")
14242 (unspec:XF [(float_extend:XF
14243 (match_operand:MODEF 1 "register_operand" "0"))
14244 (match_operand:XF 2 "register_operand" "u")]
14245 UNSPEC_FYL2X))
14246 (clobber (match_scratch:XF 3 "=2"))]
14247 "TARGET_USE_FANCY_MATH_387
14248 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14249 || TARGET_MIX_SSE_I387)
14250 && flag_unsafe_math_optimizations"
14251 "fyl2x"
14252 [(set_attr "type" "fpspc")
14253 (set_attr "mode" "XF")])
14254
14255 (define_expand "logxf2"
14256 [(parallel [(set (match_operand:XF 0 "register_operand")
14257 (unspec:XF [(match_operand:XF 1 "register_operand")
14258 (match_dup 2)] UNSPEC_FYL2X))
14259 (clobber (match_scratch:XF 3))])]
14260 "TARGET_USE_FANCY_MATH_387
14261 && flag_unsafe_math_optimizations"
14262 {
14263 operands[2] = gen_reg_rtx (XFmode);
14264 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14265 })
14266
14267 (define_expand "log<mode>2"
14268 [(use (match_operand:MODEF 0 "register_operand"))
14269 (use (match_operand:MODEF 1 "register_operand"))]
14270 "TARGET_USE_FANCY_MATH_387
14271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14272 || TARGET_MIX_SSE_I387)
14273 && flag_unsafe_math_optimizations"
14274 {
14275 rtx op0 = gen_reg_rtx (XFmode);
14276
14277 rtx op2 = gen_reg_rtx (XFmode);
14278 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14279
14280 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14281 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14282 DONE;
14283 })
14284
14285 (define_expand "log10xf2"
14286 [(parallel [(set (match_operand:XF 0 "register_operand")
14287 (unspec:XF [(match_operand:XF 1 "register_operand")
14288 (match_dup 2)] UNSPEC_FYL2X))
14289 (clobber (match_scratch:XF 3))])]
14290 "TARGET_USE_FANCY_MATH_387
14291 && flag_unsafe_math_optimizations"
14292 {
14293 operands[2] = gen_reg_rtx (XFmode);
14294 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14295 })
14296
14297 (define_expand "log10<mode>2"
14298 [(use (match_operand:MODEF 0 "register_operand"))
14299 (use (match_operand:MODEF 1 "register_operand"))]
14300 "TARGET_USE_FANCY_MATH_387
14301 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14302 || TARGET_MIX_SSE_I387)
14303 && flag_unsafe_math_optimizations"
14304 {
14305 rtx op0 = gen_reg_rtx (XFmode);
14306
14307 rtx op2 = gen_reg_rtx (XFmode);
14308 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14309
14310 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14311 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14312 DONE;
14313 })
14314
14315 (define_expand "log2xf2"
14316 [(parallel [(set (match_operand:XF 0 "register_operand")
14317 (unspec:XF [(match_operand:XF 1 "register_operand")
14318 (match_dup 2)] UNSPEC_FYL2X))
14319 (clobber (match_scratch:XF 3))])]
14320 "TARGET_USE_FANCY_MATH_387
14321 && flag_unsafe_math_optimizations"
14322 {
14323 operands[2] = gen_reg_rtx (XFmode);
14324 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14325 })
14326
14327 (define_expand "log2<mode>2"
14328 [(use (match_operand:MODEF 0 "register_operand"))
14329 (use (match_operand:MODEF 1 "register_operand"))]
14330 "TARGET_USE_FANCY_MATH_387
14331 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14332 || TARGET_MIX_SSE_I387)
14333 && flag_unsafe_math_optimizations"
14334 {
14335 rtx op0 = gen_reg_rtx (XFmode);
14336
14337 rtx op2 = gen_reg_rtx (XFmode);
14338 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14339
14340 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14341 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14342 DONE;
14343 })
14344
14345 (define_insn "fyl2xp1xf3_i387"
14346 [(set (match_operand:XF 0 "register_operand" "=f")
14347 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14348 (match_operand:XF 2 "register_operand" "u")]
14349 UNSPEC_FYL2XP1))
14350 (clobber (match_scratch:XF 3 "=2"))]
14351 "TARGET_USE_FANCY_MATH_387
14352 && flag_unsafe_math_optimizations"
14353 "fyl2xp1"
14354 [(set_attr "type" "fpspc")
14355 (set_attr "mode" "XF")])
14356
14357 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14358 [(set (match_operand:XF 0 "register_operand" "=f")
14359 (unspec:XF [(float_extend:XF
14360 (match_operand:MODEF 1 "register_operand" "0"))
14361 (match_operand:XF 2 "register_operand" "u")]
14362 UNSPEC_FYL2XP1))
14363 (clobber (match_scratch:XF 3 "=2"))]
14364 "TARGET_USE_FANCY_MATH_387
14365 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14366 || TARGET_MIX_SSE_I387)
14367 && flag_unsafe_math_optimizations"
14368 "fyl2xp1"
14369 [(set_attr "type" "fpspc")
14370 (set_attr "mode" "XF")])
14371
14372 (define_expand "log1pxf2"
14373 [(use (match_operand:XF 0 "register_operand"))
14374 (use (match_operand:XF 1 "register_operand"))]
14375 "TARGET_USE_FANCY_MATH_387
14376 && flag_unsafe_math_optimizations"
14377 {
14378 if (optimize_insn_for_size_p ())
14379 FAIL;
14380
14381 ix86_emit_i387_log1p (operands[0], operands[1]);
14382 DONE;
14383 })
14384
14385 (define_expand "log1p<mode>2"
14386 [(use (match_operand:MODEF 0 "register_operand"))
14387 (use (match_operand:MODEF 1 "register_operand"))]
14388 "TARGET_USE_FANCY_MATH_387
14389 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14390 || TARGET_MIX_SSE_I387)
14391 && flag_unsafe_math_optimizations"
14392 {
14393 rtx op0;
14394
14395 if (optimize_insn_for_size_p ())
14396 FAIL;
14397
14398 op0 = gen_reg_rtx (XFmode);
14399
14400 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14401
14402 ix86_emit_i387_log1p (op0, operands[1]);
14403 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14404 DONE;
14405 })
14406
14407 (define_insn "fxtractxf3_i387"
14408 [(set (match_operand:XF 0 "register_operand" "=f")
14409 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14410 UNSPEC_XTRACT_FRACT))
14411 (set (match_operand:XF 1 "register_operand" "=u")
14412 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14413 "TARGET_USE_FANCY_MATH_387
14414 && flag_unsafe_math_optimizations"
14415 "fxtract"
14416 [(set_attr "type" "fpspc")
14417 (set_attr "mode" "XF")])
14418
14419 (define_insn "fxtract_extend<mode>xf3_i387"
14420 [(set (match_operand:XF 0 "register_operand" "=f")
14421 (unspec:XF [(float_extend:XF
14422 (match_operand:MODEF 2 "register_operand" "0"))]
14423 UNSPEC_XTRACT_FRACT))
14424 (set (match_operand:XF 1 "register_operand" "=u")
14425 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14426 "TARGET_USE_FANCY_MATH_387
14427 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14428 || TARGET_MIX_SSE_I387)
14429 && flag_unsafe_math_optimizations"
14430 "fxtract"
14431 [(set_attr "type" "fpspc")
14432 (set_attr "mode" "XF")])
14433
14434 (define_expand "logbxf2"
14435 [(parallel [(set (match_dup 2)
14436 (unspec:XF [(match_operand:XF 1 "register_operand")]
14437 UNSPEC_XTRACT_FRACT))
14438 (set (match_operand:XF 0 "register_operand")
14439 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14440 "TARGET_USE_FANCY_MATH_387
14441 && flag_unsafe_math_optimizations"
14442 "operands[2] = gen_reg_rtx (XFmode);")
14443
14444 (define_expand "logb<mode>2"
14445 [(use (match_operand:MODEF 0 "register_operand"))
14446 (use (match_operand:MODEF 1 "register_operand"))]
14447 "TARGET_USE_FANCY_MATH_387
14448 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14449 || TARGET_MIX_SSE_I387)
14450 && flag_unsafe_math_optimizations"
14451 {
14452 rtx op0 = gen_reg_rtx (XFmode);
14453 rtx op1 = gen_reg_rtx (XFmode);
14454
14455 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14456 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14457 DONE;
14458 })
14459
14460 (define_expand "ilogbxf2"
14461 [(use (match_operand:SI 0 "register_operand"))
14462 (use (match_operand:XF 1 "register_operand"))]
14463 "TARGET_USE_FANCY_MATH_387
14464 && flag_unsafe_math_optimizations"
14465 {
14466 rtx op0, op1;
14467
14468 if (optimize_insn_for_size_p ())
14469 FAIL;
14470
14471 op0 = gen_reg_rtx (XFmode);
14472 op1 = gen_reg_rtx (XFmode);
14473
14474 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14475 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14476 DONE;
14477 })
14478
14479 (define_expand "ilogb<mode>2"
14480 [(use (match_operand:SI 0 "register_operand"))
14481 (use (match_operand:MODEF 1 "register_operand"))]
14482 "TARGET_USE_FANCY_MATH_387
14483 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14484 || TARGET_MIX_SSE_I387)
14485 && flag_unsafe_math_optimizations"
14486 {
14487 rtx op0, op1;
14488
14489 if (optimize_insn_for_size_p ())
14490 FAIL;
14491
14492 op0 = gen_reg_rtx (XFmode);
14493 op1 = gen_reg_rtx (XFmode);
14494
14495 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14496 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14497 DONE;
14498 })
14499
14500 (define_insn "*f2xm1xf2_i387"
14501 [(set (match_operand:XF 0 "register_operand" "=f")
14502 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14503 UNSPEC_F2XM1))]
14504 "TARGET_USE_FANCY_MATH_387
14505 && flag_unsafe_math_optimizations"
14506 "f2xm1"
14507 [(set_attr "type" "fpspc")
14508 (set_attr "mode" "XF")])
14509
14510 (define_insn "*fscalexf4_i387"
14511 [(set (match_operand:XF 0 "register_operand" "=f")
14512 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14513 (match_operand:XF 3 "register_operand" "1")]
14514 UNSPEC_FSCALE_FRACT))
14515 (set (match_operand:XF 1 "register_operand" "=u")
14516 (unspec:XF [(match_dup 2) (match_dup 3)]
14517 UNSPEC_FSCALE_EXP))]
14518 "TARGET_USE_FANCY_MATH_387
14519 && flag_unsafe_math_optimizations"
14520 "fscale"
14521 [(set_attr "type" "fpspc")
14522 (set_attr "mode" "XF")])
14523
14524 (define_expand "expNcorexf3"
14525 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14526 (match_operand:XF 2 "register_operand")))
14527 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14528 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14529 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14530 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14531 (parallel [(set (match_operand:XF 0 "register_operand")
14532 (unspec:XF [(match_dup 8) (match_dup 4)]
14533 UNSPEC_FSCALE_FRACT))
14534 (set (match_dup 9)
14535 (unspec:XF [(match_dup 8) (match_dup 4)]
14536 UNSPEC_FSCALE_EXP))])]
14537 "TARGET_USE_FANCY_MATH_387
14538 && flag_unsafe_math_optimizations"
14539 {
14540 int i;
14541
14542 if (optimize_insn_for_size_p ())
14543 FAIL;
14544
14545 for (i = 3; i < 10; i++)
14546 operands[i] = gen_reg_rtx (XFmode);
14547
14548 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14549 })
14550
14551 (define_expand "expxf2"
14552 [(use (match_operand:XF 0 "register_operand"))
14553 (use (match_operand:XF 1 "register_operand"))]
14554 "TARGET_USE_FANCY_MATH_387
14555 && flag_unsafe_math_optimizations"
14556 {
14557 rtx op2;
14558
14559 if (optimize_insn_for_size_p ())
14560 FAIL;
14561
14562 op2 = gen_reg_rtx (XFmode);
14563 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14564
14565 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14566 DONE;
14567 })
14568
14569 (define_expand "exp<mode>2"
14570 [(use (match_operand:MODEF 0 "register_operand"))
14571 (use (match_operand:MODEF 1 "general_operand"))]
14572 "TARGET_USE_FANCY_MATH_387
14573 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14574 || TARGET_MIX_SSE_I387)
14575 && flag_unsafe_math_optimizations"
14576 {
14577 rtx op0, op1;
14578
14579 if (optimize_insn_for_size_p ())
14580 FAIL;
14581
14582 op0 = gen_reg_rtx (XFmode);
14583 op1 = gen_reg_rtx (XFmode);
14584
14585 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14586 emit_insn (gen_expxf2 (op0, op1));
14587 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14588 DONE;
14589 })
14590
14591 (define_expand "exp10xf2"
14592 [(use (match_operand:XF 0 "register_operand"))
14593 (use (match_operand:XF 1 "register_operand"))]
14594 "TARGET_USE_FANCY_MATH_387
14595 && flag_unsafe_math_optimizations"
14596 {
14597 rtx op2;
14598
14599 if (optimize_insn_for_size_p ())
14600 FAIL;
14601
14602 op2 = gen_reg_rtx (XFmode);
14603 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14604
14605 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14606 DONE;
14607 })
14608
14609 (define_expand "exp10<mode>2"
14610 [(use (match_operand:MODEF 0 "register_operand"))
14611 (use (match_operand:MODEF 1 "general_operand"))]
14612 "TARGET_USE_FANCY_MATH_387
14613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14614 || TARGET_MIX_SSE_I387)
14615 && flag_unsafe_math_optimizations"
14616 {
14617 rtx op0, op1;
14618
14619 if (optimize_insn_for_size_p ())
14620 FAIL;
14621
14622 op0 = gen_reg_rtx (XFmode);
14623 op1 = gen_reg_rtx (XFmode);
14624
14625 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14626 emit_insn (gen_exp10xf2 (op0, op1));
14627 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14628 DONE;
14629 })
14630
14631 (define_expand "exp2xf2"
14632 [(use (match_operand:XF 0 "register_operand"))
14633 (use (match_operand:XF 1 "register_operand"))]
14634 "TARGET_USE_FANCY_MATH_387
14635 && flag_unsafe_math_optimizations"
14636 {
14637 rtx op2;
14638
14639 if (optimize_insn_for_size_p ())
14640 FAIL;
14641
14642 op2 = gen_reg_rtx (XFmode);
14643 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14644
14645 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14646 DONE;
14647 })
14648
14649 (define_expand "exp2<mode>2"
14650 [(use (match_operand:MODEF 0 "register_operand"))
14651 (use (match_operand:MODEF 1 "general_operand"))]
14652 "TARGET_USE_FANCY_MATH_387
14653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14654 || TARGET_MIX_SSE_I387)
14655 && flag_unsafe_math_optimizations"
14656 {
14657 rtx op0, op1;
14658
14659 if (optimize_insn_for_size_p ())
14660 FAIL;
14661
14662 op0 = gen_reg_rtx (XFmode);
14663 op1 = gen_reg_rtx (XFmode);
14664
14665 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14666 emit_insn (gen_exp2xf2 (op0, op1));
14667 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14668 DONE;
14669 })
14670
14671 (define_expand "expm1xf2"
14672 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14673 (match_dup 2)))
14674 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14675 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14676 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14677 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14678 (parallel [(set (match_dup 7)
14679 (unspec:XF [(match_dup 6) (match_dup 4)]
14680 UNSPEC_FSCALE_FRACT))
14681 (set (match_dup 8)
14682 (unspec:XF [(match_dup 6) (match_dup 4)]
14683 UNSPEC_FSCALE_EXP))])
14684 (parallel [(set (match_dup 10)
14685 (unspec:XF [(match_dup 9) (match_dup 8)]
14686 UNSPEC_FSCALE_FRACT))
14687 (set (match_dup 11)
14688 (unspec:XF [(match_dup 9) (match_dup 8)]
14689 UNSPEC_FSCALE_EXP))])
14690 (set (match_dup 12) (minus:XF (match_dup 10)
14691 (float_extend:XF (match_dup 13))))
14692 (set (match_operand:XF 0 "register_operand")
14693 (plus:XF (match_dup 12) (match_dup 7)))]
14694 "TARGET_USE_FANCY_MATH_387
14695 && flag_unsafe_math_optimizations"
14696 {
14697 int i;
14698
14699 if (optimize_insn_for_size_p ())
14700 FAIL;
14701
14702 for (i = 2; i < 13; i++)
14703 operands[i] = gen_reg_rtx (XFmode);
14704
14705 operands[13]
14706 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14707
14708 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14709 })
14710
14711 (define_expand "expm1<mode>2"
14712 [(use (match_operand:MODEF 0 "register_operand"))
14713 (use (match_operand:MODEF 1 "general_operand"))]
14714 "TARGET_USE_FANCY_MATH_387
14715 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14716 || TARGET_MIX_SSE_I387)
14717 && flag_unsafe_math_optimizations"
14718 {
14719 rtx op0, op1;
14720
14721 if (optimize_insn_for_size_p ())
14722 FAIL;
14723
14724 op0 = gen_reg_rtx (XFmode);
14725 op1 = gen_reg_rtx (XFmode);
14726
14727 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14728 emit_insn (gen_expm1xf2 (op0, op1));
14729 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14730 DONE;
14731 })
14732
14733 (define_expand "ldexpxf3"
14734 [(set (match_dup 3)
14735 (float:XF (match_operand:SI 2 "register_operand")))
14736 (parallel [(set (match_operand:XF 0 " register_operand")
14737 (unspec:XF [(match_operand:XF 1 "register_operand")
14738 (match_dup 3)]
14739 UNSPEC_FSCALE_FRACT))
14740 (set (match_dup 4)
14741 (unspec:XF [(match_dup 1) (match_dup 3)]
14742 UNSPEC_FSCALE_EXP))])]
14743 "TARGET_USE_FANCY_MATH_387
14744 && flag_unsafe_math_optimizations"
14745 {
14746 if (optimize_insn_for_size_p ())
14747 FAIL;
14748
14749 operands[3] = gen_reg_rtx (XFmode);
14750 operands[4] = gen_reg_rtx (XFmode);
14751 })
14752
14753 (define_expand "ldexp<mode>3"
14754 [(use (match_operand:MODEF 0 "register_operand"))
14755 (use (match_operand:MODEF 1 "general_operand"))
14756 (use (match_operand:SI 2 "register_operand"))]
14757 "TARGET_USE_FANCY_MATH_387
14758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14759 || TARGET_MIX_SSE_I387)
14760 && flag_unsafe_math_optimizations"
14761 {
14762 rtx op0, op1;
14763
14764 if (optimize_insn_for_size_p ())
14765 FAIL;
14766
14767 op0 = gen_reg_rtx (XFmode);
14768 op1 = gen_reg_rtx (XFmode);
14769
14770 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14771 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14772 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14773 DONE;
14774 })
14775
14776 (define_expand "scalbxf3"
14777 [(parallel [(set (match_operand:XF 0 " register_operand")
14778 (unspec:XF [(match_operand:XF 1 "register_operand")
14779 (match_operand:XF 2 "register_operand")]
14780 UNSPEC_FSCALE_FRACT))
14781 (set (match_dup 3)
14782 (unspec:XF [(match_dup 1) (match_dup 2)]
14783 UNSPEC_FSCALE_EXP))])]
14784 "TARGET_USE_FANCY_MATH_387
14785 && flag_unsafe_math_optimizations"
14786 {
14787 if (optimize_insn_for_size_p ())
14788 FAIL;
14789
14790 operands[3] = gen_reg_rtx (XFmode);
14791 })
14792
14793 (define_expand "scalb<mode>3"
14794 [(use (match_operand:MODEF 0 "register_operand"))
14795 (use (match_operand:MODEF 1 "general_operand"))
14796 (use (match_operand:MODEF 2 "general_operand"))]
14797 "TARGET_USE_FANCY_MATH_387
14798 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14799 || TARGET_MIX_SSE_I387)
14800 && flag_unsafe_math_optimizations"
14801 {
14802 rtx op0, op1, op2;
14803
14804 if (optimize_insn_for_size_p ())
14805 FAIL;
14806
14807 op0 = gen_reg_rtx (XFmode);
14808 op1 = gen_reg_rtx (XFmode);
14809 op2 = gen_reg_rtx (XFmode);
14810
14811 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14812 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14813 emit_insn (gen_scalbxf3 (op0, op1, op2));
14814 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14815 DONE;
14816 })
14817
14818 (define_expand "significandxf2"
14819 [(parallel [(set (match_operand:XF 0 "register_operand")
14820 (unspec:XF [(match_operand:XF 1 "register_operand")]
14821 UNSPEC_XTRACT_FRACT))
14822 (set (match_dup 2)
14823 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14824 "TARGET_USE_FANCY_MATH_387
14825 && flag_unsafe_math_optimizations"
14826 "operands[2] = gen_reg_rtx (XFmode);")
14827
14828 (define_expand "significand<mode>2"
14829 [(use (match_operand:MODEF 0 "register_operand"))
14830 (use (match_operand:MODEF 1 "register_operand"))]
14831 "TARGET_USE_FANCY_MATH_387
14832 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14833 || TARGET_MIX_SSE_I387)
14834 && flag_unsafe_math_optimizations"
14835 {
14836 rtx op0 = gen_reg_rtx (XFmode);
14837 rtx op1 = gen_reg_rtx (XFmode);
14838
14839 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14840 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14841 DONE;
14842 })
14843 \f
14844
14845 (define_insn "sse4_1_round<mode>2"
14846 [(set (match_operand:MODEF 0 "register_operand" "=x")
14847 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14848 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14849 UNSPEC_ROUND))]
14850 "TARGET_ROUND"
14851 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14852 [(set_attr "type" "ssecvt")
14853 (set_attr "prefix_extra" "1")
14854 (set_attr "prefix" "maybe_vex")
14855 (set_attr "mode" "<MODE>")])
14856
14857 (define_insn "rintxf2"
14858 [(set (match_operand:XF 0 "register_operand" "=f")
14859 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14860 UNSPEC_FRNDINT))]
14861 "TARGET_USE_FANCY_MATH_387
14862 && flag_unsafe_math_optimizations"
14863 "frndint"
14864 [(set_attr "type" "fpspc")
14865 (set_attr "mode" "XF")])
14866
14867 (define_expand "rint<mode>2"
14868 [(use (match_operand:MODEF 0 "register_operand"))
14869 (use (match_operand:MODEF 1 "register_operand"))]
14870 "(TARGET_USE_FANCY_MATH_387
14871 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14872 || TARGET_MIX_SSE_I387)
14873 && flag_unsafe_math_optimizations)
14874 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14875 && !flag_trapping_math)"
14876 {
14877 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14878 && !flag_trapping_math)
14879 {
14880 if (TARGET_ROUND)
14881 emit_insn (gen_sse4_1_round<mode>2
14882 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14883 else if (optimize_insn_for_size_p ())
14884 FAIL;
14885 else
14886 ix86_expand_rint (operands[0], operands[1]);
14887 }
14888 else
14889 {
14890 rtx op0 = gen_reg_rtx (XFmode);
14891 rtx op1 = gen_reg_rtx (XFmode);
14892
14893 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14894 emit_insn (gen_rintxf2 (op0, op1));
14895
14896 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14897 }
14898 DONE;
14899 })
14900
14901 (define_expand "round<mode>2"
14902 [(match_operand:X87MODEF 0 "register_operand")
14903 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14904 "(TARGET_USE_FANCY_MATH_387
14905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14906 || TARGET_MIX_SSE_I387)
14907 && flag_unsafe_math_optimizations)
14908 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14909 && !flag_trapping_math && !flag_rounding_math)"
14910 {
14911 if (optimize_insn_for_size_p ())
14912 FAIL;
14913
14914 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14915 && !flag_trapping_math && !flag_rounding_math)
14916 {
14917 if (TARGET_ROUND)
14918 {
14919 operands[1] = force_reg (<MODE>mode, operands[1]);
14920 ix86_expand_round_sse4 (operands[0], operands[1]);
14921 }
14922 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14923 ix86_expand_round (operands[0], operands[1]);
14924 else
14925 ix86_expand_rounddf_32 (operands[0], operands[1]);
14926 }
14927 else
14928 {
14929 operands[1] = force_reg (<MODE>mode, operands[1]);
14930 ix86_emit_i387_round (operands[0], operands[1]);
14931 }
14932 DONE;
14933 })
14934
14935 (define_insn_and_split "*fistdi2_1"
14936 [(set (match_operand:DI 0 "nonimmediate_operand")
14937 (unspec:DI [(match_operand:XF 1 "register_operand")]
14938 UNSPEC_FIST))]
14939 "TARGET_USE_FANCY_MATH_387
14940 && can_create_pseudo_p ()"
14941 "#"
14942 "&& 1"
14943 [(const_int 0)]
14944 {
14945 if (memory_operand (operands[0], VOIDmode))
14946 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14947 else
14948 {
14949 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14950 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14951 operands[2]));
14952 }
14953 DONE;
14954 }
14955 [(set_attr "type" "fpspc")
14956 (set_attr "mode" "DI")])
14957
14958 (define_insn "fistdi2"
14959 [(set (match_operand:DI 0 "memory_operand" "=m")
14960 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14961 UNSPEC_FIST))
14962 (clobber (match_scratch:XF 2 "=&1f"))]
14963 "TARGET_USE_FANCY_MATH_387"
14964 "* return output_fix_trunc (insn, operands, false);"
14965 [(set_attr "type" "fpspc")
14966 (set_attr "mode" "DI")])
14967
14968 (define_insn "fistdi2_with_temp"
14969 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14970 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14971 UNSPEC_FIST))
14972 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14973 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14974 "TARGET_USE_FANCY_MATH_387"
14975 "#"
14976 [(set_attr "type" "fpspc")
14977 (set_attr "mode" "DI")])
14978
14979 (define_split
14980 [(set (match_operand:DI 0 "register_operand")
14981 (unspec:DI [(match_operand:XF 1 "register_operand")]
14982 UNSPEC_FIST))
14983 (clobber (match_operand:DI 2 "memory_operand"))
14984 (clobber (match_scratch 3))]
14985 "reload_completed"
14986 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14987 (clobber (match_dup 3))])
14988 (set (match_dup 0) (match_dup 2))])
14989
14990 (define_split
14991 [(set (match_operand:DI 0 "memory_operand")
14992 (unspec:DI [(match_operand:XF 1 "register_operand")]
14993 UNSPEC_FIST))
14994 (clobber (match_operand:DI 2 "memory_operand"))
14995 (clobber (match_scratch 3))]
14996 "reload_completed"
14997 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14998 (clobber (match_dup 3))])])
14999
15000 (define_insn_and_split "*fist<mode>2_1"
15001 [(set (match_operand:SWI24 0 "register_operand")
15002 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15003 UNSPEC_FIST))]
15004 "TARGET_USE_FANCY_MATH_387
15005 && can_create_pseudo_p ()"
15006 "#"
15007 "&& 1"
15008 [(const_int 0)]
15009 {
15010 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15011 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15012 operands[2]));
15013 DONE;
15014 }
15015 [(set_attr "type" "fpspc")
15016 (set_attr "mode" "<MODE>")])
15017
15018 (define_insn "fist<mode>2"
15019 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15020 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15021 UNSPEC_FIST))]
15022 "TARGET_USE_FANCY_MATH_387"
15023 "* return output_fix_trunc (insn, operands, false);"
15024 [(set_attr "type" "fpspc")
15025 (set_attr "mode" "<MODE>")])
15026
15027 (define_insn "fist<mode>2_with_temp"
15028 [(set (match_operand:SWI24 0 "register_operand" "=r")
15029 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15030 UNSPEC_FIST))
15031 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15032 "TARGET_USE_FANCY_MATH_387"
15033 "#"
15034 [(set_attr "type" "fpspc")
15035 (set_attr "mode" "<MODE>")])
15036
15037 (define_split
15038 [(set (match_operand:SWI24 0 "register_operand")
15039 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15040 UNSPEC_FIST))
15041 (clobber (match_operand:SWI24 2 "memory_operand"))]
15042 "reload_completed"
15043 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15044 (set (match_dup 0) (match_dup 2))])
15045
15046 (define_split
15047 [(set (match_operand:SWI24 0 "memory_operand")
15048 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15049 UNSPEC_FIST))
15050 (clobber (match_operand:SWI24 2 "memory_operand"))]
15051 "reload_completed"
15052 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15053
15054 (define_expand "lrintxf<mode>2"
15055 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15056 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15057 UNSPEC_FIST))]
15058 "TARGET_USE_FANCY_MATH_387")
15059
15060 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15061 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15062 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15063 UNSPEC_FIX_NOTRUNC))]
15064 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15065 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15066
15067 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15068 [(match_operand:SWI248x 0 "nonimmediate_operand")
15069 (match_operand:X87MODEF 1 "register_operand")]
15070 "(TARGET_USE_FANCY_MATH_387
15071 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15072 || TARGET_MIX_SSE_I387)
15073 && flag_unsafe_math_optimizations)
15074 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15075 && <SWI248x:MODE>mode != HImode
15076 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15077 && !flag_trapping_math && !flag_rounding_math)"
15078 {
15079 if (optimize_insn_for_size_p ())
15080 FAIL;
15081
15082 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15083 && <SWI248x:MODE>mode != HImode
15084 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15085 && !flag_trapping_math && !flag_rounding_math)
15086 ix86_expand_lround (operands[0], operands[1]);
15087 else
15088 ix86_emit_i387_round (operands[0], operands[1]);
15089 DONE;
15090 })
15091
15092 (define_int_iterator FRNDINT_ROUNDING
15093 [UNSPEC_FRNDINT_FLOOR
15094 UNSPEC_FRNDINT_CEIL
15095 UNSPEC_FRNDINT_TRUNC])
15096
15097 (define_int_iterator FIST_ROUNDING
15098 [UNSPEC_FIST_FLOOR
15099 UNSPEC_FIST_CEIL])
15100
15101 ;; Base name for define_insn
15102 (define_int_attr rounding_insn
15103 [(UNSPEC_FRNDINT_FLOOR "floor")
15104 (UNSPEC_FRNDINT_CEIL "ceil")
15105 (UNSPEC_FRNDINT_TRUNC "btrunc")
15106 (UNSPEC_FIST_FLOOR "floor")
15107 (UNSPEC_FIST_CEIL "ceil")])
15108
15109 (define_int_attr rounding
15110 [(UNSPEC_FRNDINT_FLOOR "floor")
15111 (UNSPEC_FRNDINT_CEIL "ceil")
15112 (UNSPEC_FRNDINT_TRUNC "trunc")
15113 (UNSPEC_FIST_FLOOR "floor")
15114 (UNSPEC_FIST_CEIL "ceil")])
15115
15116 (define_int_attr ROUNDING
15117 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15118 (UNSPEC_FRNDINT_CEIL "CEIL")
15119 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15120 (UNSPEC_FIST_FLOOR "FLOOR")
15121 (UNSPEC_FIST_CEIL "CEIL")])
15122
15123 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15124 (define_insn_and_split "frndintxf2_<rounding>"
15125 [(set (match_operand:XF 0 "register_operand")
15126 (unspec:XF [(match_operand:XF 1 "register_operand")]
15127 FRNDINT_ROUNDING))
15128 (clobber (reg:CC FLAGS_REG))]
15129 "TARGET_USE_FANCY_MATH_387
15130 && flag_unsafe_math_optimizations
15131 && can_create_pseudo_p ()"
15132 "#"
15133 "&& 1"
15134 [(const_int 0)]
15135 {
15136 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15137
15138 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15139 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15140
15141 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15142 operands[2], operands[3]));
15143 DONE;
15144 }
15145 [(set_attr "type" "frndint")
15146 (set_attr "i387_cw" "<rounding>")
15147 (set_attr "mode" "XF")])
15148
15149 (define_insn "frndintxf2_<rounding>_i387"
15150 [(set (match_operand:XF 0 "register_operand" "=f")
15151 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15152 FRNDINT_ROUNDING))
15153 (use (match_operand:HI 2 "memory_operand" "m"))
15154 (use (match_operand:HI 3 "memory_operand" "m"))]
15155 "TARGET_USE_FANCY_MATH_387
15156 && flag_unsafe_math_optimizations"
15157 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15158 [(set_attr "type" "frndint")
15159 (set_attr "i387_cw" "<rounding>")
15160 (set_attr "mode" "XF")])
15161
15162 (define_expand "<rounding_insn>xf2"
15163 [(parallel [(set (match_operand:XF 0 "register_operand")
15164 (unspec:XF [(match_operand:XF 1 "register_operand")]
15165 FRNDINT_ROUNDING))
15166 (clobber (reg:CC FLAGS_REG))])]
15167 "TARGET_USE_FANCY_MATH_387
15168 && flag_unsafe_math_optimizations
15169 && !optimize_insn_for_size_p ()")
15170
15171 (define_expand "<rounding_insn><mode>2"
15172 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15173 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15174 FRNDINT_ROUNDING))
15175 (clobber (reg:CC FLAGS_REG))])]
15176 "(TARGET_USE_FANCY_MATH_387
15177 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15178 || TARGET_MIX_SSE_I387)
15179 && flag_unsafe_math_optimizations)
15180 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15181 && !flag_trapping_math)"
15182 {
15183 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15184 && !flag_trapping_math)
15185 {
15186 if (TARGET_ROUND)
15187 emit_insn (gen_sse4_1_round<mode>2
15188 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15189 else if (optimize_insn_for_size_p ())
15190 FAIL;
15191 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15192 {
15193 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15194 ix86_expand_floorceil (operands[0], operands[1], true);
15195 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15196 ix86_expand_floorceil (operands[0], operands[1], false);
15197 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15198 ix86_expand_trunc (operands[0], operands[1]);
15199 else
15200 gcc_unreachable ();
15201 }
15202 else
15203 {
15204 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15205 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15206 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15207 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15208 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15209 ix86_expand_truncdf_32 (operands[0], operands[1]);
15210 else
15211 gcc_unreachable ();
15212 }
15213 }
15214 else
15215 {
15216 rtx op0, op1;
15217
15218 if (optimize_insn_for_size_p ())
15219 FAIL;
15220
15221 op0 = gen_reg_rtx (XFmode);
15222 op1 = gen_reg_rtx (XFmode);
15223 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15224 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15225
15226 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15227 }
15228 DONE;
15229 })
15230
15231 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15232 (define_insn_and_split "frndintxf2_mask_pm"
15233 [(set (match_operand:XF 0 "register_operand")
15234 (unspec:XF [(match_operand:XF 1 "register_operand")]
15235 UNSPEC_FRNDINT_MASK_PM))
15236 (clobber (reg:CC FLAGS_REG))]
15237 "TARGET_USE_FANCY_MATH_387
15238 && flag_unsafe_math_optimizations
15239 && can_create_pseudo_p ()"
15240 "#"
15241 "&& 1"
15242 [(const_int 0)]
15243 {
15244 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15245
15246 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15247 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15248
15249 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15250 operands[2], operands[3]));
15251 DONE;
15252 }
15253 [(set_attr "type" "frndint")
15254 (set_attr "i387_cw" "mask_pm")
15255 (set_attr "mode" "XF")])
15256
15257 (define_insn "frndintxf2_mask_pm_i387"
15258 [(set (match_operand:XF 0 "register_operand" "=f")
15259 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15260 UNSPEC_FRNDINT_MASK_PM))
15261 (use (match_operand:HI 2 "memory_operand" "m"))
15262 (use (match_operand:HI 3 "memory_operand" "m"))]
15263 "TARGET_USE_FANCY_MATH_387
15264 && flag_unsafe_math_optimizations"
15265 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15266 [(set_attr "type" "frndint")
15267 (set_attr "i387_cw" "mask_pm")
15268 (set_attr "mode" "XF")])
15269
15270 (define_expand "nearbyintxf2"
15271 [(parallel [(set (match_operand:XF 0 "register_operand")
15272 (unspec:XF [(match_operand:XF 1 "register_operand")]
15273 UNSPEC_FRNDINT_MASK_PM))
15274 (clobber (reg:CC FLAGS_REG))])]
15275 "TARGET_USE_FANCY_MATH_387
15276 && flag_unsafe_math_optimizations")
15277
15278 (define_expand "nearbyint<mode>2"
15279 [(use (match_operand:MODEF 0 "register_operand"))
15280 (use (match_operand:MODEF 1 "register_operand"))]
15281 "TARGET_USE_FANCY_MATH_387
15282 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15283 || TARGET_MIX_SSE_I387)
15284 && flag_unsafe_math_optimizations"
15285 {
15286 rtx op0 = gen_reg_rtx (XFmode);
15287 rtx op1 = gen_reg_rtx (XFmode);
15288
15289 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15290 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15291
15292 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15293 DONE;
15294 })
15295
15296 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15297 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15298 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15299 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15300 FIST_ROUNDING))
15301 (clobber (reg:CC FLAGS_REG))]
15302 "TARGET_USE_FANCY_MATH_387
15303 && flag_unsafe_math_optimizations
15304 && can_create_pseudo_p ()"
15305 "#"
15306 "&& 1"
15307 [(const_int 0)]
15308 {
15309 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15310
15311 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15312 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15313 if (memory_operand (operands[0], VOIDmode))
15314 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15315 operands[2], operands[3]));
15316 else
15317 {
15318 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15319 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15320 (operands[0], operands[1], operands[2],
15321 operands[3], operands[4]));
15322 }
15323 DONE;
15324 }
15325 [(set_attr "type" "fistp")
15326 (set_attr "i387_cw" "<rounding>")
15327 (set_attr "mode" "<MODE>")])
15328
15329 (define_insn "fistdi2_<rounding>"
15330 [(set (match_operand:DI 0 "memory_operand" "=m")
15331 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15332 FIST_ROUNDING))
15333 (use (match_operand:HI 2 "memory_operand" "m"))
15334 (use (match_operand:HI 3 "memory_operand" "m"))
15335 (clobber (match_scratch:XF 4 "=&1f"))]
15336 "TARGET_USE_FANCY_MATH_387
15337 && flag_unsafe_math_optimizations"
15338 "* return output_fix_trunc (insn, operands, false);"
15339 [(set_attr "type" "fistp")
15340 (set_attr "i387_cw" "<rounding>")
15341 (set_attr "mode" "DI")])
15342
15343 (define_insn "fistdi2_<rounding>_with_temp"
15344 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15345 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15346 FIST_ROUNDING))
15347 (use (match_operand:HI 2 "memory_operand" "m,m"))
15348 (use (match_operand:HI 3 "memory_operand" "m,m"))
15349 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15350 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15351 "TARGET_USE_FANCY_MATH_387
15352 && flag_unsafe_math_optimizations"
15353 "#"
15354 [(set_attr "type" "fistp")
15355 (set_attr "i387_cw" "<rounding>")
15356 (set_attr "mode" "DI")])
15357
15358 (define_split
15359 [(set (match_operand:DI 0 "register_operand")
15360 (unspec:DI [(match_operand:XF 1 "register_operand")]
15361 FIST_ROUNDING))
15362 (use (match_operand:HI 2 "memory_operand"))
15363 (use (match_operand:HI 3 "memory_operand"))
15364 (clobber (match_operand:DI 4 "memory_operand"))
15365 (clobber (match_scratch 5))]
15366 "reload_completed"
15367 [(parallel [(set (match_dup 4)
15368 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15369 (use (match_dup 2))
15370 (use (match_dup 3))
15371 (clobber (match_dup 5))])
15372 (set (match_dup 0) (match_dup 4))])
15373
15374 (define_split
15375 [(set (match_operand:DI 0 "memory_operand")
15376 (unspec:DI [(match_operand:XF 1 "register_operand")]
15377 FIST_ROUNDING))
15378 (use (match_operand:HI 2 "memory_operand"))
15379 (use (match_operand:HI 3 "memory_operand"))
15380 (clobber (match_operand:DI 4 "memory_operand"))
15381 (clobber (match_scratch 5))]
15382 "reload_completed"
15383 [(parallel [(set (match_dup 0)
15384 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15385 (use (match_dup 2))
15386 (use (match_dup 3))
15387 (clobber (match_dup 5))])])
15388
15389 (define_insn "fist<mode>2_<rounding>"
15390 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15391 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15392 FIST_ROUNDING))
15393 (use (match_operand:HI 2 "memory_operand" "m"))
15394 (use (match_operand:HI 3 "memory_operand" "m"))]
15395 "TARGET_USE_FANCY_MATH_387
15396 && flag_unsafe_math_optimizations"
15397 "* return output_fix_trunc (insn, operands, false);"
15398 [(set_attr "type" "fistp")
15399 (set_attr "i387_cw" "<rounding>")
15400 (set_attr "mode" "<MODE>")])
15401
15402 (define_insn "fist<mode>2_<rounding>_with_temp"
15403 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15404 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15405 FIST_ROUNDING))
15406 (use (match_operand:HI 2 "memory_operand" "m,m"))
15407 (use (match_operand:HI 3 "memory_operand" "m,m"))
15408 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15409 "TARGET_USE_FANCY_MATH_387
15410 && flag_unsafe_math_optimizations"
15411 "#"
15412 [(set_attr "type" "fistp")
15413 (set_attr "i387_cw" "<rounding>")
15414 (set_attr "mode" "<MODE>")])
15415
15416 (define_split
15417 [(set (match_operand:SWI24 0 "register_operand")
15418 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15419 FIST_ROUNDING))
15420 (use (match_operand:HI 2 "memory_operand"))
15421 (use (match_operand:HI 3 "memory_operand"))
15422 (clobber (match_operand:SWI24 4 "memory_operand"))]
15423 "reload_completed"
15424 [(parallel [(set (match_dup 4)
15425 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15426 (use (match_dup 2))
15427 (use (match_dup 3))])
15428 (set (match_dup 0) (match_dup 4))])
15429
15430 (define_split
15431 [(set (match_operand:SWI24 0 "memory_operand")
15432 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15433 FIST_ROUNDING))
15434 (use (match_operand:HI 2 "memory_operand"))
15435 (use (match_operand:HI 3 "memory_operand"))
15436 (clobber (match_operand:SWI24 4 "memory_operand"))]
15437 "reload_completed"
15438 [(parallel [(set (match_dup 0)
15439 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15440 (use (match_dup 2))
15441 (use (match_dup 3))])])
15442
15443 (define_expand "l<rounding_insn>xf<mode>2"
15444 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15445 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15446 FIST_ROUNDING))
15447 (clobber (reg:CC FLAGS_REG))])]
15448 "TARGET_USE_FANCY_MATH_387
15449 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15450 && flag_unsafe_math_optimizations")
15451
15452 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15453 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15454 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15455 FIST_ROUNDING))
15456 (clobber (reg:CC FLAGS_REG))])]
15457 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15458 && !flag_trapping_math"
15459 {
15460 if (TARGET_64BIT && optimize_insn_for_size_p ())
15461 FAIL;
15462
15463 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15464 ix86_expand_lfloorceil (operands[0], operands[1], true);
15465 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15466 ix86_expand_lfloorceil (operands[0], operands[1], false);
15467 else
15468 gcc_unreachable ();
15469
15470 DONE;
15471 })
15472
15473 (define_insn "fxam<mode>2_i387"
15474 [(set (match_operand:HI 0 "register_operand" "=a")
15475 (unspec:HI
15476 [(match_operand:X87MODEF 1 "register_operand" "f")]
15477 UNSPEC_FXAM))]
15478 "TARGET_USE_FANCY_MATH_387"
15479 "fxam\n\tfnstsw\t%0"
15480 [(set_attr "type" "multi")
15481 (set_attr "length" "4")
15482 (set_attr "unit" "i387")
15483 (set_attr "mode" "<MODE>")])
15484
15485 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15486 [(set (match_operand:HI 0 "register_operand")
15487 (unspec:HI
15488 [(match_operand:MODEF 1 "memory_operand")]
15489 UNSPEC_FXAM_MEM))]
15490 "TARGET_USE_FANCY_MATH_387
15491 && can_create_pseudo_p ()"
15492 "#"
15493 "&& 1"
15494 [(set (match_dup 2)(match_dup 1))
15495 (set (match_dup 0)
15496 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15497 {
15498 operands[2] = gen_reg_rtx (<MODE>mode);
15499
15500 MEM_VOLATILE_P (operands[1]) = 1;
15501 }
15502 [(set_attr "type" "multi")
15503 (set_attr "unit" "i387")
15504 (set_attr "mode" "<MODE>")])
15505
15506 (define_expand "isinfxf2"
15507 [(use (match_operand:SI 0 "register_operand"))
15508 (use (match_operand:XF 1 "register_operand"))]
15509 "TARGET_USE_FANCY_MATH_387
15510 && TARGET_C99_FUNCTIONS"
15511 {
15512 rtx mask = GEN_INT (0x45);
15513 rtx val = GEN_INT (0x05);
15514
15515 rtx cond;
15516
15517 rtx scratch = gen_reg_rtx (HImode);
15518 rtx res = gen_reg_rtx (QImode);
15519
15520 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15521
15522 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15523 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15524 cond = gen_rtx_fmt_ee (EQ, QImode,
15525 gen_rtx_REG (CCmode, FLAGS_REG),
15526 const0_rtx);
15527 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15528 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15529 DONE;
15530 })
15531
15532 (define_expand "isinf<mode>2"
15533 [(use (match_operand:SI 0 "register_operand"))
15534 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15535 "TARGET_USE_FANCY_MATH_387
15536 && TARGET_C99_FUNCTIONS
15537 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15538 {
15539 rtx mask = GEN_INT (0x45);
15540 rtx val = GEN_INT (0x05);
15541
15542 rtx cond;
15543
15544 rtx scratch = gen_reg_rtx (HImode);
15545 rtx res = gen_reg_rtx (QImode);
15546
15547 /* Remove excess precision by forcing value through memory. */
15548 if (memory_operand (operands[1], VOIDmode))
15549 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15550 else
15551 {
15552 enum ix86_stack_slot slot = (virtuals_instantiated
15553 ? SLOT_TEMP
15554 : SLOT_VIRTUAL);
15555 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15556
15557 emit_move_insn (temp, operands[1]);
15558 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15559 }
15560
15561 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15562 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15563 cond = gen_rtx_fmt_ee (EQ, QImode,
15564 gen_rtx_REG (CCmode, FLAGS_REG),
15565 const0_rtx);
15566 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15567 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15568 DONE;
15569 })
15570
15571 (define_expand "signbitxf2"
15572 [(use (match_operand:SI 0 "register_operand"))
15573 (use (match_operand:XF 1 "register_operand"))]
15574 "TARGET_USE_FANCY_MATH_387"
15575 {
15576 rtx scratch = gen_reg_rtx (HImode);
15577
15578 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15579 emit_insn (gen_andsi3 (operands[0],
15580 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15581 DONE;
15582 })
15583
15584 (define_insn "movmsk_df"
15585 [(set (match_operand:SI 0 "register_operand" "=r")
15586 (unspec:SI
15587 [(match_operand:DF 1 "register_operand" "x")]
15588 UNSPEC_MOVMSK))]
15589 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15590 "%vmovmskpd\t{%1, %0|%0, %1}"
15591 [(set_attr "type" "ssemov")
15592 (set_attr "prefix" "maybe_vex")
15593 (set_attr "mode" "DF")])
15594
15595 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15596 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15597 (define_expand "signbitdf2"
15598 [(use (match_operand:SI 0 "register_operand"))
15599 (use (match_operand:DF 1 "register_operand"))]
15600 "TARGET_USE_FANCY_MATH_387
15601 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15602 {
15603 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15604 {
15605 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15606 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15607 }
15608 else
15609 {
15610 rtx scratch = gen_reg_rtx (HImode);
15611
15612 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15613 emit_insn (gen_andsi3 (operands[0],
15614 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15615 }
15616 DONE;
15617 })
15618
15619 (define_expand "signbitsf2"
15620 [(use (match_operand:SI 0 "register_operand"))
15621 (use (match_operand:SF 1 "register_operand"))]
15622 "TARGET_USE_FANCY_MATH_387
15623 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15624 {
15625 rtx scratch = gen_reg_rtx (HImode);
15626
15627 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15628 emit_insn (gen_andsi3 (operands[0],
15629 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15630 DONE;
15631 })
15632 \f
15633 ;; Block operation instructions
15634
15635 (define_insn "cld"
15636 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15637 ""
15638 "cld"
15639 [(set_attr "length" "1")
15640 (set_attr "length_immediate" "0")
15641 (set_attr "modrm" "0")])
15642
15643 (define_expand "movmem<mode>"
15644 [(use (match_operand:BLK 0 "memory_operand"))
15645 (use (match_operand:BLK 1 "memory_operand"))
15646 (use (match_operand:SWI48 2 "nonmemory_operand"))
15647 (use (match_operand:SWI48 3 "const_int_operand"))
15648 (use (match_operand:SI 4 "const_int_operand"))
15649 (use (match_operand:SI 5 "const_int_operand"))]
15650 ""
15651 {
15652 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15653 operands[4], operands[5]))
15654 DONE;
15655 else
15656 FAIL;
15657 })
15658
15659 ;; Most CPUs don't like single string operations
15660 ;; Handle this case here to simplify previous expander.
15661
15662 (define_expand "strmov"
15663 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15664 (set (match_operand 1 "memory_operand") (match_dup 4))
15665 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15666 (clobber (reg:CC FLAGS_REG))])
15667 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15668 (clobber (reg:CC FLAGS_REG))])]
15669 ""
15670 {
15671 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15672
15673 /* If .md ever supports :P for Pmode, these can be directly
15674 in the pattern above. */
15675 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15676 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15677
15678 /* Can't use this if the user has appropriated esi or edi. */
15679 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15680 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15681 {
15682 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15683 operands[2], operands[3],
15684 operands[5], operands[6]));
15685 DONE;
15686 }
15687
15688 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15689 })
15690
15691 (define_expand "strmov_singleop"
15692 [(parallel [(set (match_operand 1 "memory_operand")
15693 (match_operand 3 "memory_operand"))
15694 (set (match_operand 0 "register_operand")
15695 (match_operand 4))
15696 (set (match_operand 2 "register_operand")
15697 (match_operand 5))])]
15698 ""
15699 "ix86_current_function_needs_cld = 1;")
15700
15701 (define_insn "*strmovdi_rex_1"
15702 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15703 (mem:DI (match_operand:P 3 "register_operand" "1")))
15704 (set (match_operand:P 0 "register_operand" "=D")
15705 (plus:P (match_dup 2)
15706 (const_int 8)))
15707 (set (match_operand:P 1 "register_operand" "=S")
15708 (plus:P (match_dup 3)
15709 (const_int 8)))]
15710 "TARGET_64BIT
15711 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15712 "%^movsq"
15713 [(set_attr "type" "str")
15714 (set_attr "memory" "both")
15715 (set_attr "mode" "DI")])
15716
15717 (define_insn "*strmovsi_1"
15718 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15719 (mem:SI (match_operand:P 3 "register_operand" "1")))
15720 (set (match_operand:P 0 "register_operand" "=D")
15721 (plus:P (match_dup 2)
15722 (const_int 4)))
15723 (set (match_operand:P 1 "register_operand" "=S")
15724 (plus:P (match_dup 3)
15725 (const_int 4)))]
15726 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15727 "%^movs{l|d}"
15728 [(set_attr "type" "str")
15729 (set_attr "memory" "both")
15730 (set_attr "mode" "SI")])
15731
15732 (define_insn "*strmovhi_1"
15733 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15734 (mem:HI (match_operand:P 3 "register_operand" "1")))
15735 (set (match_operand:P 0 "register_operand" "=D")
15736 (plus:P (match_dup 2)
15737 (const_int 2)))
15738 (set (match_operand:P 1 "register_operand" "=S")
15739 (plus:P (match_dup 3)
15740 (const_int 2)))]
15741 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15742 "%^movsw"
15743 [(set_attr "type" "str")
15744 (set_attr "memory" "both")
15745 (set_attr "mode" "HI")])
15746
15747 (define_insn "*strmovqi_1"
15748 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15749 (mem:QI (match_operand:P 3 "register_operand" "1")))
15750 (set (match_operand:P 0 "register_operand" "=D")
15751 (plus:P (match_dup 2)
15752 (const_int 1)))
15753 (set (match_operand:P 1 "register_operand" "=S")
15754 (plus:P (match_dup 3)
15755 (const_int 1)))]
15756 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15757 "%^movsb"
15758 [(set_attr "type" "str")
15759 (set_attr "memory" "both")
15760 (set (attr "prefix_rex")
15761 (if_then_else
15762 (match_test "<P:MODE>mode == DImode")
15763 (const_string "0")
15764 (const_string "*")))
15765 (set_attr "mode" "QI")])
15766
15767 (define_expand "rep_mov"
15768 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15769 (set (match_operand 0 "register_operand")
15770 (match_operand 5))
15771 (set (match_operand 2 "register_operand")
15772 (match_operand 6))
15773 (set (match_operand 1 "memory_operand")
15774 (match_operand 3 "memory_operand"))
15775 (use (match_dup 4))])]
15776 ""
15777 "ix86_current_function_needs_cld = 1;")
15778
15779 (define_insn "*rep_movdi_rex64"
15780 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15781 (set (match_operand:P 0 "register_operand" "=D")
15782 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15783 (const_int 3))
15784 (match_operand:P 3 "register_operand" "0")))
15785 (set (match_operand:P 1 "register_operand" "=S")
15786 (plus:P (ashift:P (match_dup 5) (const_int 3))
15787 (match_operand:P 4 "register_operand" "1")))
15788 (set (mem:BLK (match_dup 3))
15789 (mem:BLK (match_dup 4)))
15790 (use (match_dup 5))]
15791 "TARGET_64BIT
15792 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15793 "%^rep{%;} movsq"
15794 [(set_attr "type" "str")
15795 (set_attr "prefix_rep" "1")
15796 (set_attr "memory" "both")
15797 (set_attr "mode" "DI")])
15798
15799 (define_insn "*rep_movsi"
15800 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15801 (set (match_operand:P 0 "register_operand" "=D")
15802 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15803 (const_int 2))
15804 (match_operand:P 3 "register_operand" "0")))
15805 (set (match_operand:P 1 "register_operand" "=S")
15806 (plus:P (ashift:P (match_dup 5) (const_int 2))
15807 (match_operand:P 4 "register_operand" "1")))
15808 (set (mem:BLK (match_dup 3))
15809 (mem:BLK (match_dup 4)))
15810 (use (match_dup 5))]
15811 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15812 "%^rep{%;} movs{l|d}"
15813 [(set_attr "type" "str")
15814 (set_attr "prefix_rep" "1")
15815 (set_attr "memory" "both")
15816 (set_attr "mode" "SI")])
15817
15818 (define_insn "*rep_movqi"
15819 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15820 (set (match_operand:P 0 "register_operand" "=D")
15821 (plus:P (match_operand:P 3 "register_operand" "0")
15822 (match_operand:P 5 "register_operand" "2")))
15823 (set (match_operand:P 1 "register_operand" "=S")
15824 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15825 (set (mem:BLK (match_dup 3))
15826 (mem:BLK (match_dup 4)))
15827 (use (match_dup 5))]
15828 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15829 "%^rep{%;} movsb"
15830 [(set_attr "type" "str")
15831 (set_attr "prefix_rep" "1")
15832 (set_attr "memory" "both")
15833 (set_attr "mode" "QI")])
15834
15835 (define_expand "setmem<mode>"
15836 [(use (match_operand:BLK 0 "memory_operand"))
15837 (use (match_operand:SWI48 1 "nonmemory_operand"))
15838 (use (match_operand:QI 2 "nonmemory_operand"))
15839 (use (match_operand 3 "const_int_operand"))
15840 (use (match_operand:SI 4 "const_int_operand"))
15841 (use (match_operand:SI 5 "const_int_operand"))]
15842 ""
15843 {
15844 if (ix86_expand_setmem (operands[0], operands[1],
15845 operands[2], operands[3],
15846 operands[4], operands[5]))
15847 DONE;
15848 else
15849 FAIL;
15850 })
15851
15852 ;; Most CPUs don't like single string operations
15853 ;; Handle this case here to simplify previous expander.
15854
15855 (define_expand "strset"
15856 [(set (match_operand 1 "memory_operand")
15857 (match_operand 2 "register_operand"))
15858 (parallel [(set (match_operand 0 "register_operand")
15859 (match_dup 3))
15860 (clobber (reg:CC FLAGS_REG))])]
15861 ""
15862 {
15863 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15864 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15865
15866 /* If .md ever supports :P for Pmode, this can be directly
15867 in the pattern above. */
15868 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15869 GEN_INT (GET_MODE_SIZE (GET_MODE
15870 (operands[2]))));
15871 /* Can't use this if the user has appropriated eax or edi. */
15872 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15873 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15874 {
15875 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15876 operands[3]));
15877 DONE;
15878 }
15879 })
15880
15881 (define_expand "strset_singleop"
15882 [(parallel [(set (match_operand 1 "memory_operand")
15883 (match_operand 2 "register_operand"))
15884 (set (match_operand 0 "register_operand")
15885 (match_operand 3))])]
15886 ""
15887 "ix86_current_function_needs_cld = 1;")
15888
15889 (define_insn "*strsetdi_rex_1"
15890 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15891 (match_operand:DI 2 "register_operand" "a"))
15892 (set (match_operand:P 0 "register_operand" "=D")
15893 (plus:P (match_dup 1)
15894 (const_int 8)))]
15895 "TARGET_64BIT
15896 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15897 "%^stosq"
15898 [(set_attr "type" "str")
15899 (set_attr "memory" "store")
15900 (set_attr "mode" "DI")])
15901
15902 (define_insn "*strsetsi_1"
15903 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15904 (match_operand:SI 2 "register_operand" "a"))
15905 (set (match_operand:P 0 "register_operand" "=D")
15906 (plus:P (match_dup 1)
15907 (const_int 4)))]
15908 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15909 "%^stos{l|d}"
15910 [(set_attr "type" "str")
15911 (set_attr "memory" "store")
15912 (set_attr "mode" "SI")])
15913
15914 (define_insn "*strsethi_1"
15915 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15916 (match_operand:HI 2 "register_operand" "a"))
15917 (set (match_operand:P 0 "register_operand" "=D")
15918 (plus:P (match_dup 1)
15919 (const_int 2)))]
15920 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15921 "%^stosw"
15922 [(set_attr "type" "str")
15923 (set_attr "memory" "store")
15924 (set_attr "mode" "HI")])
15925
15926 (define_insn "*strsetqi_1"
15927 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15928 (match_operand:QI 2 "register_operand" "a"))
15929 (set (match_operand:P 0 "register_operand" "=D")
15930 (plus:P (match_dup 1)
15931 (const_int 1)))]
15932 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15933 "%^stosb"
15934 [(set_attr "type" "str")
15935 (set_attr "memory" "store")
15936 (set (attr "prefix_rex")
15937 (if_then_else
15938 (match_test "<P:MODE>mode == DImode")
15939 (const_string "0")
15940 (const_string "*")))
15941 (set_attr "mode" "QI")])
15942
15943 (define_expand "rep_stos"
15944 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15945 (set (match_operand 0 "register_operand")
15946 (match_operand 4))
15947 (set (match_operand 2 "memory_operand") (const_int 0))
15948 (use (match_operand 3 "register_operand"))
15949 (use (match_dup 1))])]
15950 ""
15951 "ix86_current_function_needs_cld = 1;")
15952
15953 (define_insn "*rep_stosdi_rex64"
15954 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15955 (set (match_operand:P 0 "register_operand" "=D")
15956 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15957 (const_int 3))
15958 (match_operand:P 3 "register_operand" "0")))
15959 (set (mem:BLK (match_dup 3))
15960 (const_int 0))
15961 (use (match_operand:DI 2 "register_operand" "a"))
15962 (use (match_dup 4))]
15963 "TARGET_64BIT
15964 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15965 "%^rep{%;} stosq"
15966 [(set_attr "type" "str")
15967 (set_attr "prefix_rep" "1")
15968 (set_attr "memory" "store")
15969 (set_attr "mode" "DI")])
15970
15971 (define_insn "*rep_stossi"
15972 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15973 (set (match_operand:P 0 "register_operand" "=D")
15974 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15975 (const_int 2))
15976 (match_operand:P 3 "register_operand" "0")))
15977 (set (mem:BLK (match_dup 3))
15978 (const_int 0))
15979 (use (match_operand:SI 2 "register_operand" "a"))
15980 (use (match_dup 4))]
15981 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15982 "%^rep{%;} stos{l|d}"
15983 [(set_attr "type" "str")
15984 (set_attr "prefix_rep" "1")
15985 (set_attr "memory" "store")
15986 (set_attr "mode" "SI")])
15987
15988 (define_insn "*rep_stosqi"
15989 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15990 (set (match_operand:P 0 "register_operand" "=D")
15991 (plus:P (match_operand:P 3 "register_operand" "0")
15992 (match_operand:P 4 "register_operand" "1")))
15993 (set (mem:BLK (match_dup 3))
15994 (const_int 0))
15995 (use (match_operand:QI 2 "register_operand" "a"))
15996 (use (match_dup 4))]
15997 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15998 "%^rep{%;} stosb"
15999 [(set_attr "type" "str")
16000 (set_attr "prefix_rep" "1")
16001 (set_attr "memory" "store")
16002 (set (attr "prefix_rex")
16003 (if_then_else
16004 (match_test "<P:MODE>mode == DImode")
16005 (const_string "0")
16006 (const_string "*")))
16007 (set_attr "mode" "QI")])
16008
16009 (define_expand "cmpstrnsi"
16010 [(set (match_operand:SI 0 "register_operand")
16011 (compare:SI (match_operand:BLK 1 "general_operand")
16012 (match_operand:BLK 2 "general_operand")))
16013 (use (match_operand 3 "general_operand"))
16014 (use (match_operand 4 "immediate_operand"))]
16015 ""
16016 {
16017 rtx addr1, addr2, out, outlow, count, countreg, align;
16018
16019 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16020 FAIL;
16021
16022 /* Can't use this if the user has appropriated ecx, esi or edi. */
16023 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16024 FAIL;
16025
16026 out = operands[0];
16027 if (!REG_P (out))
16028 out = gen_reg_rtx (SImode);
16029
16030 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16031 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16032 if (addr1 != XEXP (operands[1], 0))
16033 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16034 if (addr2 != XEXP (operands[2], 0))
16035 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16036
16037 count = operands[3];
16038 countreg = ix86_zero_extend_to_Pmode (count);
16039
16040 /* %%% Iff we are testing strict equality, we can use known alignment
16041 to good advantage. This may be possible with combine, particularly
16042 once cc0 is dead. */
16043 align = operands[4];
16044
16045 if (CONST_INT_P (count))
16046 {
16047 if (INTVAL (count) == 0)
16048 {
16049 emit_move_insn (operands[0], const0_rtx);
16050 DONE;
16051 }
16052 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16053 operands[1], operands[2]));
16054 }
16055 else
16056 {
16057 rtx (*gen_cmp) (rtx, rtx);
16058
16059 gen_cmp = (TARGET_64BIT
16060 ? gen_cmpdi_1 : gen_cmpsi_1);
16061
16062 emit_insn (gen_cmp (countreg, countreg));
16063 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16064 operands[1], operands[2]));
16065 }
16066
16067 outlow = gen_lowpart (QImode, out);
16068 emit_insn (gen_cmpintqi (outlow));
16069 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16070
16071 if (operands[0] != out)
16072 emit_move_insn (operands[0], out);
16073
16074 DONE;
16075 })
16076
16077 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16078
16079 (define_expand "cmpintqi"
16080 [(set (match_dup 1)
16081 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16082 (set (match_dup 2)
16083 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16084 (parallel [(set (match_operand:QI 0 "register_operand")
16085 (minus:QI (match_dup 1)
16086 (match_dup 2)))
16087 (clobber (reg:CC FLAGS_REG))])]
16088 ""
16089 {
16090 operands[1] = gen_reg_rtx (QImode);
16091 operands[2] = gen_reg_rtx (QImode);
16092 })
16093
16094 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16095 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16096
16097 (define_expand "cmpstrnqi_nz_1"
16098 [(parallel [(set (reg:CC FLAGS_REG)
16099 (compare:CC (match_operand 4 "memory_operand")
16100 (match_operand 5 "memory_operand")))
16101 (use (match_operand 2 "register_operand"))
16102 (use (match_operand:SI 3 "immediate_operand"))
16103 (clobber (match_operand 0 "register_operand"))
16104 (clobber (match_operand 1 "register_operand"))
16105 (clobber (match_dup 2))])]
16106 ""
16107 "ix86_current_function_needs_cld = 1;")
16108
16109 (define_insn "*cmpstrnqi_nz_1"
16110 [(set (reg:CC FLAGS_REG)
16111 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16112 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16113 (use (match_operand:P 6 "register_operand" "2"))
16114 (use (match_operand:SI 3 "immediate_operand" "i"))
16115 (clobber (match_operand:P 0 "register_operand" "=S"))
16116 (clobber (match_operand:P 1 "register_operand" "=D"))
16117 (clobber (match_operand:P 2 "register_operand" "=c"))]
16118 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16119 "%^repz{%;} cmpsb"
16120 [(set_attr "type" "str")
16121 (set_attr "mode" "QI")
16122 (set (attr "prefix_rex")
16123 (if_then_else
16124 (match_test "<P:MODE>mode == DImode")
16125 (const_string "0")
16126 (const_string "*")))
16127 (set_attr "prefix_rep" "1")])
16128
16129 ;; The same, but the count is not known to not be zero.
16130
16131 (define_expand "cmpstrnqi_1"
16132 [(parallel [(set (reg:CC FLAGS_REG)
16133 (if_then_else:CC (ne (match_operand 2 "register_operand")
16134 (const_int 0))
16135 (compare:CC (match_operand 4 "memory_operand")
16136 (match_operand 5 "memory_operand"))
16137 (const_int 0)))
16138 (use (match_operand:SI 3 "immediate_operand"))
16139 (use (reg:CC FLAGS_REG))
16140 (clobber (match_operand 0 "register_operand"))
16141 (clobber (match_operand 1 "register_operand"))
16142 (clobber (match_dup 2))])]
16143 ""
16144 "ix86_current_function_needs_cld = 1;")
16145
16146 (define_insn "*cmpstrnqi_1"
16147 [(set (reg:CC FLAGS_REG)
16148 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16149 (const_int 0))
16150 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16151 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16152 (const_int 0)))
16153 (use (match_operand:SI 3 "immediate_operand" "i"))
16154 (use (reg:CC FLAGS_REG))
16155 (clobber (match_operand:P 0 "register_operand" "=S"))
16156 (clobber (match_operand:P 1 "register_operand" "=D"))
16157 (clobber (match_operand:P 2 "register_operand" "=c"))]
16158 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16159 "%^repz{%;} cmpsb"
16160 [(set_attr "type" "str")
16161 (set_attr "mode" "QI")
16162 (set (attr "prefix_rex")
16163 (if_then_else
16164 (match_test "<P:MODE>mode == DImode")
16165 (const_string "0")
16166 (const_string "*")))
16167 (set_attr "prefix_rep" "1")])
16168
16169 (define_expand "strlen<mode>"
16170 [(set (match_operand:P 0 "register_operand")
16171 (unspec:P [(match_operand:BLK 1 "general_operand")
16172 (match_operand:QI 2 "immediate_operand")
16173 (match_operand 3 "immediate_operand")]
16174 UNSPEC_SCAS))]
16175 ""
16176 {
16177 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16178 DONE;
16179 else
16180 FAIL;
16181 })
16182
16183 (define_expand "strlenqi_1"
16184 [(parallel [(set (match_operand 0 "register_operand")
16185 (match_operand 2))
16186 (clobber (match_operand 1 "register_operand"))
16187 (clobber (reg:CC FLAGS_REG))])]
16188 ""
16189 "ix86_current_function_needs_cld = 1;")
16190
16191 (define_insn "*strlenqi_1"
16192 [(set (match_operand:P 0 "register_operand" "=&c")
16193 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16194 (match_operand:QI 2 "register_operand" "a")
16195 (match_operand:P 3 "immediate_operand" "i")
16196 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16197 (clobber (match_operand:P 1 "register_operand" "=D"))
16198 (clobber (reg:CC FLAGS_REG))]
16199 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16200 "%^repnz{%;} scasb"
16201 [(set_attr "type" "str")
16202 (set_attr "mode" "QI")
16203 (set (attr "prefix_rex")
16204 (if_then_else
16205 (match_test "<P:MODE>mode == DImode")
16206 (const_string "0")
16207 (const_string "*")))
16208 (set_attr "prefix_rep" "1")])
16209
16210 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16211 ;; handled in combine, but it is not currently up to the task.
16212 ;; When used for their truth value, the cmpstrn* expanders generate
16213 ;; code like this:
16214 ;;
16215 ;; repz cmpsb
16216 ;; seta %al
16217 ;; setb %dl
16218 ;; cmpb %al, %dl
16219 ;; jcc label
16220 ;;
16221 ;; The intermediate three instructions are unnecessary.
16222
16223 ;; This one handles cmpstrn*_nz_1...
16224 (define_peephole2
16225 [(parallel[
16226 (set (reg:CC FLAGS_REG)
16227 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16228 (mem:BLK (match_operand 5 "register_operand"))))
16229 (use (match_operand 6 "register_operand"))
16230 (use (match_operand:SI 3 "immediate_operand"))
16231 (clobber (match_operand 0 "register_operand"))
16232 (clobber (match_operand 1 "register_operand"))
16233 (clobber (match_operand 2 "register_operand"))])
16234 (set (match_operand:QI 7 "register_operand")
16235 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16236 (set (match_operand:QI 8 "register_operand")
16237 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16238 (set (reg FLAGS_REG)
16239 (compare (match_dup 7) (match_dup 8)))
16240 ]
16241 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16242 [(parallel[
16243 (set (reg:CC FLAGS_REG)
16244 (compare:CC (mem:BLK (match_dup 4))
16245 (mem:BLK (match_dup 5))))
16246 (use (match_dup 6))
16247 (use (match_dup 3))
16248 (clobber (match_dup 0))
16249 (clobber (match_dup 1))
16250 (clobber (match_dup 2))])])
16251
16252 ;; ...and this one handles cmpstrn*_1.
16253 (define_peephole2
16254 [(parallel[
16255 (set (reg:CC FLAGS_REG)
16256 (if_then_else:CC (ne (match_operand 6 "register_operand")
16257 (const_int 0))
16258 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16259 (mem:BLK (match_operand 5 "register_operand")))
16260 (const_int 0)))
16261 (use (match_operand:SI 3 "immediate_operand"))
16262 (use (reg:CC FLAGS_REG))
16263 (clobber (match_operand 0 "register_operand"))
16264 (clobber (match_operand 1 "register_operand"))
16265 (clobber (match_operand 2 "register_operand"))])
16266 (set (match_operand:QI 7 "register_operand")
16267 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16268 (set (match_operand:QI 8 "register_operand")
16269 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16270 (set (reg FLAGS_REG)
16271 (compare (match_dup 7) (match_dup 8)))
16272 ]
16273 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16274 [(parallel[
16275 (set (reg:CC FLAGS_REG)
16276 (if_then_else:CC (ne (match_dup 6)
16277 (const_int 0))
16278 (compare:CC (mem:BLK (match_dup 4))
16279 (mem:BLK (match_dup 5)))
16280 (const_int 0)))
16281 (use (match_dup 3))
16282 (use (reg:CC FLAGS_REG))
16283 (clobber (match_dup 0))
16284 (clobber (match_dup 1))
16285 (clobber (match_dup 2))])])
16286 \f
16287 ;; Conditional move instructions.
16288
16289 (define_expand "mov<mode>cc"
16290 [(set (match_operand:SWIM 0 "register_operand")
16291 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16292 (match_operand:SWIM 2 "<general_operand>")
16293 (match_operand:SWIM 3 "<general_operand>")))]
16294 ""
16295 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16296
16297 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16298 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16299 ;; So just document what we're doing explicitly.
16300
16301 (define_expand "x86_mov<mode>cc_0_m1"
16302 [(parallel
16303 [(set (match_operand:SWI48 0 "register_operand")
16304 (if_then_else:SWI48
16305 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16306 [(match_operand 1 "flags_reg_operand")
16307 (const_int 0)])
16308 (const_int -1)
16309 (const_int 0)))
16310 (clobber (reg:CC FLAGS_REG))])])
16311
16312 (define_insn "*x86_mov<mode>cc_0_m1"
16313 [(set (match_operand:SWI48 0 "register_operand" "=r")
16314 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16315 [(reg FLAGS_REG) (const_int 0)])
16316 (const_int -1)
16317 (const_int 0)))
16318 (clobber (reg:CC FLAGS_REG))]
16319 ""
16320 "sbb{<imodesuffix>}\t%0, %0"
16321 ; Since we don't have the proper number of operands for an alu insn,
16322 ; fill in all the blanks.
16323 [(set_attr "type" "alu")
16324 (set_attr "use_carry" "1")
16325 (set_attr "pent_pair" "pu")
16326 (set_attr "memory" "none")
16327 (set_attr "imm_disp" "false")
16328 (set_attr "mode" "<MODE>")
16329 (set_attr "length_immediate" "0")])
16330
16331 (define_insn "*x86_mov<mode>cc_0_m1_se"
16332 [(set (match_operand:SWI48 0 "register_operand" "=r")
16333 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16334 [(reg FLAGS_REG) (const_int 0)])
16335 (const_int 1)
16336 (const_int 0)))
16337 (clobber (reg:CC FLAGS_REG))]
16338 ""
16339 "sbb{<imodesuffix>}\t%0, %0"
16340 [(set_attr "type" "alu")
16341 (set_attr "use_carry" "1")
16342 (set_attr "pent_pair" "pu")
16343 (set_attr "memory" "none")
16344 (set_attr "imm_disp" "false")
16345 (set_attr "mode" "<MODE>")
16346 (set_attr "length_immediate" "0")])
16347
16348 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16349 [(set (match_operand:SWI48 0 "register_operand" "=r")
16350 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16351 [(reg FLAGS_REG) (const_int 0)])))
16352 (clobber (reg:CC FLAGS_REG))]
16353 ""
16354 "sbb{<imodesuffix>}\t%0, %0"
16355 [(set_attr "type" "alu")
16356 (set_attr "use_carry" "1")
16357 (set_attr "pent_pair" "pu")
16358 (set_attr "memory" "none")
16359 (set_attr "imm_disp" "false")
16360 (set_attr "mode" "<MODE>")
16361 (set_attr "length_immediate" "0")])
16362
16363 (define_insn "*mov<mode>cc_noc"
16364 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16365 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16366 [(reg FLAGS_REG) (const_int 0)])
16367 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16368 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16369 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16370 "@
16371 cmov%O2%C1\t{%2, %0|%0, %2}
16372 cmov%O2%c1\t{%3, %0|%0, %3}"
16373 [(set_attr "type" "icmov")
16374 (set_attr "mode" "<MODE>")])
16375
16376 (define_insn_and_split "*movqicc_noc"
16377 [(set (match_operand:QI 0 "register_operand" "=r,r")
16378 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16379 [(match_operand 4 "flags_reg_operand")
16380 (const_int 0)])
16381 (match_operand:QI 2 "register_operand" "r,0")
16382 (match_operand:QI 3 "register_operand" "0,r")))]
16383 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16384 "#"
16385 "&& reload_completed"
16386 [(set (match_dup 0)
16387 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16388 (match_dup 2)
16389 (match_dup 3)))]
16390 "operands[0] = gen_lowpart (SImode, operands[0]);
16391 operands[2] = gen_lowpart (SImode, operands[2]);
16392 operands[3] = gen_lowpart (SImode, operands[3]);"
16393 [(set_attr "type" "icmov")
16394 (set_attr "mode" "SI")])
16395
16396 (define_expand "mov<mode>cc"
16397 [(set (match_operand:X87MODEF 0 "register_operand")
16398 (if_then_else:X87MODEF
16399 (match_operand 1 "ix86_fp_comparison_operator")
16400 (match_operand:X87MODEF 2 "register_operand")
16401 (match_operand:X87MODEF 3 "register_operand")))]
16402 "(TARGET_80387 && TARGET_CMOVE)
16403 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16404 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16405
16406 (define_insn "*movxfcc_1"
16407 [(set (match_operand:XF 0 "register_operand" "=f,f")
16408 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16409 [(reg FLAGS_REG) (const_int 0)])
16410 (match_operand:XF 2 "register_operand" "f,0")
16411 (match_operand:XF 3 "register_operand" "0,f")))]
16412 "TARGET_80387 && TARGET_CMOVE"
16413 "@
16414 fcmov%F1\t{%2, %0|%0, %2}
16415 fcmov%f1\t{%3, %0|%0, %3}"
16416 [(set_attr "type" "fcmov")
16417 (set_attr "mode" "XF")])
16418
16419 (define_insn "*movdfcc_1_rex64"
16420 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16421 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16422 [(reg FLAGS_REG) (const_int 0)])
16423 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16424 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16425 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16426 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16427 "@
16428 fcmov%F1\t{%2, %0|%0, %2}
16429 fcmov%f1\t{%3, %0|%0, %3}
16430 cmov%O2%C1\t{%2, %0|%0, %2}
16431 cmov%O2%c1\t{%3, %0|%0, %3}"
16432 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16433 (set_attr "mode" "DF,DF,DI,DI")])
16434
16435 (define_insn "*movdfcc_1"
16436 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16437 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16438 [(reg FLAGS_REG) (const_int 0)])
16439 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16440 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16441 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16442 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16443 "@
16444 fcmov%F1\t{%2, %0|%0, %2}
16445 fcmov%f1\t{%3, %0|%0, %3}
16446 #
16447 #"
16448 [(set_attr "type" "fcmov,fcmov,multi,multi")
16449 (set_attr "mode" "DF,DF,DI,DI")])
16450
16451 (define_split
16452 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16453 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16454 [(match_operand 4 "flags_reg_operand")
16455 (const_int 0)])
16456 (match_operand:DF 2 "nonimmediate_operand")
16457 (match_operand:DF 3 "nonimmediate_operand")))]
16458 "!TARGET_64BIT && reload_completed"
16459 [(set (match_dup 2)
16460 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16461 (match_dup 5)
16462 (match_dup 6)))
16463 (set (match_dup 3)
16464 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16465 (match_dup 7)
16466 (match_dup 8)))]
16467 {
16468 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16469 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16470 })
16471
16472 (define_insn "*movsfcc_1_387"
16473 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16474 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16475 [(reg FLAGS_REG) (const_int 0)])
16476 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16477 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16478 "TARGET_80387 && TARGET_CMOVE
16479 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16480 "@
16481 fcmov%F1\t{%2, %0|%0, %2}
16482 fcmov%f1\t{%3, %0|%0, %3}
16483 cmov%O2%C1\t{%2, %0|%0, %2}
16484 cmov%O2%c1\t{%3, %0|%0, %3}"
16485 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16486 (set_attr "mode" "SF,SF,SI,SI")])
16487
16488 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16489 ;; the scalar versions to have only XMM registers as operands.
16490
16491 ;; XOP conditional move
16492 (define_insn "*xop_pcmov_<mode>"
16493 [(set (match_operand:MODEF 0 "register_operand" "=x")
16494 (if_then_else:MODEF
16495 (match_operand:MODEF 1 "register_operand" "x")
16496 (match_operand:MODEF 2 "register_operand" "x")
16497 (match_operand:MODEF 3 "register_operand" "x")))]
16498 "TARGET_XOP"
16499 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16500 [(set_attr "type" "sse4arg")])
16501
16502 ;; These versions of the min/max patterns are intentionally ignorant of
16503 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16504 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16505 ;; are undefined in this condition, we're certain this is correct.
16506
16507 (define_insn "<code><mode>3"
16508 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16509 (smaxmin:MODEF
16510 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16511 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16512 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16513 "@
16514 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16515 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16516 [(set_attr "isa" "noavx,avx")
16517 (set_attr "prefix" "orig,vex")
16518 (set_attr "type" "sseadd")
16519 (set_attr "mode" "<MODE>")])
16520
16521 ;; These versions of the min/max patterns implement exactly the operations
16522 ;; min = (op1 < op2 ? op1 : op2)
16523 ;; max = (!(op1 < op2) ? op1 : op2)
16524 ;; Their operands are not commutative, and thus they may be used in the
16525 ;; presence of -0.0 and NaN.
16526
16527 (define_int_iterator IEEE_MAXMIN
16528 [UNSPEC_IEEE_MAX
16529 UNSPEC_IEEE_MIN])
16530
16531 (define_int_attr ieee_maxmin
16532 [(UNSPEC_IEEE_MAX "max")
16533 (UNSPEC_IEEE_MIN "min")])
16534
16535 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16536 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16537 (unspec:MODEF
16538 [(match_operand:MODEF 1 "register_operand" "0,x")
16539 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16540 IEEE_MAXMIN))]
16541 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16542 "@
16543 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16544 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16545 [(set_attr "isa" "noavx,avx")
16546 (set_attr "prefix" "orig,vex")
16547 (set_attr "type" "sseadd")
16548 (set_attr "mode" "<MODE>")])
16549
16550 ;; Make two stack loads independent:
16551 ;; fld aa fld aa
16552 ;; fld %st(0) -> fld bb
16553 ;; fmul bb fmul %st(1), %st
16554 ;;
16555 ;; Actually we only match the last two instructions for simplicity.
16556 (define_peephole2
16557 [(set (match_operand 0 "fp_register_operand")
16558 (match_operand 1 "fp_register_operand"))
16559 (set (match_dup 0)
16560 (match_operator 2 "binary_fp_operator"
16561 [(match_dup 0)
16562 (match_operand 3 "memory_operand")]))]
16563 "REGNO (operands[0]) != REGNO (operands[1])"
16564 [(set (match_dup 0) (match_dup 3))
16565 (set (match_dup 0) (match_dup 4))]
16566
16567 ;; The % modifier is not operational anymore in peephole2's, so we have to
16568 ;; swap the operands manually in the case of addition and multiplication.
16569 {
16570 rtx op0, op1;
16571
16572 if (COMMUTATIVE_ARITH_P (operands[2]))
16573 op0 = operands[0], op1 = operands[1];
16574 else
16575 op0 = operands[1], op1 = operands[0];
16576
16577 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16578 GET_MODE (operands[2]),
16579 op0, op1);
16580 })
16581
16582 ;; Conditional addition patterns
16583 (define_expand "add<mode>cc"
16584 [(match_operand:SWI 0 "register_operand")
16585 (match_operand 1 "ordered_comparison_operator")
16586 (match_operand:SWI 2 "register_operand")
16587 (match_operand:SWI 3 "const_int_operand")]
16588 ""
16589 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16590 \f
16591 ;; Misc patterns (?)
16592
16593 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16594 ;; Otherwise there will be nothing to keep
16595 ;;
16596 ;; [(set (reg ebp) (reg esp))]
16597 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16598 ;; (clobber (eflags)]
16599 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16600 ;;
16601 ;; in proper program order.
16602
16603 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16604 [(set (match_operand:P 0 "register_operand" "=r,r")
16605 (plus:P (match_operand:P 1 "register_operand" "0,r")
16606 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16607 (clobber (reg:CC FLAGS_REG))
16608 (clobber (mem:BLK (scratch)))]
16609 ""
16610 {
16611 switch (get_attr_type (insn))
16612 {
16613 case TYPE_IMOV:
16614 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16615
16616 case TYPE_ALU:
16617 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16618 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16619 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16620
16621 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16622
16623 default:
16624 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16625 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16626 }
16627 }
16628 [(set (attr "type")
16629 (cond [(and (eq_attr "alternative" "0")
16630 (not (match_test "TARGET_OPT_AGU")))
16631 (const_string "alu")
16632 (match_operand:<MODE> 2 "const0_operand")
16633 (const_string "imov")
16634 ]
16635 (const_string "lea")))
16636 (set (attr "length_immediate")
16637 (cond [(eq_attr "type" "imov")
16638 (const_string "0")
16639 (and (eq_attr "type" "alu")
16640 (match_operand 2 "const128_operand"))
16641 (const_string "1")
16642 ]
16643 (const_string "*")))
16644 (set_attr "mode" "<MODE>")])
16645
16646 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16647 [(set (match_operand:P 0 "register_operand" "=r")
16648 (minus:P (match_operand:P 1 "register_operand" "0")
16649 (match_operand:P 2 "register_operand" "r")))
16650 (clobber (reg:CC FLAGS_REG))
16651 (clobber (mem:BLK (scratch)))]
16652 ""
16653 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16654 [(set_attr "type" "alu")
16655 (set_attr "mode" "<MODE>")])
16656
16657 (define_insn "allocate_stack_worker_probe_<mode>"
16658 [(set (match_operand:P 0 "register_operand" "=a")
16659 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16660 UNSPECV_STACK_PROBE))
16661 (clobber (reg:CC FLAGS_REG))]
16662 "ix86_target_stack_probe ()"
16663 "call\t___chkstk_ms"
16664 [(set_attr "type" "multi")
16665 (set_attr "length" "5")])
16666
16667 (define_expand "allocate_stack"
16668 [(match_operand 0 "register_operand")
16669 (match_operand 1 "general_operand")]
16670 "ix86_target_stack_probe ()"
16671 {
16672 rtx x;
16673
16674 #ifndef CHECK_STACK_LIMIT
16675 #define CHECK_STACK_LIMIT 0
16676 #endif
16677
16678 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16679 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16680 x = operands[1];
16681 else
16682 {
16683 rtx (*insn) (rtx, rtx);
16684
16685 x = copy_to_mode_reg (Pmode, operands[1]);
16686
16687 insn = (TARGET_64BIT
16688 ? gen_allocate_stack_worker_probe_di
16689 : gen_allocate_stack_worker_probe_si);
16690
16691 emit_insn (insn (x, x));
16692 }
16693
16694 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16695 stack_pointer_rtx, 0, OPTAB_DIRECT);
16696
16697 if (x != stack_pointer_rtx)
16698 emit_move_insn (stack_pointer_rtx, x);
16699
16700 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16701 DONE;
16702 })
16703
16704 ;; Use IOR for stack probes, this is shorter.
16705 (define_expand "probe_stack"
16706 [(match_operand 0 "memory_operand")]
16707 ""
16708 {
16709 rtx (*gen_ior3) (rtx, rtx, rtx);
16710
16711 gen_ior3 = (GET_MODE (operands[0]) == DImode
16712 ? gen_iordi3 : gen_iorsi3);
16713
16714 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16715 DONE;
16716 })
16717
16718 (define_insn "adjust_stack_and_probe<mode>"
16719 [(set (match_operand:P 0 "register_operand" "=r")
16720 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16721 UNSPECV_PROBE_STACK_RANGE))
16722 (set (reg:P SP_REG)
16723 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16724 (clobber (reg:CC FLAGS_REG))
16725 (clobber (mem:BLK (scratch)))]
16726 ""
16727 "* return output_adjust_stack_and_probe (operands[0]);"
16728 [(set_attr "type" "multi")])
16729
16730 (define_insn "probe_stack_range<mode>"
16731 [(set (match_operand:P 0 "register_operand" "=r")
16732 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16733 (match_operand:P 2 "const_int_operand" "n")]
16734 UNSPECV_PROBE_STACK_RANGE))
16735 (clobber (reg:CC FLAGS_REG))]
16736 ""
16737 "* return output_probe_stack_range (operands[0], operands[2]);"
16738 [(set_attr "type" "multi")])
16739
16740 (define_expand "builtin_setjmp_receiver"
16741 [(label_ref (match_operand 0))]
16742 "!TARGET_64BIT && flag_pic"
16743 {
16744 #if TARGET_MACHO
16745 if (TARGET_MACHO)
16746 {
16747 rtx xops[3];
16748 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16749 rtx label_rtx = gen_label_rtx ();
16750 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16751 xops[0] = xops[1] = picreg;
16752 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16753 ix86_expand_binary_operator (MINUS, SImode, xops);
16754 }
16755 else
16756 #endif
16757 emit_insn (gen_set_got (pic_offset_table_rtx));
16758 DONE;
16759 })
16760 \f
16761 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16762
16763 (define_split
16764 [(set (match_operand 0 "register_operand")
16765 (match_operator 3 "promotable_binary_operator"
16766 [(match_operand 1 "register_operand")
16767 (match_operand 2 "aligned_operand")]))
16768 (clobber (reg:CC FLAGS_REG))]
16769 "! TARGET_PARTIAL_REG_STALL && reload_completed
16770 && ((GET_MODE (operands[0]) == HImode
16771 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16772 /* ??? next two lines just !satisfies_constraint_K (...) */
16773 || !CONST_INT_P (operands[2])
16774 || satisfies_constraint_K (operands[2])))
16775 || (GET_MODE (operands[0]) == QImode
16776 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16777 [(parallel [(set (match_dup 0)
16778 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16779 (clobber (reg:CC FLAGS_REG))])]
16780 {
16781 operands[0] = gen_lowpart (SImode, operands[0]);
16782 operands[1] = gen_lowpart (SImode, operands[1]);
16783 if (GET_CODE (operands[3]) != ASHIFT)
16784 operands[2] = gen_lowpart (SImode, operands[2]);
16785 PUT_MODE (operands[3], SImode);
16786 })
16787
16788 ; Promote the QImode tests, as i386 has encoding of the AND
16789 ; instruction with 32-bit sign-extended immediate and thus the
16790 ; instruction size is unchanged, except in the %eax case for
16791 ; which it is increased by one byte, hence the ! optimize_size.
16792 (define_split
16793 [(set (match_operand 0 "flags_reg_operand")
16794 (match_operator 2 "compare_operator"
16795 [(and (match_operand 3 "aligned_operand")
16796 (match_operand 4 "const_int_operand"))
16797 (const_int 0)]))
16798 (set (match_operand 1 "register_operand")
16799 (and (match_dup 3) (match_dup 4)))]
16800 "! TARGET_PARTIAL_REG_STALL && reload_completed
16801 && optimize_insn_for_speed_p ()
16802 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16803 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16804 /* Ensure that the operand will remain sign-extended immediate. */
16805 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16806 [(parallel [(set (match_dup 0)
16807 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16808 (const_int 0)]))
16809 (set (match_dup 1)
16810 (and:SI (match_dup 3) (match_dup 4)))])]
16811 {
16812 operands[4]
16813 = gen_int_mode (INTVAL (operands[4])
16814 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16815 operands[1] = gen_lowpart (SImode, operands[1]);
16816 operands[3] = gen_lowpart (SImode, operands[3]);
16817 })
16818
16819 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16820 ; the TEST instruction with 32-bit sign-extended immediate and thus
16821 ; the instruction size would at least double, which is not what we
16822 ; want even with ! optimize_size.
16823 (define_split
16824 [(set (match_operand 0 "flags_reg_operand")
16825 (match_operator 1 "compare_operator"
16826 [(and (match_operand:HI 2 "aligned_operand")
16827 (match_operand:HI 3 "const_int_operand"))
16828 (const_int 0)]))]
16829 "! TARGET_PARTIAL_REG_STALL && reload_completed
16830 && ! TARGET_FAST_PREFIX
16831 && optimize_insn_for_speed_p ()
16832 /* Ensure that the operand will remain sign-extended immediate. */
16833 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16834 [(set (match_dup 0)
16835 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16836 (const_int 0)]))]
16837 {
16838 operands[3]
16839 = gen_int_mode (INTVAL (operands[3])
16840 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16841 operands[2] = gen_lowpart (SImode, operands[2]);
16842 })
16843
16844 (define_split
16845 [(set (match_operand 0 "register_operand")
16846 (neg (match_operand 1 "register_operand")))
16847 (clobber (reg:CC FLAGS_REG))]
16848 "! TARGET_PARTIAL_REG_STALL && reload_completed
16849 && (GET_MODE (operands[0]) == HImode
16850 || (GET_MODE (operands[0]) == QImode
16851 && (TARGET_PROMOTE_QImode
16852 || optimize_insn_for_size_p ())))"
16853 [(parallel [(set (match_dup 0)
16854 (neg:SI (match_dup 1)))
16855 (clobber (reg:CC FLAGS_REG))])]
16856 {
16857 operands[0] = gen_lowpart (SImode, operands[0]);
16858 operands[1] = gen_lowpart (SImode, operands[1]);
16859 })
16860
16861 (define_split
16862 [(set (match_operand 0 "register_operand")
16863 (not (match_operand 1 "register_operand")))]
16864 "! TARGET_PARTIAL_REG_STALL && reload_completed
16865 && (GET_MODE (operands[0]) == HImode
16866 || (GET_MODE (operands[0]) == QImode
16867 && (TARGET_PROMOTE_QImode
16868 || optimize_insn_for_size_p ())))"
16869 [(set (match_dup 0)
16870 (not:SI (match_dup 1)))]
16871 {
16872 operands[0] = gen_lowpart (SImode, operands[0]);
16873 operands[1] = gen_lowpart (SImode, operands[1]);
16874 })
16875
16876 (define_split
16877 [(set (match_operand 0 "register_operand")
16878 (if_then_else (match_operator 1 "ordered_comparison_operator"
16879 [(reg FLAGS_REG) (const_int 0)])
16880 (match_operand 2 "register_operand")
16881 (match_operand 3 "register_operand")))]
16882 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16883 && (GET_MODE (operands[0]) == HImode
16884 || (GET_MODE (operands[0]) == QImode
16885 && (TARGET_PROMOTE_QImode
16886 || optimize_insn_for_size_p ())))"
16887 [(set (match_dup 0)
16888 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16889 {
16890 operands[0] = gen_lowpart (SImode, operands[0]);
16891 operands[2] = gen_lowpart (SImode, operands[2]);
16892 operands[3] = gen_lowpart (SImode, operands[3]);
16893 })
16894 \f
16895 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16896 ;; transform a complex memory operation into two memory to register operations.
16897
16898 ;; Don't push memory operands
16899 (define_peephole2
16900 [(set (match_operand:SWI 0 "push_operand")
16901 (match_operand:SWI 1 "memory_operand"))
16902 (match_scratch:SWI 2 "<r>")]
16903 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16904 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16905 [(set (match_dup 2) (match_dup 1))
16906 (set (match_dup 0) (match_dup 2))])
16907
16908 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16909 ;; SImode pushes.
16910 (define_peephole2
16911 [(set (match_operand:SF 0 "push_operand")
16912 (match_operand:SF 1 "memory_operand"))
16913 (match_scratch:SF 2 "r")]
16914 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16915 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16916 [(set (match_dup 2) (match_dup 1))
16917 (set (match_dup 0) (match_dup 2))])
16918
16919 ;; Don't move an immediate directly to memory when the instruction
16920 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16921 (define_peephole2
16922 [(match_scratch:SWI124 1 "<r>")
16923 (set (match_operand:SWI124 0 "memory_operand")
16924 (const_int 0))]
16925 "optimize_insn_for_speed_p ()
16926 && ((<MODE>mode == HImode
16927 && TARGET_LCP_STALL)
16928 || (!TARGET_USE_MOV0
16929 && TARGET_SPLIT_LONG_MOVES
16930 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16931 && peep2_regno_dead_p (0, FLAGS_REG)"
16932 [(parallel [(set (match_dup 2) (const_int 0))
16933 (clobber (reg:CC FLAGS_REG))])
16934 (set (match_dup 0) (match_dup 1))]
16935 "operands[2] = gen_lowpart (SImode, operands[1]);")
16936
16937 (define_peephole2
16938 [(match_scratch:SWI124 2 "<r>")
16939 (set (match_operand:SWI124 0 "memory_operand")
16940 (match_operand:SWI124 1 "immediate_operand"))]
16941 "optimize_insn_for_speed_p ()
16942 && ((<MODE>mode == HImode
16943 && TARGET_LCP_STALL)
16944 || (TARGET_SPLIT_LONG_MOVES
16945 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16946 [(set (match_dup 2) (match_dup 1))
16947 (set (match_dup 0) (match_dup 2))])
16948
16949 ;; Don't compare memory with zero, load and use a test instead.
16950 (define_peephole2
16951 [(set (match_operand 0 "flags_reg_operand")
16952 (match_operator 1 "compare_operator"
16953 [(match_operand:SI 2 "memory_operand")
16954 (const_int 0)]))
16955 (match_scratch:SI 3 "r")]
16956 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16957 [(set (match_dup 3) (match_dup 2))
16958 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16959
16960 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16961 ;; Don't split NOTs with a displacement operand, because resulting XOR
16962 ;; will not be pairable anyway.
16963 ;;
16964 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16965 ;; represented using a modRM byte. The XOR replacement is long decoded,
16966 ;; so this split helps here as well.
16967 ;;
16968 ;; Note: Can't do this as a regular split because we can't get proper
16969 ;; lifetime information then.
16970
16971 (define_peephole2
16972 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16973 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16974 "optimize_insn_for_speed_p ()
16975 && ((TARGET_NOT_UNPAIRABLE
16976 && (!MEM_P (operands[0])
16977 || !memory_displacement_operand (operands[0], <MODE>mode)))
16978 || (TARGET_NOT_VECTORMODE
16979 && long_memory_operand (operands[0], <MODE>mode)))
16980 && peep2_regno_dead_p (0, FLAGS_REG)"
16981 [(parallel [(set (match_dup 0)
16982 (xor:SWI124 (match_dup 1) (const_int -1)))
16983 (clobber (reg:CC FLAGS_REG))])])
16984
16985 ;; Non pairable "test imm, reg" instructions can be translated to
16986 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16987 ;; byte opcode instead of two, have a short form for byte operands),
16988 ;; so do it for other CPUs as well. Given that the value was dead,
16989 ;; this should not create any new dependencies. Pass on the sub-word
16990 ;; versions if we're concerned about partial register stalls.
16991
16992 (define_peephole2
16993 [(set (match_operand 0 "flags_reg_operand")
16994 (match_operator 1 "compare_operator"
16995 [(and:SI (match_operand:SI 2 "register_operand")
16996 (match_operand:SI 3 "immediate_operand"))
16997 (const_int 0)]))]
16998 "ix86_match_ccmode (insn, CCNOmode)
16999 && (true_regnum (operands[2]) != AX_REG
17000 || satisfies_constraint_K (operands[3]))
17001 && peep2_reg_dead_p (1, operands[2])"
17002 [(parallel
17003 [(set (match_dup 0)
17004 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17005 (const_int 0)]))
17006 (set (match_dup 2)
17007 (and:SI (match_dup 2) (match_dup 3)))])])
17008
17009 ;; We don't need to handle HImode case, because it will be promoted to SImode
17010 ;; on ! TARGET_PARTIAL_REG_STALL
17011
17012 (define_peephole2
17013 [(set (match_operand 0 "flags_reg_operand")
17014 (match_operator 1 "compare_operator"
17015 [(and:QI (match_operand:QI 2 "register_operand")
17016 (match_operand:QI 3 "immediate_operand"))
17017 (const_int 0)]))]
17018 "! TARGET_PARTIAL_REG_STALL
17019 && ix86_match_ccmode (insn, CCNOmode)
17020 && true_regnum (operands[2]) != AX_REG
17021 && peep2_reg_dead_p (1, operands[2])"
17022 [(parallel
17023 [(set (match_dup 0)
17024 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17025 (const_int 0)]))
17026 (set (match_dup 2)
17027 (and:QI (match_dup 2) (match_dup 3)))])])
17028
17029 (define_peephole2
17030 [(set (match_operand 0 "flags_reg_operand")
17031 (match_operator 1 "compare_operator"
17032 [(and:SI
17033 (zero_extract:SI
17034 (match_operand 2 "ext_register_operand")
17035 (const_int 8)
17036 (const_int 8))
17037 (match_operand 3 "const_int_operand"))
17038 (const_int 0)]))]
17039 "! TARGET_PARTIAL_REG_STALL
17040 && ix86_match_ccmode (insn, CCNOmode)
17041 && true_regnum (operands[2]) != AX_REG
17042 && peep2_reg_dead_p (1, operands[2])"
17043 [(parallel [(set (match_dup 0)
17044 (match_op_dup 1
17045 [(and:SI
17046 (zero_extract:SI
17047 (match_dup 2)
17048 (const_int 8)
17049 (const_int 8))
17050 (match_dup 3))
17051 (const_int 0)]))
17052 (set (zero_extract:SI (match_dup 2)
17053 (const_int 8)
17054 (const_int 8))
17055 (and:SI
17056 (zero_extract:SI
17057 (match_dup 2)
17058 (const_int 8)
17059 (const_int 8))
17060 (match_dup 3)))])])
17061
17062 ;; Don't do logical operations with memory inputs.
17063 (define_peephole2
17064 [(match_scratch:SI 2 "r")
17065 (parallel [(set (match_operand:SI 0 "register_operand")
17066 (match_operator:SI 3 "arith_or_logical_operator"
17067 [(match_dup 0)
17068 (match_operand:SI 1 "memory_operand")]))
17069 (clobber (reg:CC FLAGS_REG))])]
17070 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17071 [(set (match_dup 2) (match_dup 1))
17072 (parallel [(set (match_dup 0)
17073 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17074 (clobber (reg:CC FLAGS_REG))])])
17075
17076 (define_peephole2
17077 [(match_scratch:SI 2 "r")
17078 (parallel [(set (match_operand:SI 0 "register_operand")
17079 (match_operator:SI 3 "arith_or_logical_operator"
17080 [(match_operand:SI 1 "memory_operand")
17081 (match_dup 0)]))
17082 (clobber (reg:CC FLAGS_REG))])]
17083 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17084 [(set (match_dup 2) (match_dup 1))
17085 (parallel [(set (match_dup 0)
17086 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17087 (clobber (reg:CC FLAGS_REG))])])
17088
17089 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17090 ;; refers to the destination of the load!
17091
17092 (define_peephole2
17093 [(set (match_operand:SI 0 "register_operand")
17094 (match_operand:SI 1 "register_operand"))
17095 (parallel [(set (match_dup 0)
17096 (match_operator:SI 3 "commutative_operator"
17097 [(match_dup 0)
17098 (match_operand:SI 2 "memory_operand")]))
17099 (clobber (reg:CC FLAGS_REG))])]
17100 "REGNO (operands[0]) != REGNO (operands[1])
17101 && GENERAL_REGNO_P (REGNO (operands[0]))
17102 && GENERAL_REGNO_P (REGNO (operands[1]))"
17103 [(set (match_dup 0) (match_dup 4))
17104 (parallel [(set (match_dup 0)
17105 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17106 (clobber (reg:CC FLAGS_REG))])]
17107 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17108
17109 (define_peephole2
17110 [(set (match_operand 0 "register_operand")
17111 (match_operand 1 "register_operand"))
17112 (set (match_dup 0)
17113 (match_operator 3 "commutative_operator"
17114 [(match_dup 0)
17115 (match_operand 2 "memory_operand")]))]
17116 "REGNO (operands[0]) != REGNO (operands[1])
17117 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17118 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17119 [(set (match_dup 0) (match_dup 2))
17120 (set (match_dup 0)
17121 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17122
17123 ; Don't do logical operations with memory outputs
17124 ;
17125 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17126 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17127 ; the same decoder scheduling characteristics as the original.
17128
17129 (define_peephole2
17130 [(match_scratch:SI 2 "r")
17131 (parallel [(set (match_operand:SI 0 "memory_operand")
17132 (match_operator:SI 3 "arith_or_logical_operator"
17133 [(match_dup 0)
17134 (match_operand:SI 1 "nonmemory_operand")]))
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17137 /* Do not split stack checking probes. */
17138 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17139 [(set (match_dup 2) (match_dup 0))
17140 (parallel [(set (match_dup 2)
17141 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17142 (clobber (reg:CC FLAGS_REG))])
17143 (set (match_dup 0) (match_dup 2))])
17144
17145 (define_peephole2
17146 [(match_scratch:SI 2 "r")
17147 (parallel [(set (match_operand:SI 0 "memory_operand")
17148 (match_operator:SI 3 "arith_or_logical_operator"
17149 [(match_operand:SI 1 "nonmemory_operand")
17150 (match_dup 0)]))
17151 (clobber (reg:CC FLAGS_REG))])]
17152 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17153 /* Do not split stack checking probes. */
17154 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17155 [(set (match_dup 2) (match_dup 0))
17156 (parallel [(set (match_dup 2)
17157 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17158 (clobber (reg:CC FLAGS_REG))])
17159 (set (match_dup 0) (match_dup 2))])
17160
17161 ;; Attempt to use arith or logical operations with memory outputs with
17162 ;; setting of flags.
17163 (define_peephole2
17164 [(set (match_operand:SWI 0 "register_operand")
17165 (match_operand:SWI 1 "memory_operand"))
17166 (parallel [(set (match_dup 0)
17167 (match_operator:SWI 3 "plusminuslogic_operator"
17168 [(match_dup 0)
17169 (match_operand:SWI 2 "<nonmemory_operand>")]))
17170 (clobber (reg:CC FLAGS_REG))])
17171 (set (match_dup 1) (match_dup 0))
17172 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17173 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17174 && peep2_reg_dead_p (4, operands[0])
17175 && !reg_overlap_mentioned_p (operands[0], operands[1])
17176 && (<MODE>mode != QImode
17177 || immediate_operand (operands[2], QImode)
17178 || q_regs_operand (operands[2], QImode))
17179 && ix86_match_ccmode (peep2_next_insn (3),
17180 (GET_CODE (operands[3]) == PLUS
17181 || GET_CODE (operands[3]) == MINUS)
17182 ? CCGOCmode : CCNOmode)"
17183 [(parallel [(set (match_dup 4) (match_dup 5))
17184 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17185 (match_dup 2)]))])]
17186 {
17187 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17188 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17189 copy_rtx (operands[1]),
17190 copy_rtx (operands[2]));
17191 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17192 operands[5], const0_rtx);
17193 })
17194
17195 (define_peephole2
17196 [(parallel [(set (match_operand:SWI 0 "register_operand")
17197 (match_operator:SWI 2 "plusminuslogic_operator"
17198 [(match_dup 0)
17199 (match_operand:SWI 1 "memory_operand")]))
17200 (clobber (reg:CC FLAGS_REG))])
17201 (set (match_dup 1) (match_dup 0))
17202 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17203 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17204 && GET_CODE (operands[2]) != MINUS
17205 && peep2_reg_dead_p (3, operands[0])
17206 && !reg_overlap_mentioned_p (operands[0], operands[1])
17207 && ix86_match_ccmode (peep2_next_insn (2),
17208 GET_CODE (operands[2]) == PLUS
17209 ? CCGOCmode : CCNOmode)"
17210 [(parallel [(set (match_dup 3) (match_dup 4))
17211 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17212 (match_dup 0)]))])]
17213 {
17214 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17215 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17216 copy_rtx (operands[1]),
17217 copy_rtx (operands[0]));
17218 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17219 operands[4], const0_rtx);
17220 })
17221
17222 (define_peephole2
17223 [(set (match_operand:SWI12 0 "register_operand")
17224 (match_operand:SWI12 1 "memory_operand"))
17225 (parallel [(set (match_operand:SI 4 "register_operand")
17226 (match_operator:SI 3 "plusminuslogic_operator"
17227 [(match_dup 4)
17228 (match_operand:SI 2 "nonmemory_operand")]))
17229 (clobber (reg:CC FLAGS_REG))])
17230 (set (match_dup 1) (match_dup 0))
17231 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17232 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17233 && REG_P (operands[0]) && REG_P (operands[4])
17234 && REGNO (operands[0]) == REGNO (operands[4])
17235 && peep2_reg_dead_p (4, operands[0])
17236 && (<MODE>mode != QImode
17237 || immediate_operand (operands[2], SImode)
17238 || q_regs_operand (operands[2], SImode))
17239 && !reg_overlap_mentioned_p (operands[0], operands[1])
17240 && ix86_match_ccmode (peep2_next_insn (3),
17241 (GET_CODE (operands[3]) == PLUS
17242 || GET_CODE (operands[3]) == MINUS)
17243 ? CCGOCmode : CCNOmode)"
17244 [(parallel [(set (match_dup 4) (match_dup 5))
17245 (set (match_dup 1) (match_dup 6))])]
17246 {
17247 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17248 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17249 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17250 copy_rtx (operands[1]), operands[2]);
17251 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17252 operands[5], const0_rtx);
17253 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17254 copy_rtx (operands[1]),
17255 copy_rtx (operands[2]));
17256 })
17257
17258 ;; Attempt to always use XOR for zeroing registers.
17259 (define_peephole2
17260 [(set (match_operand 0 "register_operand")
17261 (match_operand 1 "const0_operand"))]
17262 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17263 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17264 && GENERAL_REG_P (operands[0])
17265 && peep2_regno_dead_p (0, FLAGS_REG)"
17266 [(parallel [(set (match_dup 0) (const_int 0))
17267 (clobber (reg:CC FLAGS_REG))])]
17268 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17269
17270 (define_peephole2
17271 [(set (strict_low_part (match_operand 0 "register_operand"))
17272 (const_int 0))]
17273 "(GET_MODE (operands[0]) == QImode
17274 || GET_MODE (operands[0]) == HImode)
17275 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17276 && peep2_regno_dead_p (0, FLAGS_REG)"
17277 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17278 (clobber (reg:CC FLAGS_REG))])])
17279
17280 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17281 (define_peephole2
17282 [(set (match_operand:SWI248 0 "register_operand")
17283 (const_int -1))]
17284 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17285 && peep2_regno_dead_p (0, FLAGS_REG)"
17286 [(parallel [(set (match_dup 0) (const_int -1))
17287 (clobber (reg:CC FLAGS_REG))])]
17288 {
17289 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17290 operands[0] = gen_lowpart (SImode, operands[0]);
17291 })
17292
17293 ;; Attempt to convert simple lea to add/shift.
17294 ;; These can be created by move expanders.
17295
17296 (define_peephole2
17297 [(set (match_operand:SWI48 0 "register_operand")
17298 (plus:SWI48 (match_dup 0)
17299 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17300 "peep2_regno_dead_p (0, FLAGS_REG)"
17301 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17302 (clobber (reg:CC FLAGS_REG))])])
17303
17304 (define_peephole2
17305 [(set (match_operand:SI 0 "register_operand")
17306 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17307 (match_operand:DI 2 "nonmemory_operand")) 0))]
17308 "TARGET_64BIT
17309 && peep2_regno_dead_p (0, FLAGS_REG)
17310 && REGNO (operands[0]) == REGNO (operands[1])"
17311 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17312 (clobber (reg:CC FLAGS_REG))])]
17313 "operands[2] = gen_lowpart (SImode, operands[2]);")
17314
17315 (define_peephole2
17316 [(set (match_operand:SWI48 0 "register_operand")
17317 (mult:SWI48 (match_dup 0)
17318 (match_operand:SWI48 1 "const_int_operand")))]
17319 "exact_log2 (INTVAL (operands[1])) >= 0
17320 && peep2_regno_dead_p (0, FLAGS_REG)"
17321 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17322 (clobber (reg:CC FLAGS_REG))])]
17323 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17324
17325 (define_peephole2
17326 [(set (match_operand:SI 0 "register_operand")
17327 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17328 (match_operand:DI 2 "const_int_operand")) 0))]
17329 "TARGET_64BIT
17330 && exact_log2 (INTVAL (operands[2])) >= 0
17331 && REGNO (operands[0]) == REGNO (operands[1])
17332 && peep2_regno_dead_p (0, FLAGS_REG)"
17333 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17334 (clobber (reg:CC FLAGS_REG))])]
17335 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17336
17337 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17338 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17339 ;; On many CPUs it is also faster, since special hardware to avoid esp
17340 ;; dependencies is present.
17341
17342 ;; While some of these conversions may be done using splitters, we use
17343 ;; peepholes in order to allow combine_stack_adjustments pass to see
17344 ;; nonobfuscated RTL.
17345
17346 ;; Convert prologue esp subtractions to push.
17347 ;; We need register to push. In order to keep verify_flow_info happy we have
17348 ;; two choices
17349 ;; - use scratch and clobber it in order to avoid dependencies
17350 ;; - use already live register
17351 ;; We can't use the second way right now, since there is no reliable way how to
17352 ;; verify that given register is live. First choice will also most likely in
17353 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17354 ;; call clobbered registers are dead. We may want to use base pointer as an
17355 ;; alternative when no register is available later.
17356
17357 (define_peephole2
17358 [(match_scratch:W 1 "r")
17359 (parallel [(set (reg:P SP_REG)
17360 (plus:P (reg:P SP_REG)
17361 (match_operand:P 0 "const_int_operand")))
17362 (clobber (reg:CC FLAGS_REG))
17363 (clobber (mem:BLK (scratch)))])]
17364 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17365 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17366 [(clobber (match_dup 1))
17367 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17368 (clobber (mem:BLK (scratch)))])])
17369
17370 (define_peephole2
17371 [(match_scratch:W 1 "r")
17372 (parallel [(set (reg:P SP_REG)
17373 (plus:P (reg:P SP_REG)
17374 (match_operand:P 0 "const_int_operand")))
17375 (clobber (reg:CC FLAGS_REG))
17376 (clobber (mem:BLK (scratch)))])]
17377 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17378 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17379 [(clobber (match_dup 1))
17380 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17381 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17382 (clobber (mem:BLK (scratch)))])])
17383
17384 ;; Convert esp subtractions to push.
17385 (define_peephole2
17386 [(match_scratch:W 1 "r")
17387 (parallel [(set (reg:P SP_REG)
17388 (plus:P (reg:P SP_REG)
17389 (match_operand:P 0 "const_int_operand")))
17390 (clobber (reg:CC FLAGS_REG))])]
17391 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17392 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17393 [(clobber (match_dup 1))
17394 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17395
17396 (define_peephole2
17397 [(match_scratch:W 1 "r")
17398 (parallel [(set (reg:P SP_REG)
17399 (plus:P (reg:P SP_REG)
17400 (match_operand:P 0 "const_int_operand")))
17401 (clobber (reg:CC FLAGS_REG))])]
17402 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17403 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17404 [(clobber (match_dup 1))
17405 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17406 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17407
17408 ;; Convert epilogue deallocator to pop.
17409 (define_peephole2
17410 [(match_scratch:W 1 "r")
17411 (parallel [(set (reg:P SP_REG)
17412 (plus:P (reg:P SP_REG)
17413 (match_operand:P 0 "const_int_operand")))
17414 (clobber (reg:CC FLAGS_REG))
17415 (clobber (mem:BLK (scratch)))])]
17416 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17417 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17418 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17419 (clobber (mem:BLK (scratch)))])])
17420
17421 ;; Two pops case is tricky, since pop causes dependency
17422 ;; on destination register. We use two registers if available.
17423 (define_peephole2
17424 [(match_scratch:W 1 "r")
17425 (match_scratch:W 2 "r")
17426 (parallel [(set (reg:P SP_REG)
17427 (plus:P (reg:P SP_REG)
17428 (match_operand:P 0 "const_int_operand")))
17429 (clobber (reg:CC FLAGS_REG))
17430 (clobber (mem:BLK (scratch)))])]
17431 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17432 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17433 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17434 (clobber (mem:BLK (scratch)))])
17435 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17436
17437 (define_peephole2
17438 [(match_scratch:W 1 "r")
17439 (parallel [(set (reg:P SP_REG)
17440 (plus:P (reg:P SP_REG)
17441 (match_operand:P 0 "const_int_operand")))
17442 (clobber (reg:CC FLAGS_REG))
17443 (clobber (mem:BLK (scratch)))])]
17444 "optimize_insn_for_size_p ()
17445 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17446 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17447 (clobber (mem:BLK (scratch)))])
17448 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17449
17450 ;; Convert esp additions to pop.
17451 (define_peephole2
17452 [(match_scratch:W 1 "r")
17453 (parallel [(set (reg:P SP_REG)
17454 (plus:P (reg:P SP_REG)
17455 (match_operand:P 0 "const_int_operand")))
17456 (clobber (reg:CC FLAGS_REG))])]
17457 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17458 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17459
17460 ;; Two pops case is tricky, since pop causes dependency
17461 ;; on destination register. We use two registers if available.
17462 (define_peephole2
17463 [(match_scratch:W 1 "r")
17464 (match_scratch:W 2 "r")
17465 (parallel [(set (reg:P SP_REG)
17466 (plus:P (reg:P SP_REG)
17467 (match_operand:P 0 "const_int_operand")))
17468 (clobber (reg:CC FLAGS_REG))])]
17469 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17470 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17471 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17472
17473 (define_peephole2
17474 [(match_scratch:W 1 "r")
17475 (parallel [(set (reg:P SP_REG)
17476 (plus:P (reg:P SP_REG)
17477 (match_operand:P 0 "const_int_operand")))
17478 (clobber (reg:CC FLAGS_REG))])]
17479 "optimize_insn_for_size_p ()
17480 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17481 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17482 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17483 \f
17484 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17485 ;; required and register dies. Similarly for 128 to -128.
17486 (define_peephole2
17487 [(set (match_operand 0 "flags_reg_operand")
17488 (match_operator 1 "compare_operator"
17489 [(match_operand 2 "register_operand")
17490 (match_operand 3 "const_int_operand")]))]
17491 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17492 && incdec_operand (operands[3], GET_MODE (operands[3])))
17493 || (!TARGET_FUSE_CMP_AND_BRANCH
17494 && INTVAL (operands[3]) == 128))
17495 && ix86_match_ccmode (insn, CCGCmode)
17496 && peep2_reg_dead_p (1, operands[2])"
17497 [(parallel [(set (match_dup 0)
17498 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17499 (clobber (match_dup 2))])])
17500 \f
17501 ;; Convert imul by three, five and nine into lea
17502 (define_peephole2
17503 [(parallel
17504 [(set (match_operand:SWI48 0 "register_operand")
17505 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17506 (match_operand:SWI48 2 "const359_operand")))
17507 (clobber (reg:CC FLAGS_REG))])]
17508 "!TARGET_PARTIAL_REG_STALL
17509 || <MODE>mode == SImode
17510 || optimize_function_for_size_p (cfun)"
17511 [(set (match_dup 0)
17512 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17513 (match_dup 1)))]
17514 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17515
17516 (define_peephole2
17517 [(parallel
17518 [(set (match_operand:SWI48 0 "register_operand")
17519 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17520 (match_operand:SWI48 2 "const359_operand")))
17521 (clobber (reg:CC FLAGS_REG))])]
17522 "optimize_insn_for_speed_p ()
17523 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17524 [(set (match_dup 0) (match_dup 1))
17525 (set (match_dup 0)
17526 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17527 (match_dup 0)))]
17528 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17529
17530 ;; imul $32bit_imm, mem, reg is vector decoded, while
17531 ;; imul $32bit_imm, reg, reg is direct decoded.
17532 (define_peephole2
17533 [(match_scratch:SWI48 3 "r")
17534 (parallel [(set (match_operand:SWI48 0 "register_operand")
17535 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17536 (match_operand:SWI48 2 "immediate_operand")))
17537 (clobber (reg:CC FLAGS_REG))])]
17538 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17539 && !satisfies_constraint_K (operands[2])"
17540 [(set (match_dup 3) (match_dup 1))
17541 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17542 (clobber (reg:CC FLAGS_REG))])])
17543
17544 (define_peephole2
17545 [(match_scratch:SI 3 "r")
17546 (parallel [(set (match_operand:DI 0 "register_operand")
17547 (zero_extend:DI
17548 (mult:SI (match_operand:SI 1 "memory_operand")
17549 (match_operand:SI 2 "immediate_operand"))))
17550 (clobber (reg:CC FLAGS_REG))])]
17551 "TARGET_64BIT
17552 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17553 && !satisfies_constraint_K (operands[2])"
17554 [(set (match_dup 3) (match_dup 1))
17555 (parallel [(set (match_dup 0)
17556 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17557 (clobber (reg:CC FLAGS_REG))])])
17558
17559 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17560 ;; Convert it into imul reg, reg
17561 ;; It would be better to force assembler to encode instruction using long
17562 ;; immediate, but there is apparently no way to do so.
17563 (define_peephole2
17564 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17565 (mult:SWI248
17566 (match_operand:SWI248 1 "nonimmediate_operand")
17567 (match_operand:SWI248 2 "const_int_operand")))
17568 (clobber (reg:CC FLAGS_REG))])
17569 (match_scratch:SWI248 3 "r")]
17570 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17571 && satisfies_constraint_K (operands[2])"
17572 [(set (match_dup 3) (match_dup 2))
17573 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17574 (clobber (reg:CC FLAGS_REG))])]
17575 {
17576 if (!rtx_equal_p (operands[0], operands[1]))
17577 emit_move_insn (operands[0], operands[1]);
17578 })
17579
17580 ;; After splitting up read-modify operations, array accesses with memory
17581 ;; operands might end up in form:
17582 ;; sall $2, %eax
17583 ;; movl 4(%esp), %edx
17584 ;; addl %edx, %eax
17585 ;; instead of pre-splitting:
17586 ;; sall $2, %eax
17587 ;; addl 4(%esp), %eax
17588 ;; Turn it into:
17589 ;; movl 4(%esp), %edx
17590 ;; leal (%edx,%eax,4), %eax
17591
17592 (define_peephole2
17593 [(match_scratch:W 5 "r")
17594 (parallel [(set (match_operand 0 "register_operand")
17595 (ashift (match_operand 1 "register_operand")
17596 (match_operand 2 "const_int_operand")))
17597 (clobber (reg:CC FLAGS_REG))])
17598 (parallel [(set (match_operand 3 "register_operand")
17599 (plus (match_dup 0)
17600 (match_operand 4 "x86_64_general_operand")))
17601 (clobber (reg:CC FLAGS_REG))])]
17602 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17603 /* Validate MODE for lea. */
17604 && ((!TARGET_PARTIAL_REG_STALL
17605 && (GET_MODE (operands[0]) == QImode
17606 || GET_MODE (operands[0]) == HImode))
17607 || GET_MODE (operands[0]) == SImode
17608 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17609 && (rtx_equal_p (operands[0], operands[3])
17610 || peep2_reg_dead_p (2, operands[0]))
17611 /* We reorder load and the shift. */
17612 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17613 [(set (match_dup 5) (match_dup 4))
17614 (set (match_dup 0) (match_dup 1))]
17615 {
17616 enum machine_mode op1mode = GET_MODE (operands[1]);
17617 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17618 int scale = 1 << INTVAL (operands[2]);
17619 rtx index = gen_lowpart (word_mode, operands[1]);
17620 rtx base = gen_lowpart (word_mode, operands[5]);
17621 rtx dest = gen_lowpart (mode, operands[3]);
17622
17623 operands[1] = gen_rtx_PLUS (word_mode, base,
17624 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17625 operands[5] = base;
17626 if (mode != word_mode)
17627 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17628 if (op1mode != word_mode)
17629 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17630 operands[0] = dest;
17631 })
17632 \f
17633 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17634 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17635 ;; caught for use by garbage collectors and the like. Using an insn that
17636 ;; maps to SIGILL makes it more likely the program will rightfully die.
17637 ;; Keeping with tradition, "6" is in honor of #UD.
17638 (define_insn "trap"
17639 [(trap_if (const_int 1) (const_int 6))]
17640 ""
17641 { return ASM_SHORT "0x0b0f"; }
17642 [(set_attr "length" "2")])
17643
17644 (define_expand "prefetch"
17645 [(prefetch (match_operand 0 "address_operand")
17646 (match_operand:SI 1 "const_int_operand")
17647 (match_operand:SI 2 "const_int_operand"))]
17648 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17649 {
17650 int rw = INTVAL (operands[1]);
17651 int locality = INTVAL (operands[2]);
17652
17653 gcc_assert (rw == 0 || rw == 1);
17654 gcc_assert (locality >= 0 && locality <= 3);
17655 gcc_assert (GET_MODE (operands[0]) == Pmode
17656 || GET_MODE (operands[0]) == VOIDmode);
17657
17658 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17659 supported by SSE counterpart or the SSE prefetch is not available
17660 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17661 of locality. */
17662 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17663 operands[2] = GEN_INT (3);
17664 else
17665 operands[1] = const0_rtx;
17666 })
17667
17668 (define_insn "*prefetch_sse_<mode>"
17669 [(prefetch (match_operand:P 0 "address_operand" "p")
17670 (const_int 0)
17671 (match_operand:SI 1 "const_int_operand"))]
17672 "TARGET_PREFETCH_SSE"
17673 {
17674 static const char * const patterns[4] = {
17675 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17676 };
17677
17678 int locality = INTVAL (operands[1]);
17679 gcc_assert (locality >= 0 && locality <= 3);
17680
17681 return patterns[locality];
17682 }
17683 [(set_attr "type" "sse")
17684 (set_attr "atom_sse_attr" "prefetch")
17685 (set (attr "length_address")
17686 (symbol_ref "memory_address_length (operands[0])"))
17687 (set_attr "memory" "none")])
17688
17689 (define_insn "*prefetch_3dnow_<mode>"
17690 [(prefetch (match_operand:P 0 "address_operand" "p")
17691 (match_operand:SI 1 "const_int_operand" "n")
17692 (const_int 3))]
17693 "TARGET_3DNOW"
17694 {
17695 if (INTVAL (operands[1]) == 0)
17696 return "prefetch\t%a0";
17697 else
17698 return "prefetchw\t%a0";
17699 }
17700 [(set_attr "type" "mmx")
17701 (set (attr "length_address")
17702 (symbol_ref "memory_address_length (operands[0])"))
17703 (set_attr "memory" "none")])
17704
17705 (define_expand "stack_protect_set"
17706 [(match_operand 0 "memory_operand")
17707 (match_operand 1 "memory_operand")]
17708 ""
17709 {
17710 rtx (*insn)(rtx, rtx);
17711
17712 #ifdef TARGET_THREAD_SSP_OFFSET
17713 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17714 insn = (TARGET_LP64
17715 ? gen_stack_tls_protect_set_di
17716 : gen_stack_tls_protect_set_si);
17717 #else
17718 insn = (TARGET_LP64
17719 ? gen_stack_protect_set_di
17720 : gen_stack_protect_set_si);
17721 #endif
17722
17723 emit_insn (insn (operands[0], operands[1]));
17724 DONE;
17725 })
17726
17727 (define_insn "stack_protect_set_<mode>"
17728 [(set (match_operand:PTR 0 "memory_operand" "=m")
17729 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17730 UNSPEC_SP_SET))
17731 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17732 (clobber (reg:CC FLAGS_REG))]
17733 ""
17734 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17735 [(set_attr "type" "multi")])
17736
17737 (define_insn "stack_tls_protect_set_<mode>"
17738 [(set (match_operand:PTR 0 "memory_operand" "=m")
17739 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17740 UNSPEC_SP_TLS_SET))
17741 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17742 (clobber (reg:CC FLAGS_REG))]
17743 ""
17744 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17745 [(set_attr "type" "multi")])
17746
17747 (define_expand "stack_protect_test"
17748 [(match_operand 0 "memory_operand")
17749 (match_operand 1 "memory_operand")
17750 (match_operand 2)]
17751 ""
17752 {
17753 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17754
17755 rtx (*insn)(rtx, rtx, rtx);
17756
17757 #ifdef TARGET_THREAD_SSP_OFFSET
17758 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17759 insn = (TARGET_LP64
17760 ? gen_stack_tls_protect_test_di
17761 : gen_stack_tls_protect_test_si);
17762 #else
17763 insn = (TARGET_LP64
17764 ? gen_stack_protect_test_di
17765 : gen_stack_protect_test_si);
17766 #endif
17767
17768 emit_insn (insn (flags, operands[0], operands[1]));
17769
17770 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17771 flags, const0_rtx, operands[2]));
17772 DONE;
17773 })
17774
17775 (define_insn "stack_protect_test_<mode>"
17776 [(set (match_operand:CCZ 0 "flags_reg_operand")
17777 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17778 (match_operand:PTR 2 "memory_operand" "m")]
17779 UNSPEC_SP_TEST))
17780 (clobber (match_scratch:PTR 3 "=&r"))]
17781 ""
17782 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17783 [(set_attr "type" "multi")])
17784
17785 (define_insn "stack_tls_protect_test_<mode>"
17786 [(set (match_operand:CCZ 0 "flags_reg_operand")
17787 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17788 (match_operand:PTR 2 "const_int_operand" "i")]
17789 UNSPEC_SP_TLS_TEST))
17790 (clobber (match_scratch:PTR 3 "=r"))]
17791 ""
17792 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17793 [(set_attr "type" "multi")])
17794
17795 (define_insn "sse4_2_crc32<mode>"
17796 [(set (match_operand:SI 0 "register_operand" "=r")
17797 (unspec:SI
17798 [(match_operand:SI 1 "register_operand" "0")
17799 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17800 UNSPEC_CRC32))]
17801 "TARGET_SSE4_2 || TARGET_CRC32"
17802 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17803 [(set_attr "type" "sselog1")
17804 (set_attr "prefix_rep" "1")
17805 (set_attr "prefix_extra" "1")
17806 (set (attr "prefix_data16")
17807 (if_then_else (match_operand:HI 2)
17808 (const_string "1")
17809 (const_string "*")))
17810 (set (attr "prefix_rex")
17811 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17812 (const_string "1")
17813 (const_string "*")))
17814 (set_attr "mode" "SI")])
17815
17816 (define_insn "sse4_2_crc32di"
17817 [(set (match_operand:DI 0 "register_operand" "=r")
17818 (unspec:DI
17819 [(match_operand:DI 1 "register_operand" "0")
17820 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17821 UNSPEC_CRC32))]
17822 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17823 "crc32{q}\t{%2, %0|%0, %2}"
17824 [(set_attr "type" "sselog1")
17825 (set_attr "prefix_rep" "1")
17826 (set_attr "prefix_extra" "1")
17827 (set_attr "mode" "DI")])
17828
17829 (define_expand "rdpmc"
17830 [(match_operand:DI 0 "register_operand")
17831 (match_operand:SI 1 "register_operand")]
17832 ""
17833 {
17834 rtx reg = gen_reg_rtx (DImode);
17835 rtx si;
17836
17837 /* Force operand 1 into ECX. */
17838 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17839 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17840 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17841 UNSPECV_RDPMC);
17842
17843 if (TARGET_64BIT)
17844 {
17845 rtvec vec = rtvec_alloc (2);
17846 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17847 rtx upper = gen_reg_rtx (DImode);
17848 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17849 gen_rtvec (1, const0_rtx),
17850 UNSPECV_RDPMC);
17851 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17852 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17853 emit_insn (load);
17854 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17855 NULL, 1, OPTAB_DIRECT);
17856 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17857 OPTAB_DIRECT);
17858 }
17859 else
17860 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17861 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17862 DONE;
17863 })
17864
17865 (define_insn "*rdpmc"
17866 [(set (match_operand:DI 0 "register_operand" "=A")
17867 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17868 UNSPECV_RDPMC))]
17869 "!TARGET_64BIT"
17870 "rdpmc"
17871 [(set_attr "type" "other")
17872 (set_attr "length" "2")])
17873
17874 (define_insn "*rdpmc_rex64"
17875 [(set (match_operand:DI 0 "register_operand" "=a")
17876 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17877 UNSPECV_RDPMC))
17878 (set (match_operand:DI 1 "register_operand" "=d")
17879 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17880 "TARGET_64BIT"
17881 "rdpmc"
17882 [(set_attr "type" "other")
17883 (set_attr "length" "2")])
17884
17885 (define_expand "rdtsc"
17886 [(set (match_operand:DI 0 "register_operand")
17887 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17888 ""
17889 {
17890 if (TARGET_64BIT)
17891 {
17892 rtvec vec = rtvec_alloc (2);
17893 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17894 rtx upper = gen_reg_rtx (DImode);
17895 rtx lower = gen_reg_rtx (DImode);
17896 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17897 gen_rtvec (1, const0_rtx),
17898 UNSPECV_RDTSC);
17899 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17900 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17901 emit_insn (load);
17902 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17903 NULL, 1, OPTAB_DIRECT);
17904 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17905 OPTAB_DIRECT);
17906 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17907 DONE;
17908 }
17909 })
17910
17911 (define_insn "*rdtsc"
17912 [(set (match_operand:DI 0 "register_operand" "=A")
17913 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17914 "!TARGET_64BIT"
17915 "rdtsc"
17916 [(set_attr "type" "other")
17917 (set_attr "length" "2")])
17918
17919 (define_insn "*rdtsc_rex64"
17920 [(set (match_operand:DI 0 "register_operand" "=a")
17921 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17922 (set (match_operand:DI 1 "register_operand" "=d")
17923 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17924 "TARGET_64BIT"
17925 "rdtsc"
17926 [(set_attr "type" "other")
17927 (set_attr "length" "2")])
17928
17929 (define_expand "rdtscp"
17930 [(match_operand:DI 0 "register_operand")
17931 (match_operand:SI 1 "memory_operand")]
17932 ""
17933 {
17934 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17935 gen_rtvec (1, const0_rtx),
17936 UNSPECV_RDTSCP);
17937 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17938 gen_rtvec (1, const0_rtx),
17939 UNSPECV_RDTSCP);
17940 rtx reg = gen_reg_rtx (DImode);
17941 rtx tmp = gen_reg_rtx (SImode);
17942
17943 if (TARGET_64BIT)
17944 {
17945 rtvec vec = rtvec_alloc (3);
17946 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17947 rtx upper = gen_reg_rtx (DImode);
17948 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17949 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17950 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17951 emit_insn (load);
17952 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17953 NULL, 1, OPTAB_DIRECT);
17954 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17955 OPTAB_DIRECT);
17956 }
17957 else
17958 {
17959 rtvec vec = rtvec_alloc (2);
17960 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17961 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17962 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17963 emit_insn (load);
17964 }
17965 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17966 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17967 DONE;
17968 })
17969
17970 (define_insn "*rdtscp"
17971 [(set (match_operand:DI 0 "register_operand" "=A")
17972 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17973 (set (match_operand:SI 1 "register_operand" "=c")
17974 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17975 "!TARGET_64BIT"
17976 "rdtscp"
17977 [(set_attr "type" "other")
17978 (set_attr "length" "3")])
17979
17980 (define_insn "*rdtscp_rex64"
17981 [(set (match_operand:DI 0 "register_operand" "=a")
17982 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17983 (set (match_operand:DI 1 "register_operand" "=d")
17984 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17985 (set (match_operand:SI 2 "register_operand" "=c")
17986 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17987 "TARGET_64BIT"
17988 "rdtscp"
17989 [(set_attr "type" "other")
17990 (set_attr "length" "3")])
17991
17992 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17993 ;;
17994 ;; LWP instructions
17995 ;;
17996 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17997
17998 (define_expand "lwp_llwpcb"
17999 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18000 UNSPECV_LLWP_INTRINSIC)]
18001 "TARGET_LWP")
18002
18003 (define_insn "*lwp_llwpcb<mode>1"
18004 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18005 UNSPECV_LLWP_INTRINSIC)]
18006 "TARGET_LWP"
18007 "llwpcb\t%0"
18008 [(set_attr "type" "lwp")
18009 (set_attr "mode" "<MODE>")
18010 (set_attr "length" "5")])
18011
18012 (define_expand "lwp_slwpcb"
18013 [(set (match_operand 0 "register_operand" "=r")
18014 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18015 "TARGET_LWP"
18016 {
18017 rtx (*insn)(rtx);
18018
18019 insn = (Pmode == DImode
18020 ? gen_lwp_slwpcbdi
18021 : gen_lwp_slwpcbsi);
18022
18023 emit_insn (insn (operands[0]));
18024 DONE;
18025 })
18026
18027 (define_insn "lwp_slwpcb<mode>"
18028 [(set (match_operand:P 0 "register_operand" "=r")
18029 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18030 "TARGET_LWP"
18031 "slwpcb\t%0"
18032 [(set_attr "type" "lwp")
18033 (set_attr "mode" "<MODE>")
18034 (set_attr "length" "5")])
18035
18036 (define_expand "lwp_lwpval<mode>3"
18037 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18038 (match_operand:SI 2 "nonimmediate_operand" "rm")
18039 (match_operand:SI 3 "const_int_operand" "i")]
18040 UNSPECV_LWPVAL_INTRINSIC)]
18041 "TARGET_LWP"
18042 ;; Avoid unused variable warning.
18043 "(void) operands[0];")
18044
18045 (define_insn "*lwp_lwpval<mode>3_1"
18046 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18047 (match_operand:SI 1 "nonimmediate_operand" "rm")
18048 (match_operand:SI 2 "const_int_operand" "i")]
18049 UNSPECV_LWPVAL_INTRINSIC)]
18050 "TARGET_LWP"
18051 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18052 [(set_attr "type" "lwp")
18053 (set_attr "mode" "<MODE>")
18054 (set (attr "length")
18055 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18056
18057 (define_expand "lwp_lwpins<mode>3"
18058 [(set (reg:CCC FLAGS_REG)
18059 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18060 (match_operand:SI 2 "nonimmediate_operand" "rm")
18061 (match_operand:SI 3 "const_int_operand" "i")]
18062 UNSPECV_LWPINS_INTRINSIC))
18063 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18064 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18065 "TARGET_LWP")
18066
18067 (define_insn "*lwp_lwpins<mode>3_1"
18068 [(set (reg:CCC FLAGS_REG)
18069 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18070 (match_operand:SI 1 "nonimmediate_operand" "rm")
18071 (match_operand:SI 2 "const_int_operand" "i")]
18072 UNSPECV_LWPINS_INTRINSIC))]
18073 "TARGET_LWP"
18074 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18075 [(set_attr "type" "lwp")
18076 (set_attr "mode" "<MODE>")
18077 (set (attr "length")
18078 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18079
18080 (define_int_iterator RDFSGSBASE
18081 [UNSPECV_RDFSBASE
18082 UNSPECV_RDGSBASE])
18083
18084 (define_int_iterator WRFSGSBASE
18085 [UNSPECV_WRFSBASE
18086 UNSPECV_WRGSBASE])
18087
18088 (define_int_attr fsgs
18089 [(UNSPECV_RDFSBASE "fs")
18090 (UNSPECV_RDGSBASE "gs")
18091 (UNSPECV_WRFSBASE "fs")
18092 (UNSPECV_WRGSBASE "gs")])
18093
18094 (define_insn "rd<fsgs>base<mode>"
18095 [(set (match_operand:SWI48 0 "register_operand" "=r")
18096 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18097 "TARGET_64BIT && TARGET_FSGSBASE"
18098 "rd<fsgs>base\t%0"
18099 [(set_attr "type" "other")
18100 (set_attr "prefix_extra" "2")])
18101
18102 (define_insn "wr<fsgs>base<mode>"
18103 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18104 WRFSGSBASE)]
18105 "TARGET_64BIT && TARGET_FSGSBASE"
18106 "wr<fsgs>base\t%0"
18107 [(set_attr "type" "other")
18108 (set_attr "prefix_extra" "2")])
18109
18110 (define_insn "rdrand<mode>_1"
18111 [(set (match_operand:SWI248 0 "register_operand" "=r")
18112 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18113 (set (reg:CCC FLAGS_REG)
18114 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18115 "TARGET_RDRND"
18116 "rdrand\t%0"
18117 [(set_attr "type" "other")
18118 (set_attr "prefix_extra" "1")])
18119
18120 (define_expand "pause"
18121 [(set (match_dup 0)
18122 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18123 ""
18124 {
18125 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18126 MEM_VOLATILE_P (operands[0]) = 1;
18127 })
18128
18129 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18130 ;; They have the same encoding.
18131 (define_insn "*pause"
18132 [(set (match_operand:BLK 0)
18133 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18134 ""
18135 "rep; nop"
18136 [(set_attr "length" "2")
18137 (set_attr "memory" "unknown")])
18138
18139 (define_expand "xbegin"
18140 [(set (match_operand:SI 0 "register_operand")
18141 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18142 "TARGET_RTM"
18143 {
18144 rtx label = gen_label_rtx ();
18145
18146 operands[1] = force_reg (SImode, constm1_rtx);
18147
18148 emit_jump_insn (gen_xbegin_1 (operands[1], label));
18149
18150 emit_label (label);
18151 LABEL_NUSES (label) = 1;
18152
18153 emit_move_insn (operands[0], operands[1]);
18154
18155 DONE;
18156 })
18157
18158 (define_insn "xbegin_1"
18159 [(set (pc)
18160 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18161 (const_int 0))
18162 (label_ref (match_operand 1))
18163 (pc)))
18164 (set (match_operand:SI 0 "register_operand" "+a")
18165 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18166 "TARGET_RTM"
18167 "xbegin\t%l1"
18168 [(set_attr "type" "other")
18169 (set_attr "length" "6")])
18170
18171 (define_insn "xend"
18172 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18173 "TARGET_RTM"
18174 "xend"
18175 [(set_attr "type" "other")
18176 (set_attr "length" "3")])
18177
18178 (define_insn "xabort"
18179 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18180 UNSPECV_XABORT)]
18181 "TARGET_RTM"
18182 "xabort\t%0"
18183 [(set_attr "type" "other")
18184 (set_attr "length" "3")])
18185
18186 (define_expand "xtest"
18187 [(set (match_operand:QI 0 "register_operand")
18188 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18189 "TARGET_RTM"
18190 {
18191 emit_insn (gen_xtest_1 ());
18192
18193 ix86_expand_setcc (operands[0], NE,
18194 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18195 DONE;
18196 })
18197
18198 (define_insn "xtest_1"
18199 [(set (reg:CCZ FLAGS_REG)
18200 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18201 "TARGET_RTM"
18202 "xtest"
18203 [(set_attr "type" "other")
18204 (set_attr "length" "3")])
18205
18206 (include "mmx.md")
18207 (include "sse.md")
18208 (include "sync.md")