]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
f8a6c3ad73c240886ec4acff520252291fd36e1c
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;; otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; K -- print HLE lock prefix
62 ;; Y -- print condition for XOP pcom* instruction.
63 ;; + -- print a branch hint as 'cs' or 'ds' prefix
64 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
65 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
66 ;; @ -- print a segment register of thread base pointer load
67 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
68
69 (define_c_enum "unspec" [
70 ;; Relocation specifiers
71 UNSPEC_GOT
72 UNSPEC_GOTOFF
73 UNSPEC_GOTPCREL
74 UNSPEC_GOTTPOFF
75 UNSPEC_TPOFF
76 UNSPEC_NTPOFF
77 UNSPEC_DTPOFF
78 UNSPEC_GOTNTPOFF
79 UNSPEC_INDNTPOFF
80 UNSPEC_PLTOFF
81 UNSPEC_MACHOPIC_OFFSET
82 UNSPEC_PCREL
83
84 ;; Prologue support
85 UNSPEC_STACK_ALLOC
86 UNSPEC_SET_GOT
87 UNSPEC_SET_RIP
88 UNSPEC_SET_GOT_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
90 UNSPEC_STACK_CHECK
91
92 ;; TLS support
93 UNSPEC_TP
94 UNSPEC_TLS_GD
95 UNSPEC_TLS_LD_BASE
96 UNSPEC_TLSDESC
97 UNSPEC_TLS_IE_SUN
98
99 ;; Other random patterns
100 UNSPEC_SCAS
101 UNSPEC_FNSTSW
102 UNSPEC_SAHF
103 UNSPEC_PARITY
104 UNSPEC_FSTCW
105 UNSPEC_ADD_CARRY
106 UNSPEC_FLDCW
107 UNSPEC_REP
108 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_TRUNC_NOOP
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_MS_TO_SYSV_CALL
112 UNSPEC_CALL_NEEDS_VZEROUPPER
113 UNSPEC_PAUSE
114 UNSPEC_LEA_ADDR
115 UNSPEC_XBEGIN_ABORT
116
117 ;; For SSE/MMX support:
118 UNSPEC_FIX_NOTRUNC
119 UNSPEC_MASKMOV
120 UNSPEC_MOVMSK
121 UNSPEC_RCP
122 UNSPEC_RSQRT
123 UNSPEC_PSADBW
124
125 ;; Generic math support
126 UNSPEC_COPYSIGN
127 UNSPEC_IEEE_MIN ; not commutative
128 UNSPEC_IEEE_MAX ; not commutative
129
130 ;; x87 Floating point
131 UNSPEC_SIN
132 UNSPEC_COS
133 UNSPEC_FPATAN
134 UNSPEC_FYL2X
135 UNSPEC_FYL2XP1
136 UNSPEC_FRNDINT
137 UNSPEC_FIST
138 UNSPEC_F2XM1
139 UNSPEC_TAN
140 UNSPEC_FXAM
141
142 ;; x87 Rounding
143 UNSPEC_FRNDINT_FLOOR
144 UNSPEC_FRNDINT_CEIL
145 UNSPEC_FRNDINT_TRUNC
146 UNSPEC_FRNDINT_MASK_PM
147 UNSPEC_FIST_FLOOR
148 UNSPEC_FIST_CEIL
149
150 ;; x87 Double output FP
151 UNSPEC_SINCOS_COS
152 UNSPEC_SINCOS_SIN
153 UNSPEC_XTRACT_FRACT
154 UNSPEC_XTRACT_EXP
155 UNSPEC_FSCALE_FRACT
156 UNSPEC_FSCALE_EXP
157 UNSPEC_FPREM_F
158 UNSPEC_FPREM_U
159 UNSPEC_FPREM1_F
160 UNSPEC_FPREM1_U
161
162 UNSPEC_C2_FLAG
163 UNSPEC_FXAM_MEM
164
165 ;; SSP patterns
166 UNSPEC_SP_SET
167 UNSPEC_SP_TEST
168 UNSPEC_SP_TLS_SET
169 UNSPEC_SP_TLS_TEST
170
171 ;; For ROUND support
172 UNSPEC_ROUND
173
174 ;; For CRC32 support
175 UNSPEC_CRC32
176
177 ;; For BMI support
178 UNSPEC_BEXTR
179
180 ;; For BMI2 support
181 UNSPEC_PDEP
182 UNSPEC_PEXT
183 ])
184
185 (define_c_enum "unspecv" [
186 UNSPECV_BLOCKAGE
187 UNSPECV_STACK_PROBE
188 UNSPECV_PROBE_STACK_RANGE
189 UNSPECV_ALIGN
190 UNSPECV_PROLOGUE_USE
191 UNSPECV_SPLIT_STACK_RETURN
192 UNSPECV_CLD
193 UNSPECV_NOPS
194 UNSPECV_RDTSC
195 UNSPECV_RDTSCP
196 UNSPECV_RDPMC
197 UNSPECV_LLWP_INTRINSIC
198 UNSPECV_SLWP_INTRINSIC
199 UNSPECV_LWPVAL_INTRINSIC
200 UNSPECV_LWPINS_INTRINSIC
201 UNSPECV_RDFSBASE
202 UNSPECV_RDGSBASE
203 UNSPECV_WRFSBASE
204 UNSPECV_WRGSBASE
205
206 ;; For RDRAND support
207 UNSPECV_RDRAND
208
209 ;; For RTM support
210 UNSPECV_XBEGIN
211 UNSPECV_XEND
212 UNSPECV_XABORT
213 UNSPECV_XTEST
214 ])
215
216 ;; Constants to represent rounding modes in the ROUND instruction
217 (define_constants
218 [(ROUND_FLOOR 0x1)
219 (ROUND_CEIL 0x2)
220 (ROUND_TRUNC 0x3)
221 (ROUND_MXCSR 0x4)
222 (ROUND_NO_EXC 0x8)
223 ])
224
225 ;; Constants to represent pcomtrue/pcomfalse variants
226 (define_constants
227 [(PCOM_FALSE 0)
228 (PCOM_TRUE 1)
229 (COM_FALSE_S 2)
230 (COM_FALSE_P 3)
231 (COM_TRUE_S 4)
232 (COM_TRUE_P 5)
233 ])
234
235 ;; Constants used in the XOP pperm instruction
236 (define_constants
237 [(PPERM_SRC 0x00) /* copy source */
238 (PPERM_INVERT 0x20) /* invert source */
239 (PPERM_REVERSE 0x40) /* bit reverse source */
240 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
241 (PPERM_ZERO 0x80) /* all 0's */
242 (PPERM_ONES 0xa0) /* all 1's */
243 (PPERM_SIGN 0xc0) /* propagate sign bit */
244 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
245 (PPERM_SRC1 0x00) /* use first source byte */
246 (PPERM_SRC2 0x10) /* use second source byte */
247 ])
248
249 ;; Registers by name.
250 (define_constants
251 [(AX_REG 0)
252 (DX_REG 1)
253 (CX_REG 2)
254 (BX_REG 3)
255 (SI_REG 4)
256 (DI_REG 5)
257 (BP_REG 6)
258 (SP_REG 7)
259 (ST0_REG 8)
260 (ST1_REG 9)
261 (ST2_REG 10)
262 (ST3_REG 11)
263 (ST4_REG 12)
264 (ST5_REG 13)
265 (ST6_REG 14)
266 (ST7_REG 15)
267 (FLAGS_REG 17)
268 (FPSR_REG 18)
269 (FPCR_REG 19)
270 (XMM0_REG 21)
271 (XMM1_REG 22)
272 (XMM2_REG 23)
273 (XMM3_REG 24)
274 (XMM4_REG 25)
275 (XMM5_REG 26)
276 (XMM6_REG 27)
277 (XMM7_REG 28)
278 (MM0_REG 29)
279 (MM1_REG 30)
280 (MM2_REG 31)
281 (MM3_REG 32)
282 (MM4_REG 33)
283 (MM5_REG 34)
284 (MM6_REG 35)
285 (MM7_REG 36)
286 (R8_REG 37)
287 (R9_REG 38)
288 (R10_REG 39)
289 (R11_REG 40)
290 (R12_REG 41)
291 (R13_REG 42)
292 (XMM8_REG 45)
293 (XMM9_REG 46)
294 (XMM10_REG 47)
295 (XMM11_REG 48)
296 (XMM12_REG 49)
297 (XMM13_REG 50)
298 (XMM14_REG 51)
299 (XMM15_REG 52)
300 ])
301
302 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
303 ;; from i386.c.
304
305 ;; In C guard expressions, put expressions which may be compile-time
306 ;; constants first. This allows for better optimization. For
307 ;; example, write "TARGET_64BIT && reload_completed", not
308 ;; "reload_completed && TARGET_64BIT".
309
310 \f
311 ;; Processor type.
312 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
313 atom,generic64,amdfam10,bdver1,bdver2,btver1,btver2"
314 (const (symbol_ref "ix86_schedule")))
315
316 ;; A basic instruction type. Refinements due to arguments to be
317 ;; provided in other attributes.
318 (define_attr "type"
319 "other,multi,
320 alu,alu1,negnot,imov,imovx,lea,
321 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
322 icmp,test,ibr,setcc,icmov,
323 push,pop,call,callv,leave,
324 str,bitmanip,
325 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
326 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
327 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
328 ssemuladd,sse4arg,lwp,
329 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
330 (const_string "other"))
331
332 ;; Main data type used by the insn
333 (define_attr "mode"
334 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
335 (const_string "unknown"))
336
337 ;; The CPU unit operations uses.
338 (define_attr "unit" "integer,i387,sse,mmx,unknown"
339 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
340 (const_string "i387")
341 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
342 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
343 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
344 (const_string "sse")
345 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
346 (const_string "mmx")
347 (eq_attr "type" "other")
348 (const_string "unknown")]
349 (const_string "integer")))
350
351 ;; The (bounding maximum) length of an instruction immediate.
352 (define_attr "length_immediate" ""
353 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
354 bitmanip,imulx")
355 (const_int 0)
356 (eq_attr "unit" "i387,sse,mmx")
357 (const_int 0)
358 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
359 rotate,rotatex,rotate1,imul,icmp,push,pop")
360 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
361 (eq_attr "type" "imov,test")
362 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
363 (eq_attr "type" "call")
364 (if_then_else (match_operand 0 "constant_call_address_operand")
365 (const_int 4)
366 (const_int 0))
367 (eq_attr "type" "callv")
368 (if_then_else (match_operand 1 "constant_call_address_operand")
369 (const_int 4)
370 (const_int 0))
371 ;; We don't know the size before shorten_branches. Expect
372 ;; the instruction to fit for better scheduling.
373 (eq_attr "type" "ibr")
374 (const_int 1)
375 ]
376 (symbol_ref "/* Update immediate_length and other attributes! */
377 gcc_unreachable (),1")))
378
379 ;; The (bounding maximum) length of an instruction address.
380 (define_attr "length_address" ""
381 (cond [(eq_attr "type" "str,other,multi,fxch")
382 (const_int 0)
383 (and (eq_attr "type" "call")
384 (match_operand 0 "constant_call_address_operand"))
385 (const_int 0)
386 (and (eq_attr "type" "callv")
387 (match_operand 1 "constant_call_address_operand"))
388 (const_int 0)
389 ]
390 (symbol_ref "ix86_attr_length_address_default (insn)")))
391
392 ;; Set when length prefix is used.
393 (define_attr "prefix_data16" ""
394 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
395 (const_int 0)
396 (eq_attr "mode" "HI")
397 (const_int 1)
398 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
399 (const_int 1)
400 ]
401 (const_int 0)))
402
403 ;; Set when string REP prefix is used.
404 (define_attr "prefix_rep" ""
405 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
406 (const_int 0)
407 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
408 (const_int 1)
409 ]
410 (const_int 0)))
411
412 ;; Set when 0f opcode prefix is used.
413 (define_attr "prefix_0f" ""
414 (if_then_else
415 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
416 (eq_attr "unit" "sse,mmx"))
417 (const_int 1)
418 (const_int 0)))
419
420 ;; Set when REX opcode prefix is used.
421 (define_attr "prefix_rex" ""
422 (cond [(not (match_test "TARGET_64BIT"))
423 (const_int 0)
424 (and (eq_attr "mode" "DI")
425 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
426 (eq_attr "unit" "!mmx")))
427 (const_int 1)
428 (and (eq_attr "mode" "QI")
429 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
430 (const_int 1)
431 (match_test "x86_extended_reg_mentioned_p (insn)")
432 (const_int 1)
433 (and (eq_attr "type" "imovx")
434 (match_operand:QI 1 "ext_QIreg_operand"))
435 (const_int 1)
436 ]
437 (const_int 0)))
438
439 ;; There are also additional prefixes in 3DNOW, SSSE3.
440 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
441 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
442 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
443 (define_attr "prefix_extra" ""
444 (cond [(eq_attr "type" "ssemuladd,sse4arg")
445 (const_int 2)
446 (eq_attr "type" "sseiadd1,ssecvt1")
447 (const_int 1)
448 ]
449 (const_int 0)))
450
451 ;; Prefix used: original, VEX or maybe VEX.
452 (define_attr "prefix" "orig,vex,maybe_vex"
453 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
454 (const_string "vex")
455 (const_string "orig")))
456
457 ;; VEX W bit is used.
458 (define_attr "prefix_vex_w" "" (const_int 0))
459
460 ;; The length of VEX prefix
461 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
462 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
463 ;; still prefix_0f 1, with prefix_extra 1.
464 (define_attr "length_vex" ""
465 (if_then_else (and (eq_attr "prefix_0f" "1")
466 (eq_attr "prefix_extra" "0"))
467 (if_then_else (eq_attr "prefix_vex_w" "1")
468 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
469 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
470 (if_then_else (eq_attr "prefix_vex_w" "1")
471 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
472 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
473
474 ;; Set when modrm byte is used.
475 (define_attr "modrm" ""
476 (cond [(eq_attr "type" "str,leave")
477 (const_int 0)
478 (eq_attr "unit" "i387")
479 (const_int 0)
480 (and (eq_attr "type" "incdec")
481 (and (not (match_test "TARGET_64BIT"))
482 (ior (match_operand:SI 1 "register_operand")
483 (match_operand:HI 1 "register_operand"))))
484 (const_int 0)
485 (and (eq_attr "type" "push")
486 (not (match_operand 1 "memory_operand")))
487 (const_int 0)
488 (and (eq_attr "type" "pop")
489 (not (match_operand 0 "memory_operand")))
490 (const_int 0)
491 (and (eq_attr "type" "imov")
492 (and (not (eq_attr "mode" "DI"))
493 (ior (and (match_operand 0 "register_operand")
494 (match_operand 1 "immediate_operand"))
495 (ior (and (match_operand 0 "ax_reg_operand")
496 (match_operand 1 "memory_displacement_only_operand"))
497 (and (match_operand 0 "memory_displacement_only_operand")
498 (match_operand 1 "ax_reg_operand"))))))
499 (const_int 0)
500 (and (eq_attr "type" "call")
501 (match_operand 0 "constant_call_address_operand"))
502 (const_int 0)
503 (and (eq_attr "type" "callv")
504 (match_operand 1 "constant_call_address_operand"))
505 (const_int 0)
506 (and (eq_attr "type" "alu,alu1,icmp,test")
507 (match_operand 0 "ax_reg_operand"))
508 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
509 ]
510 (const_int 1)))
511
512 ;; The (bounding maximum) length of an instruction in bytes.
513 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
514 ;; Later we may want to split them and compute proper length as for
515 ;; other insns.
516 (define_attr "length" ""
517 (cond [(eq_attr "type" "other,multi,fistp,frndint")
518 (const_int 16)
519 (eq_attr "type" "fcmp")
520 (const_int 4)
521 (eq_attr "unit" "i387")
522 (plus (const_int 2)
523 (plus (attr "prefix_data16")
524 (attr "length_address")))
525 (ior (eq_attr "prefix" "vex")
526 (and (eq_attr "prefix" "maybe_vex")
527 (match_test "TARGET_AVX")))
528 (plus (attr "length_vex")
529 (plus (attr "length_immediate")
530 (plus (attr "modrm")
531 (attr "length_address"))))]
532 (plus (plus (attr "modrm")
533 (plus (attr "prefix_0f")
534 (plus (attr "prefix_rex")
535 (plus (attr "prefix_extra")
536 (const_int 1)))))
537 (plus (attr "prefix_rep")
538 (plus (attr "prefix_data16")
539 (plus (attr "length_immediate")
540 (attr "length_address")))))))
541
542 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
543 ;; `store' if there is a simple memory reference therein, or `unknown'
544 ;; if the instruction is complex.
545
546 (define_attr "memory" "none,load,store,both,unknown"
547 (cond [(eq_attr "type" "other,multi,str,lwp")
548 (const_string "unknown")
549 (eq_attr "type" "lea,fcmov,fpspc")
550 (const_string "none")
551 (eq_attr "type" "fistp,leave")
552 (const_string "both")
553 (eq_attr "type" "frndint")
554 (const_string "load")
555 (eq_attr "type" "push")
556 (if_then_else (match_operand 1 "memory_operand")
557 (const_string "both")
558 (const_string "store"))
559 (eq_attr "type" "pop")
560 (if_then_else (match_operand 0 "memory_operand")
561 (const_string "both")
562 (const_string "load"))
563 (eq_attr "type" "setcc")
564 (if_then_else (match_operand 0 "memory_operand")
565 (const_string "store")
566 (const_string "none"))
567 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
568 (if_then_else (ior (match_operand 0 "memory_operand")
569 (match_operand 1 "memory_operand"))
570 (const_string "load")
571 (const_string "none"))
572 (eq_attr "type" "ibr")
573 (if_then_else (match_operand 0 "memory_operand")
574 (const_string "load")
575 (const_string "none"))
576 (eq_attr "type" "call")
577 (if_then_else (match_operand 0 "constant_call_address_operand")
578 (const_string "none")
579 (const_string "load"))
580 (eq_attr "type" "callv")
581 (if_then_else (match_operand 1 "constant_call_address_operand")
582 (const_string "none")
583 (const_string "load"))
584 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
585 (match_operand 1 "memory_operand"))
586 (const_string "both")
587 (and (match_operand 0 "memory_operand")
588 (match_operand 1 "memory_operand"))
589 (const_string "both")
590 (match_operand 0 "memory_operand")
591 (const_string "store")
592 (match_operand 1 "memory_operand")
593 (const_string "load")
594 (and (eq_attr "type"
595 "!alu1,negnot,ishift1,
596 imov,imovx,icmp,test,bitmanip,
597 fmov,fcmp,fsgn,
598 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
599 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
600 (match_operand 2 "memory_operand"))
601 (const_string "load")
602 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
603 (match_operand 3 "memory_operand"))
604 (const_string "load")
605 ]
606 (const_string "none")))
607
608 ;; Indicates if an instruction has both an immediate and a displacement.
609
610 (define_attr "imm_disp" "false,true,unknown"
611 (cond [(eq_attr "type" "other,multi")
612 (const_string "unknown")
613 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
614 (and (match_operand 0 "memory_displacement_operand")
615 (match_operand 1 "immediate_operand")))
616 (const_string "true")
617 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
618 (and (match_operand 0 "memory_displacement_operand")
619 (match_operand 2 "immediate_operand")))
620 (const_string "true")
621 ]
622 (const_string "false")))
623
624 ;; Indicates if an FP operation has an integer source.
625
626 (define_attr "fp_int_src" "false,true"
627 (const_string "false"))
628
629 ;; Defines rounding mode of an FP operation.
630
631 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
632 (const_string "any"))
633
634 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
635 (define_attr "use_carry" "0,1" (const_string "0"))
636
637 ;; Define attribute to indicate unaligned ssemov insns
638 (define_attr "movu" "0,1" (const_string "0"))
639
640 ;; Used to control the "enabled" attribute on a per-instruction basis.
641 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,avx2,noavx2,bmi2"
642 (const_string "base"))
643
644 (define_attr "enabled" ""
645 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
646 (eq_attr "isa" "sse2_noavx")
647 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
648 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
649 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
650 (eq_attr "isa" "sse4_noavx")
651 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
652 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
653 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
654 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
655 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
656 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
657 ]
658 (const_int 1)))
659
660 ;; Describe a user's asm statement.
661 (define_asm_attributes
662 [(set_attr "length" "128")
663 (set_attr "type" "multi")])
664
665 (define_code_iterator plusminus [plus minus])
666
667 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
668
669 ;; Base name for define_insn
670 (define_code_attr plusminus_insn
671 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
672 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
673
674 ;; Base name for insn mnemonic.
675 (define_code_attr plusminus_mnemonic
676 [(plus "add") (ss_plus "adds") (us_plus "addus")
677 (minus "sub") (ss_minus "subs") (us_minus "subus")])
678 (define_code_attr plusminus_carry_mnemonic
679 [(plus "adc") (minus "sbb")])
680
681 ;; Mark commutative operators as such in constraints.
682 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
683 (minus "") (ss_minus "") (us_minus "")])
684
685 ;; Mapping of max and min
686 (define_code_iterator maxmin [smax smin umax umin])
687
688 ;; Mapping of signed max and min
689 (define_code_iterator smaxmin [smax smin])
690
691 ;; Mapping of unsigned max and min
692 (define_code_iterator umaxmin [umax umin])
693
694 ;; Base name for integer and FP insn mnemonic
695 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
696 (umax "maxu") (umin "minu")])
697 (define_code_attr maxmin_float [(smax "max") (smin "min")])
698
699 ;; Mapping of logic operators
700 (define_code_iterator any_logic [and ior xor])
701 (define_code_iterator any_or [ior xor])
702
703 ;; Base name for insn mnemonic.
704 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
705
706 ;; Mapping of logic-shift operators
707 (define_code_iterator any_lshift [ashift lshiftrt])
708
709 ;; Mapping of shift-right operators
710 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
711
712 ;; Mapping of all shift operators
713 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
714
715 ;; Base name for define_insn
716 (define_code_attr shift_insn
717 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
718
719 ;; Base name for insn mnemonic.
720 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
721 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
722
723 ;; Mapping of rotate operators
724 (define_code_iterator any_rotate [rotate rotatert])
725
726 ;; Base name for define_insn
727 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
728
729 ;; Base name for insn mnemonic.
730 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
731
732 ;; Mapping of abs neg operators
733 (define_code_iterator absneg [abs neg])
734
735 ;; Base name for x87 insn mnemonic.
736 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
737
738 ;; Used in signed and unsigned widening multiplications.
739 (define_code_iterator any_extend [sign_extend zero_extend])
740
741 ;; Prefix for insn menmonic.
742 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
743
744 ;; Prefix for define_insn
745 (define_code_attr u [(sign_extend "") (zero_extend "u")])
746 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
747 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
748
749 ;; All integer modes.
750 (define_mode_iterator SWI1248x [QI HI SI DI])
751
752 ;; All integer modes without QImode.
753 (define_mode_iterator SWI248x [HI SI DI])
754
755 ;; All integer modes without QImode and HImode.
756 (define_mode_iterator SWI48x [SI DI])
757
758 ;; All integer modes without SImode and DImode.
759 (define_mode_iterator SWI12 [QI HI])
760
761 ;; All integer modes without DImode.
762 (define_mode_iterator SWI124 [QI HI SI])
763
764 ;; All integer modes without QImode and DImode.
765 (define_mode_iterator SWI24 [HI SI])
766
767 ;; Single word integer modes.
768 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
769
770 ;; Single word integer modes without QImode.
771 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
772
773 ;; Single word integer modes without QImode and HImode.
774 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
775
776 ;; All math-dependant single and double word integer modes.
777 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
778 (HI "TARGET_HIMODE_MATH")
779 SI DI (TI "TARGET_64BIT")])
780
781 ;; Math-dependant single word integer modes.
782 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
783 (HI "TARGET_HIMODE_MATH")
784 SI (DI "TARGET_64BIT")])
785
786 ;; Math-dependant integer modes without DImode.
787 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
788 (HI "TARGET_HIMODE_MATH")
789 SI])
790
791 ;; Math-dependant single word integer modes without QImode.
792 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
793 SI (DI "TARGET_64BIT")])
794
795 ;; Double word integer modes.
796 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
797 (TI "TARGET_64BIT")])
798
799 ;; Double word integer modes as mode attribute.
800 (define_mode_attr DWI [(SI "DI") (DI "TI")])
801 (define_mode_attr dwi [(SI "di") (DI "ti")])
802
803 ;; Half mode for double word integer modes.
804 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
805 (DI "TARGET_64BIT")])
806
807 ;; Instruction suffix for integer modes.
808 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
809
810 ;; Pointer size prefix for integer modes (Intel asm dialect)
811 (define_mode_attr iptrsize [(QI "BYTE")
812 (HI "WORD")
813 (SI "DWORD")
814 (DI "QWORD")])
815
816 ;; Register class for integer modes.
817 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
818
819 ;; Immediate operand constraint for integer modes.
820 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
821
822 ;; General operand constraint for word modes.
823 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
824
825 ;; Immediate operand constraint for double integer modes.
826 (define_mode_attr di [(SI "nF") (DI "e")])
827
828 ;; Immediate operand constraint for shifts.
829 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
830
831 ;; General operand predicate for integer modes.
832 (define_mode_attr general_operand
833 [(QI "general_operand")
834 (HI "general_operand")
835 (SI "x86_64_general_operand")
836 (DI "x86_64_general_operand")
837 (TI "x86_64_general_operand")])
838
839 ;; General sign/zero extend operand predicate for integer modes.
840 (define_mode_attr general_szext_operand
841 [(QI "general_operand")
842 (HI "general_operand")
843 (SI "x86_64_szext_general_operand")
844 (DI "x86_64_szext_general_operand")])
845
846 ;; Immediate operand predicate for integer modes.
847 (define_mode_attr immediate_operand
848 [(QI "immediate_operand")
849 (HI "immediate_operand")
850 (SI "x86_64_immediate_operand")
851 (DI "x86_64_immediate_operand")])
852
853 ;; Nonmemory operand predicate for integer modes.
854 (define_mode_attr nonmemory_operand
855 [(QI "nonmemory_operand")
856 (HI "nonmemory_operand")
857 (SI "x86_64_nonmemory_operand")
858 (DI "x86_64_nonmemory_operand")])
859
860 ;; Operand predicate for shifts.
861 (define_mode_attr shift_operand
862 [(QI "nonimmediate_operand")
863 (HI "nonimmediate_operand")
864 (SI "nonimmediate_operand")
865 (DI "shiftdi_operand")
866 (TI "register_operand")])
867
868 ;; Operand predicate for shift argument.
869 (define_mode_attr shift_immediate_operand
870 [(QI "const_1_to_31_operand")
871 (HI "const_1_to_31_operand")
872 (SI "const_1_to_31_operand")
873 (DI "const_1_to_63_operand")])
874
875 ;; Input operand predicate for arithmetic left shifts.
876 (define_mode_attr ashl_input_operand
877 [(QI "nonimmediate_operand")
878 (HI "nonimmediate_operand")
879 (SI "nonimmediate_operand")
880 (DI "ashldi_input_operand")
881 (TI "reg_or_pm1_operand")])
882
883 ;; SSE and x87 SFmode and DFmode floating point modes
884 (define_mode_iterator MODEF [SF DF])
885
886 ;; All x87 floating point modes
887 (define_mode_iterator X87MODEF [SF DF XF])
888
889 ;; SSE instruction suffix for various modes
890 (define_mode_attr ssemodesuffix
891 [(SF "ss") (DF "sd")
892 (V8SF "ps") (V4DF "pd")
893 (V4SF "ps") (V2DF "pd")
894 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
895 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
896
897 ;; SSE vector suffix for floating point modes
898 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
899
900 ;; SSE vector mode corresponding to a scalar mode
901 (define_mode_attr ssevecmode
902 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
903
904 ;; Instruction suffix for REX 64bit operators.
905 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
906
907 ;; This mode iterator allows :P to be used for patterns that operate on
908 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
909 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
910
911 ;; This mode iterator allows :W to be used for patterns that operate on
912 ;; word_mode sized quantities.
913 (define_mode_iterator W
914 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
915
916 ;; This mode iterator allows :PTR to be used for patterns that operate on
917 ;; ptr_mode sized quantities.
918 (define_mode_iterator PTR
919 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
920 \f
921 ;; Scheduling descriptions
922
923 (include "pentium.md")
924 (include "ppro.md")
925 (include "k6.md")
926 (include "athlon.md")
927 (include "bdver1.md")
928 (include "geode.md")
929 (include "atom.md")
930 (include "core2.md")
931
932 \f
933 ;; Operand and operator predicates and constraints
934
935 (include "predicates.md")
936 (include "constraints.md")
937
938 \f
939 ;; Compare and branch/compare and store instructions.
940
941 (define_expand "cbranch<mode>4"
942 [(set (reg:CC FLAGS_REG)
943 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
944 (match_operand:SDWIM 2 "<general_operand>")))
945 (set (pc) (if_then_else
946 (match_operator 0 "ordered_comparison_operator"
947 [(reg:CC FLAGS_REG) (const_int 0)])
948 (label_ref (match_operand 3))
949 (pc)))]
950 ""
951 {
952 if (MEM_P (operands[1]) && MEM_P (operands[2]))
953 operands[1] = force_reg (<MODE>mode, operands[1]);
954 ix86_expand_branch (GET_CODE (operands[0]),
955 operands[1], operands[2], operands[3]);
956 DONE;
957 })
958
959 (define_expand "cstore<mode>4"
960 [(set (reg:CC FLAGS_REG)
961 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
962 (match_operand:SWIM 3 "<general_operand>")))
963 (set (match_operand:QI 0 "register_operand")
964 (match_operator 1 "ordered_comparison_operator"
965 [(reg:CC FLAGS_REG) (const_int 0)]))]
966 ""
967 {
968 if (MEM_P (operands[2]) && MEM_P (operands[3]))
969 operands[2] = force_reg (<MODE>mode, operands[2]);
970 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
971 operands[2], operands[3]);
972 DONE;
973 })
974
975 (define_expand "cmp<mode>_1"
976 [(set (reg:CC FLAGS_REG)
977 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
978 (match_operand:SWI48 1 "<general_operand>")))])
979
980 (define_insn "*cmp<mode>_ccno_1"
981 [(set (reg FLAGS_REG)
982 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
983 (match_operand:SWI 1 "const0_operand")))]
984 "ix86_match_ccmode (insn, CCNOmode)"
985 "@
986 test{<imodesuffix>}\t%0, %0
987 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
988 [(set_attr "type" "test,icmp")
989 (set_attr "length_immediate" "0,1")
990 (set_attr "mode" "<MODE>")])
991
992 (define_insn "*cmp<mode>_1"
993 [(set (reg FLAGS_REG)
994 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
995 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
996 "ix86_match_ccmode (insn, CCmode)"
997 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
998 [(set_attr "type" "icmp")
999 (set_attr "mode" "<MODE>")])
1000
1001 (define_insn "*cmp<mode>_minus_1"
1002 [(set (reg FLAGS_REG)
1003 (compare
1004 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1005 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1006 (const_int 0)))]
1007 "ix86_match_ccmode (insn, CCGOCmode)"
1008 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1009 [(set_attr "type" "icmp")
1010 (set_attr "mode" "<MODE>")])
1011
1012 (define_insn "*cmpqi_ext_1"
1013 [(set (reg FLAGS_REG)
1014 (compare
1015 (match_operand:QI 0 "general_operand" "Qm")
1016 (subreg:QI
1017 (zero_extract:SI
1018 (match_operand 1 "ext_register_operand" "Q")
1019 (const_int 8)
1020 (const_int 8)) 0)))]
1021 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1022 "cmp{b}\t{%h1, %0|%0, %h1}"
1023 [(set_attr "type" "icmp")
1024 (set_attr "mode" "QI")])
1025
1026 (define_insn "*cmpqi_ext_1_rex64"
1027 [(set (reg FLAGS_REG)
1028 (compare
1029 (match_operand:QI 0 "register_operand" "Q")
1030 (subreg:QI
1031 (zero_extract:SI
1032 (match_operand 1 "ext_register_operand" "Q")
1033 (const_int 8)
1034 (const_int 8)) 0)))]
1035 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1036 "cmp{b}\t{%h1, %0|%0, %h1}"
1037 [(set_attr "type" "icmp")
1038 (set_attr "mode" "QI")])
1039
1040 (define_insn "*cmpqi_ext_2"
1041 [(set (reg FLAGS_REG)
1042 (compare
1043 (subreg:QI
1044 (zero_extract:SI
1045 (match_operand 0 "ext_register_operand" "Q")
1046 (const_int 8)
1047 (const_int 8)) 0)
1048 (match_operand:QI 1 "const0_operand")))]
1049 "ix86_match_ccmode (insn, CCNOmode)"
1050 "test{b}\t%h0, %h0"
1051 [(set_attr "type" "test")
1052 (set_attr "length_immediate" "0")
1053 (set_attr "mode" "QI")])
1054
1055 (define_expand "cmpqi_ext_3"
1056 [(set (reg:CC FLAGS_REG)
1057 (compare:CC
1058 (subreg:QI
1059 (zero_extract:SI
1060 (match_operand 0 "ext_register_operand")
1061 (const_int 8)
1062 (const_int 8)) 0)
1063 (match_operand:QI 1 "immediate_operand")))])
1064
1065 (define_insn "*cmpqi_ext_3_insn"
1066 [(set (reg FLAGS_REG)
1067 (compare
1068 (subreg:QI
1069 (zero_extract:SI
1070 (match_operand 0 "ext_register_operand" "Q")
1071 (const_int 8)
1072 (const_int 8)) 0)
1073 (match_operand:QI 1 "general_operand" "Qmn")))]
1074 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1075 "cmp{b}\t{%1, %h0|%h0, %1}"
1076 [(set_attr "type" "icmp")
1077 (set_attr "modrm" "1")
1078 (set_attr "mode" "QI")])
1079
1080 (define_insn "*cmpqi_ext_3_insn_rex64"
1081 [(set (reg FLAGS_REG)
1082 (compare
1083 (subreg:QI
1084 (zero_extract:SI
1085 (match_operand 0 "ext_register_operand" "Q")
1086 (const_int 8)
1087 (const_int 8)) 0)
1088 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1089 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1090 "cmp{b}\t{%1, %h0|%h0, %1}"
1091 [(set_attr "type" "icmp")
1092 (set_attr "modrm" "1")
1093 (set_attr "mode" "QI")])
1094
1095 (define_insn "*cmpqi_ext_4"
1096 [(set (reg FLAGS_REG)
1097 (compare
1098 (subreg:QI
1099 (zero_extract:SI
1100 (match_operand 0 "ext_register_operand" "Q")
1101 (const_int 8)
1102 (const_int 8)) 0)
1103 (subreg:QI
1104 (zero_extract:SI
1105 (match_operand 1 "ext_register_operand" "Q")
1106 (const_int 8)
1107 (const_int 8)) 0)))]
1108 "ix86_match_ccmode (insn, CCmode)"
1109 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1110 [(set_attr "type" "icmp")
1111 (set_attr "mode" "QI")])
1112
1113 ;; These implement float point compares.
1114 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1115 ;; which would allow mix and match FP modes on the compares. Which is what
1116 ;; the old patterns did, but with many more of them.
1117
1118 (define_expand "cbranchxf4"
1119 [(set (reg:CC FLAGS_REG)
1120 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1121 (match_operand:XF 2 "nonmemory_operand")))
1122 (set (pc) (if_then_else
1123 (match_operator 0 "ix86_fp_comparison_operator"
1124 [(reg:CC FLAGS_REG)
1125 (const_int 0)])
1126 (label_ref (match_operand 3))
1127 (pc)))]
1128 "TARGET_80387"
1129 {
1130 ix86_expand_branch (GET_CODE (operands[0]),
1131 operands[1], operands[2], operands[3]);
1132 DONE;
1133 })
1134
1135 (define_expand "cstorexf4"
1136 [(set (reg:CC FLAGS_REG)
1137 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1138 (match_operand:XF 3 "nonmemory_operand")))
1139 (set (match_operand:QI 0 "register_operand")
1140 (match_operator 1 "ix86_fp_comparison_operator"
1141 [(reg:CC FLAGS_REG)
1142 (const_int 0)]))]
1143 "TARGET_80387"
1144 {
1145 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1146 operands[2], operands[3]);
1147 DONE;
1148 })
1149
1150 (define_expand "cbranch<mode>4"
1151 [(set (reg:CC FLAGS_REG)
1152 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1153 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1154 (set (pc) (if_then_else
1155 (match_operator 0 "ix86_fp_comparison_operator"
1156 [(reg:CC FLAGS_REG)
1157 (const_int 0)])
1158 (label_ref (match_operand 3))
1159 (pc)))]
1160 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1161 {
1162 ix86_expand_branch (GET_CODE (operands[0]),
1163 operands[1], operands[2], operands[3]);
1164 DONE;
1165 })
1166
1167 (define_expand "cstore<mode>4"
1168 [(set (reg:CC FLAGS_REG)
1169 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1170 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1171 (set (match_operand:QI 0 "register_operand")
1172 (match_operator 1 "ix86_fp_comparison_operator"
1173 [(reg:CC FLAGS_REG)
1174 (const_int 0)]))]
1175 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1176 {
1177 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1178 operands[2], operands[3]);
1179 DONE;
1180 })
1181
1182 (define_expand "cbranchcc4"
1183 [(set (pc) (if_then_else
1184 (match_operator 0 "comparison_operator"
1185 [(match_operand 1 "flags_reg_operand")
1186 (match_operand 2 "const0_operand")])
1187 (label_ref (match_operand 3))
1188 (pc)))]
1189 ""
1190 {
1191 ix86_expand_branch (GET_CODE (operands[0]),
1192 operands[1], operands[2], operands[3]);
1193 DONE;
1194 })
1195
1196 (define_expand "cstorecc4"
1197 [(set (match_operand:QI 0 "register_operand")
1198 (match_operator 1 "comparison_operator"
1199 [(match_operand 2 "flags_reg_operand")
1200 (match_operand 3 "const0_operand")]))]
1201 ""
1202 {
1203 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1204 operands[2], operands[3]);
1205 DONE;
1206 })
1207
1208
1209 ;; FP compares, step 1:
1210 ;; Set the FP condition codes.
1211 ;;
1212 ;; CCFPmode compare with exceptions
1213 ;; CCFPUmode compare with no exceptions
1214
1215 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1216 ;; used to manage the reg stack popping would not be preserved.
1217
1218 (define_insn "*cmpfp_0"
1219 [(set (match_operand:HI 0 "register_operand" "=a")
1220 (unspec:HI
1221 [(compare:CCFP
1222 (match_operand 1 "register_operand" "f")
1223 (match_operand 2 "const0_operand"))]
1224 UNSPEC_FNSTSW))]
1225 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1226 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1227 "* return output_fp_compare (insn, operands, false, false);"
1228 [(set_attr "type" "multi")
1229 (set_attr "unit" "i387")
1230 (set (attr "mode")
1231 (cond [(match_operand:SF 1)
1232 (const_string "SF")
1233 (match_operand:DF 1)
1234 (const_string "DF")
1235 ]
1236 (const_string "XF")))])
1237
1238 (define_insn_and_split "*cmpfp_0_cc"
1239 [(set (reg:CCFP FLAGS_REG)
1240 (compare:CCFP
1241 (match_operand 1 "register_operand" "f")
1242 (match_operand 2 "const0_operand")))
1243 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1244 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1245 && TARGET_SAHF && !TARGET_CMOVE
1246 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1247 "#"
1248 "&& reload_completed"
1249 [(set (match_dup 0)
1250 (unspec:HI
1251 [(compare:CCFP (match_dup 1)(match_dup 2))]
1252 UNSPEC_FNSTSW))
1253 (set (reg:CC FLAGS_REG)
1254 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1255 ""
1256 [(set_attr "type" "multi")
1257 (set_attr "unit" "i387")
1258 (set (attr "mode")
1259 (cond [(match_operand:SF 1)
1260 (const_string "SF")
1261 (match_operand:DF 1)
1262 (const_string "DF")
1263 ]
1264 (const_string "XF")))])
1265
1266 (define_insn "*cmpfp_xf"
1267 [(set (match_operand:HI 0 "register_operand" "=a")
1268 (unspec:HI
1269 [(compare:CCFP
1270 (match_operand:XF 1 "register_operand" "f")
1271 (match_operand:XF 2 "register_operand" "f"))]
1272 UNSPEC_FNSTSW))]
1273 "TARGET_80387"
1274 "* return output_fp_compare (insn, operands, false, false);"
1275 [(set_attr "type" "multi")
1276 (set_attr "unit" "i387")
1277 (set_attr "mode" "XF")])
1278
1279 (define_insn_and_split "*cmpfp_xf_cc"
1280 [(set (reg:CCFP FLAGS_REG)
1281 (compare:CCFP
1282 (match_operand:XF 1 "register_operand" "f")
1283 (match_operand:XF 2 "register_operand" "f")))
1284 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1285 "TARGET_80387
1286 && TARGET_SAHF && !TARGET_CMOVE"
1287 "#"
1288 "&& reload_completed"
1289 [(set (match_dup 0)
1290 (unspec:HI
1291 [(compare:CCFP (match_dup 1)(match_dup 2))]
1292 UNSPEC_FNSTSW))
1293 (set (reg:CC FLAGS_REG)
1294 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1295 ""
1296 [(set_attr "type" "multi")
1297 (set_attr "unit" "i387")
1298 (set_attr "mode" "XF")])
1299
1300 (define_insn "*cmpfp_<mode>"
1301 [(set (match_operand:HI 0 "register_operand" "=a")
1302 (unspec:HI
1303 [(compare:CCFP
1304 (match_operand:MODEF 1 "register_operand" "f")
1305 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1306 UNSPEC_FNSTSW))]
1307 "TARGET_80387"
1308 "* return output_fp_compare (insn, operands, false, false);"
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "<MODE>")])
1312
1313 (define_insn_and_split "*cmpfp_<mode>_cc"
1314 [(set (reg:CCFP FLAGS_REG)
1315 (compare:CCFP
1316 (match_operand:MODEF 1 "register_operand" "f")
1317 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1318 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1319 "TARGET_80387
1320 && TARGET_SAHF && !TARGET_CMOVE"
1321 "#"
1322 "&& reload_completed"
1323 [(set (match_dup 0)
1324 (unspec:HI
1325 [(compare:CCFP (match_dup 1)(match_dup 2))]
1326 UNSPEC_FNSTSW))
1327 (set (reg:CC FLAGS_REG)
1328 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1329 ""
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1332 (set_attr "mode" "<MODE>")])
1333
1334 (define_insn "*cmpfp_u"
1335 [(set (match_operand:HI 0 "register_operand" "=a")
1336 (unspec:HI
1337 [(compare:CCFPU
1338 (match_operand 1 "register_operand" "f")
1339 (match_operand 2 "register_operand" "f"))]
1340 UNSPEC_FNSTSW))]
1341 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1342 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1343 "* return output_fp_compare (insn, operands, false, true);"
1344 [(set_attr "type" "multi")
1345 (set_attr "unit" "i387")
1346 (set (attr "mode")
1347 (cond [(match_operand:SF 1)
1348 (const_string "SF")
1349 (match_operand:DF 1)
1350 (const_string "DF")
1351 ]
1352 (const_string "XF")))])
1353
1354 (define_insn_and_split "*cmpfp_u_cc"
1355 [(set (reg:CCFPU FLAGS_REG)
1356 (compare:CCFPU
1357 (match_operand 1 "register_operand" "f")
1358 (match_operand 2 "register_operand" "f")))
1359 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1360 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1361 && TARGET_SAHF && !TARGET_CMOVE
1362 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1363 "#"
1364 "&& reload_completed"
1365 [(set (match_dup 0)
1366 (unspec:HI
1367 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1368 UNSPEC_FNSTSW))
1369 (set (reg:CC FLAGS_REG)
1370 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1371 ""
1372 [(set_attr "type" "multi")
1373 (set_attr "unit" "i387")
1374 (set (attr "mode")
1375 (cond [(match_operand:SF 1)
1376 (const_string "SF")
1377 (match_operand:DF 1)
1378 (const_string "DF")
1379 ]
1380 (const_string "XF")))])
1381
1382 (define_insn "*cmpfp_<mode>"
1383 [(set (match_operand:HI 0 "register_operand" "=a")
1384 (unspec:HI
1385 [(compare:CCFP
1386 (match_operand 1 "register_operand" "f")
1387 (match_operator 3 "float_operator"
1388 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1389 UNSPEC_FNSTSW))]
1390 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1391 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1392 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1393 "* return output_fp_compare (insn, operands, false, false);"
1394 [(set_attr "type" "multi")
1395 (set_attr "unit" "i387")
1396 (set_attr "fp_int_src" "true")
1397 (set_attr "mode" "<MODE>")])
1398
1399 (define_insn_and_split "*cmpfp_<mode>_cc"
1400 [(set (reg:CCFP FLAGS_REG)
1401 (compare:CCFP
1402 (match_operand 1 "register_operand" "f")
1403 (match_operator 3 "float_operator"
1404 [(match_operand:SWI24 2 "memory_operand" "m")])))
1405 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1406 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1407 && TARGET_SAHF && !TARGET_CMOVE
1408 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1409 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1410 "#"
1411 "&& reload_completed"
1412 [(set (match_dup 0)
1413 (unspec:HI
1414 [(compare:CCFP
1415 (match_dup 1)
1416 (match_op_dup 3 [(match_dup 2)]))]
1417 UNSPEC_FNSTSW))
1418 (set (reg:CC FLAGS_REG)
1419 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1420 ""
1421 [(set_attr "type" "multi")
1422 (set_attr "unit" "i387")
1423 (set_attr "fp_int_src" "true")
1424 (set_attr "mode" "<MODE>")])
1425
1426 ;; FP compares, step 2
1427 ;; Move the fpsw to ax.
1428
1429 (define_insn "x86_fnstsw_1"
1430 [(set (match_operand:HI 0 "register_operand" "=a")
1431 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1432 "TARGET_80387"
1433 "fnstsw\t%0"
1434 [(set (attr "length")
1435 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1436 (set_attr "mode" "SI")
1437 (set_attr "unit" "i387")])
1438
1439 ;; FP compares, step 3
1440 ;; Get ax into flags, general case.
1441
1442 (define_insn "x86_sahf_1"
1443 [(set (reg:CC FLAGS_REG)
1444 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1445 UNSPEC_SAHF))]
1446 "TARGET_SAHF"
1447 {
1448 #ifndef HAVE_AS_IX86_SAHF
1449 if (TARGET_64BIT)
1450 return ASM_BYTE "0x9e";
1451 else
1452 #endif
1453 return "sahf";
1454 }
1455 [(set_attr "length" "1")
1456 (set_attr "athlon_decode" "vector")
1457 (set_attr "amdfam10_decode" "direct")
1458 (set_attr "bdver1_decode" "direct")
1459 (set_attr "mode" "SI")])
1460
1461 ;; Pentium Pro can do steps 1 through 3 in one go.
1462 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1463 ;; (these i387 instructions set flags directly)
1464 (define_insn "*cmpfp_i_mixed"
1465 [(set (reg:CCFP FLAGS_REG)
1466 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1467 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1468 "TARGET_MIX_SSE_I387
1469 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1470 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1471 "* return output_fp_compare (insn, operands, true, false);"
1472 [(set_attr "type" "fcmp,ssecomi")
1473 (set_attr "prefix" "orig,maybe_vex")
1474 (set (attr "mode")
1475 (if_then_else (match_operand:SF 1)
1476 (const_string "SF")
1477 (const_string "DF")))
1478 (set (attr "prefix_rep")
1479 (if_then_else (eq_attr "type" "ssecomi")
1480 (const_string "0")
1481 (const_string "*")))
1482 (set (attr "prefix_data16")
1483 (cond [(eq_attr "type" "fcmp")
1484 (const_string "*")
1485 (eq_attr "mode" "DF")
1486 (const_string "1")
1487 ]
1488 (const_string "0")))
1489 (set_attr "athlon_decode" "vector")
1490 (set_attr "amdfam10_decode" "direct")
1491 (set_attr "bdver1_decode" "double")])
1492
1493 (define_insn "*cmpfp_i_sse"
1494 [(set (reg:CCFP FLAGS_REG)
1495 (compare:CCFP (match_operand 0 "register_operand" "x")
1496 (match_operand 1 "nonimmediate_operand" "xm")))]
1497 "TARGET_SSE_MATH
1498 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1499 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1500 "* return output_fp_compare (insn, operands, true, false);"
1501 [(set_attr "type" "ssecomi")
1502 (set_attr "prefix" "maybe_vex")
1503 (set (attr "mode")
1504 (if_then_else (match_operand:SF 1)
1505 (const_string "SF")
1506 (const_string "DF")))
1507 (set_attr "prefix_rep" "0")
1508 (set (attr "prefix_data16")
1509 (if_then_else (eq_attr "mode" "DF")
1510 (const_string "1")
1511 (const_string "0")))
1512 (set_attr "athlon_decode" "vector")
1513 (set_attr "amdfam10_decode" "direct")
1514 (set_attr "bdver1_decode" "double")])
1515
1516 (define_insn "*cmpfp_i_i387"
1517 [(set (reg:CCFP FLAGS_REG)
1518 (compare:CCFP (match_operand 0 "register_operand" "f")
1519 (match_operand 1 "register_operand" "f")))]
1520 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1521 && TARGET_CMOVE
1522 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1523 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1524 "* return output_fp_compare (insn, operands, true, false);"
1525 [(set_attr "type" "fcmp")
1526 (set (attr "mode")
1527 (cond [(match_operand:SF 1)
1528 (const_string "SF")
1529 (match_operand:DF 1)
1530 (const_string "DF")
1531 ]
1532 (const_string "XF")))
1533 (set_attr "athlon_decode" "vector")
1534 (set_attr "amdfam10_decode" "direct")
1535 (set_attr "bdver1_decode" "double")])
1536
1537 (define_insn "*cmpfp_iu_mixed"
1538 [(set (reg:CCFPU FLAGS_REG)
1539 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1540 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1541 "TARGET_MIX_SSE_I387
1542 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1543 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1544 "* return output_fp_compare (insn, operands, true, true);"
1545 [(set_attr "type" "fcmp,ssecomi")
1546 (set_attr "prefix" "orig,maybe_vex")
1547 (set (attr "mode")
1548 (if_then_else (match_operand:SF 1)
1549 (const_string "SF")
1550 (const_string "DF")))
1551 (set (attr "prefix_rep")
1552 (if_then_else (eq_attr "type" "ssecomi")
1553 (const_string "0")
1554 (const_string "*")))
1555 (set (attr "prefix_data16")
1556 (cond [(eq_attr "type" "fcmp")
1557 (const_string "*")
1558 (eq_attr "mode" "DF")
1559 (const_string "1")
1560 ]
1561 (const_string "0")))
1562 (set_attr "athlon_decode" "vector")
1563 (set_attr "amdfam10_decode" "direct")
1564 (set_attr "bdver1_decode" "double")])
1565
1566 (define_insn "*cmpfp_iu_sse"
1567 [(set (reg:CCFPU FLAGS_REG)
1568 (compare:CCFPU (match_operand 0 "register_operand" "x")
1569 (match_operand 1 "nonimmediate_operand" "xm")))]
1570 "TARGET_SSE_MATH
1571 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1572 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1573 "* return output_fp_compare (insn, operands, true, true);"
1574 [(set_attr "type" "ssecomi")
1575 (set_attr "prefix" "maybe_vex")
1576 (set (attr "mode")
1577 (if_then_else (match_operand:SF 1)
1578 (const_string "SF")
1579 (const_string "DF")))
1580 (set_attr "prefix_rep" "0")
1581 (set (attr "prefix_data16")
1582 (if_then_else (eq_attr "mode" "DF")
1583 (const_string "1")
1584 (const_string "0")))
1585 (set_attr "athlon_decode" "vector")
1586 (set_attr "amdfam10_decode" "direct")
1587 (set_attr "bdver1_decode" "double")])
1588
1589 (define_insn "*cmpfp_iu_387"
1590 [(set (reg:CCFPU FLAGS_REG)
1591 (compare:CCFPU (match_operand 0 "register_operand" "f")
1592 (match_operand 1 "register_operand" "f")))]
1593 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1594 && TARGET_CMOVE
1595 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1596 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1597 "* return output_fp_compare (insn, operands, true, true);"
1598 [(set_attr "type" "fcmp")
1599 (set (attr "mode")
1600 (cond [(match_operand:SF 1)
1601 (const_string "SF")
1602 (match_operand:DF 1)
1603 (const_string "DF")
1604 ]
1605 (const_string "XF")))
1606 (set_attr "athlon_decode" "vector")
1607 (set_attr "amdfam10_decode" "direct")
1608 (set_attr "bdver1_decode" "direct")])
1609 \f
1610 ;; Push/pop instructions.
1611
1612 (define_insn "*push<mode>2"
1613 [(set (match_operand:DWI 0 "push_operand" "=<")
1614 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1615 ""
1616 "#"
1617 [(set_attr "type" "multi")
1618 (set_attr "mode" "<MODE>")])
1619
1620 (define_split
1621 [(set (match_operand:TI 0 "push_operand")
1622 (match_operand:TI 1 "general_operand"))]
1623 "TARGET_64BIT && reload_completed
1624 && !SSE_REG_P (operands[1])"
1625 [(const_int 0)]
1626 "ix86_split_long_move (operands); DONE;")
1627
1628 (define_insn "*pushdi2_rex64"
1629 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1630 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1631 "TARGET_64BIT"
1632 "@
1633 push{q}\t%1
1634 #"
1635 [(set_attr "type" "push,multi")
1636 (set_attr "mode" "DI")])
1637
1638 ;; Convert impossible pushes of immediate to existing instructions.
1639 ;; First try to get scratch register and go through it. In case this
1640 ;; fails, push sign extended lower part first and then overwrite
1641 ;; upper part by 32bit move.
1642 (define_peephole2
1643 [(match_scratch:DI 2 "r")
1644 (set (match_operand:DI 0 "push_operand")
1645 (match_operand:DI 1 "immediate_operand"))]
1646 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1647 && !x86_64_immediate_operand (operands[1], DImode)"
1648 [(set (match_dup 2) (match_dup 1))
1649 (set (match_dup 0) (match_dup 2))])
1650
1651 ;; We need to define this as both peepholer and splitter for case
1652 ;; peephole2 pass is not run.
1653 ;; "&& 1" is needed to keep it from matching the previous pattern.
1654 (define_peephole2
1655 [(set (match_operand:DI 0 "push_operand")
1656 (match_operand:DI 1 "immediate_operand"))]
1657 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1658 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1659 [(set (match_dup 0) (match_dup 1))
1660 (set (match_dup 2) (match_dup 3))]
1661 {
1662 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1663
1664 operands[1] = gen_lowpart (DImode, operands[2]);
1665 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1666 GEN_INT (4)));
1667 })
1668
1669 (define_split
1670 [(set (match_operand:DI 0 "push_operand")
1671 (match_operand:DI 1 "immediate_operand"))]
1672 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1673 ? epilogue_completed : reload_completed)
1674 && !symbolic_operand (operands[1], DImode)
1675 && !x86_64_immediate_operand (operands[1], DImode)"
1676 [(set (match_dup 0) (match_dup 1))
1677 (set (match_dup 2) (match_dup 3))]
1678 {
1679 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1680
1681 operands[1] = gen_lowpart (DImode, operands[2]);
1682 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1683 GEN_INT (4)));
1684 })
1685
1686 (define_split
1687 [(set (match_operand:DI 0 "push_operand")
1688 (match_operand:DI 1 "general_operand"))]
1689 "!TARGET_64BIT && reload_completed
1690 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1691 [(const_int 0)]
1692 "ix86_split_long_move (operands); DONE;")
1693
1694 (define_insn "*pushsi2"
1695 [(set (match_operand:SI 0 "push_operand" "=<")
1696 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1697 "!TARGET_64BIT"
1698 "push{l}\t%1"
1699 [(set_attr "type" "push")
1700 (set_attr "mode" "SI")])
1701
1702 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1703 ;; "push a byte/word". But actually we use pushl, which has the effect
1704 ;; of rounding the amount pushed up to a word.
1705
1706 ;; For TARGET_64BIT we always round up to 8 bytes.
1707 (define_insn "*push<mode>2_rex64"
1708 [(set (match_operand:SWI124 0 "push_operand" "=X")
1709 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1710 "TARGET_64BIT"
1711 "push{q}\t%q1"
1712 [(set_attr "type" "push")
1713 (set_attr "mode" "DI")])
1714
1715 (define_insn "*push<mode>2"
1716 [(set (match_operand:SWI12 0 "push_operand" "=X")
1717 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1718 "!TARGET_64BIT"
1719 "push{l}\t%k1"
1720 [(set_attr "type" "push")
1721 (set_attr "mode" "SI")])
1722
1723 (define_insn "*push<mode>2_prologue"
1724 [(set (match_operand:W 0 "push_operand" "=<")
1725 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1726 (clobber (mem:BLK (scratch)))]
1727 ""
1728 "push{<imodesuffix>}\t%1"
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "<MODE>")])
1731
1732 (define_insn "*pop<mode>1"
1733 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1734 (match_operand:W 1 "pop_operand" ">"))]
1735 ""
1736 "pop{<imodesuffix>}\t%0"
1737 [(set_attr "type" "pop")
1738 (set_attr "mode" "<MODE>")])
1739
1740 (define_insn "*pop<mode>1_epilogue"
1741 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1742 (match_operand:W 1 "pop_operand" ">"))
1743 (clobber (mem:BLK (scratch)))]
1744 ""
1745 "pop{<imodesuffix>}\t%0"
1746 [(set_attr "type" "pop")
1747 (set_attr "mode" "<MODE>")])
1748 \f
1749 ;; Move instructions.
1750
1751 (define_expand "movoi"
1752 [(set (match_operand:OI 0 "nonimmediate_operand")
1753 (match_operand:OI 1 "general_operand"))]
1754 "TARGET_AVX"
1755 "ix86_expand_move (OImode, operands); DONE;")
1756
1757 (define_expand "movti"
1758 [(set (match_operand:TI 0 "nonimmediate_operand")
1759 (match_operand:TI 1 "nonimmediate_operand"))]
1760 "TARGET_64BIT || TARGET_SSE"
1761 {
1762 if (TARGET_64BIT)
1763 ix86_expand_move (TImode, operands);
1764 else if (push_operand (operands[0], TImode))
1765 ix86_expand_push (TImode, operands[1]);
1766 else
1767 ix86_expand_vector_move (TImode, operands);
1768 DONE;
1769 })
1770
1771 ;; This expands to what emit_move_complex would generate if we didn't
1772 ;; have a movti pattern. Having this avoids problems with reload on
1773 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1774 ;; to have around all the time.
1775 (define_expand "movcdi"
1776 [(set (match_operand:CDI 0 "nonimmediate_operand")
1777 (match_operand:CDI 1 "general_operand"))]
1778 ""
1779 {
1780 if (push_operand (operands[0], CDImode))
1781 emit_move_complex_push (CDImode, operands[0], operands[1]);
1782 else
1783 emit_move_complex_parts (operands[0], operands[1]);
1784 DONE;
1785 })
1786
1787 (define_expand "mov<mode>"
1788 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1789 (match_operand:SWI1248x 1 "general_operand"))]
1790 ""
1791 "ix86_expand_move (<MODE>mode, operands); DONE;")
1792
1793 (define_insn "*mov<mode>_xor"
1794 [(set (match_operand:SWI48 0 "register_operand" "=r")
1795 (match_operand:SWI48 1 "const0_operand"))
1796 (clobber (reg:CC FLAGS_REG))]
1797 "reload_completed"
1798 "xor{l}\t%k0, %k0"
1799 [(set_attr "type" "alu1")
1800 (set_attr "mode" "SI")
1801 (set_attr "length_immediate" "0")])
1802
1803 (define_insn "*mov<mode>_or"
1804 [(set (match_operand:SWI48 0 "register_operand" "=r")
1805 (match_operand:SWI48 1 "const_int_operand"))
1806 (clobber (reg:CC FLAGS_REG))]
1807 "reload_completed
1808 && operands[1] == constm1_rtx"
1809 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1810 [(set_attr "type" "alu1")
1811 (set_attr "mode" "<MODE>")
1812 (set_attr "length_immediate" "1")])
1813
1814 (define_insn "*movoi_internal_avx"
1815 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1816 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1817 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1818 {
1819 switch (which_alternative)
1820 {
1821 case 0:
1822 return standard_sse_constant_opcode (insn, operands[1]);
1823 case 1:
1824 case 2:
1825 if (misaligned_operand (operands[0], OImode)
1826 || misaligned_operand (operands[1], OImode))
1827 {
1828 if (get_attr_mode (insn) == MODE_V8SF)
1829 return "vmovups\t{%1, %0|%0, %1}";
1830 else
1831 return "vmovdqu\t{%1, %0|%0, %1}";
1832 }
1833 else
1834 {
1835 if (get_attr_mode (insn) == MODE_V8SF)
1836 return "vmovaps\t{%1, %0|%0, %1}";
1837 else
1838 return "vmovdqa\t{%1, %0|%0, %1}";
1839 }
1840 default:
1841 gcc_unreachable ();
1842 }
1843 }
1844 [(set_attr "type" "sselog1,ssemov,ssemov")
1845 (set_attr "prefix" "vex")
1846 (set (attr "mode")
1847 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1848 (const_string "V8SF")
1849 (and (eq_attr "alternative" "2")
1850 (match_test "TARGET_SSE_TYPELESS_STORES"))
1851 (const_string "V8SF")
1852 ]
1853 (const_string "OI")))])
1854
1855 (define_insn "*movti_internal_rex64"
1856 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1857 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1858 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1859 {
1860 switch (which_alternative)
1861 {
1862 case 0:
1863 case 1:
1864 return "#";
1865 case 2:
1866 return standard_sse_constant_opcode (insn, operands[1]);
1867 case 3:
1868 case 4:
1869 /* TDmode values are passed as TImode on the stack. Moving them
1870 to stack may result in unaligned memory access. */
1871 if (misaligned_operand (operands[0], TImode)
1872 || misaligned_operand (operands[1], TImode))
1873 {
1874 if (get_attr_mode (insn) == MODE_V4SF)
1875 return "%vmovups\t{%1, %0|%0, %1}";
1876 else
1877 return "%vmovdqu\t{%1, %0|%0, %1}";
1878 }
1879 else
1880 {
1881 if (get_attr_mode (insn) == MODE_V4SF)
1882 return "%vmovaps\t{%1, %0|%0, %1}";
1883 else
1884 return "%vmovdqa\t{%1, %0|%0, %1}";
1885 }
1886 default:
1887 gcc_unreachable ();
1888 }
1889 }
1890 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1891 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1892 (set (attr "mode")
1893 (cond [(eq_attr "alternative" "0,1")
1894 (const_string "DI")
1895 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1896 (const_string "V4SF")
1897 (and (eq_attr "alternative" "4")
1898 (match_test "TARGET_SSE_TYPELESS_STORES"))
1899 (const_string "V4SF")
1900 (match_test "TARGET_AVX")
1901 (const_string "TI")
1902 (match_test "optimize_function_for_size_p (cfun)")
1903 (const_string "V4SF")
1904 ]
1905 (const_string "TI")))])
1906
1907 (define_split
1908 [(set (match_operand:TI 0 "nonimmediate_operand")
1909 (match_operand:TI 1 "general_operand"))]
1910 "reload_completed
1911 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1912 [(const_int 0)]
1913 "ix86_split_long_move (operands); DONE;")
1914
1915 (define_insn "*movti_internal_sse"
1916 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1917 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1918 "TARGET_SSE && !TARGET_64BIT
1919 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1920 {
1921 switch (which_alternative)
1922 {
1923 case 0:
1924 return standard_sse_constant_opcode (insn, operands[1]);
1925 case 1:
1926 case 2:
1927 /* TDmode values are passed as TImode on the stack. Moving them
1928 to stack may result in unaligned memory access. */
1929 if (misaligned_operand (operands[0], TImode)
1930 || misaligned_operand (operands[1], TImode))
1931 {
1932 if (get_attr_mode (insn) == MODE_V4SF)
1933 return "%vmovups\t{%1, %0|%0, %1}";
1934 else
1935 return "%vmovdqu\t{%1, %0|%0, %1}";
1936 }
1937 else
1938 {
1939 if (get_attr_mode (insn) == MODE_V4SF)
1940 return "%vmovaps\t{%1, %0|%0, %1}";
1941 else
1942 return "%vmovdqa\t{%1, %0|%0, %1}";
1943 }
1944 default:
1945 gcc_unreachable ();
1946 }
1947 }
1948 [(set_attr "type" "sselog1,ssemov,ssemov")
1949 (set_attr "prefix" "maybe_vex")
1950 (set (attr "mode")
1951 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1952 (const_string "V4SF")
1953 (and (eq_attr "alternative" "2")
1954 (match_test "TARGET_SSE_TYPELESS_STORES"))
1955 (const_string "V4SF")
1956 (match_test "TARGET_AVX")
1957 (const_string "TI")
1958 (ior (not (match_test "TARGET_SSE2"))
1959 (match_test "optimize_function_for_size_p (cfun)"))
1960 (const_string "V4SF")
1961 ]
1962 (const_string "TI")))])
1963
1964 (define_insn "*movdi_internal_rex64"
1965 [(set (match_operand:DI 0 "nonimmediate_operand"
1966 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1967 (match_operand:DI 1 "general_operand"
1968 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1969 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1970 {
1971 switch (get_attr_type (insn))
1972 {
1973 case TYPE_SSECVT:
1974 if (SSE_REG_P (operands[0]))
1975 return "movq2dq\t{%1, %0|%0, %1}";
1976 else
1977 return "movdq2q\t{%1, %0|%0, %1}";
1978
1979 case TYPE_SSEMOV:
1980 if (get_attr_mode (insn) == MODE_V4SF)
1981 return "%vmovaps\t{%1, %0|%0, %1}";
1982 else if (get_attr_mode (insn) == MODE_TI)
1983 return "%vmovdqa\t{%1, %0|%0, %1}";
1984
1985 /* Handle broken assemblers that require movd instead of movq. */
1986 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1987 return "%vmovd\t{%1, %0|%0, %1}";
1988 else
1989 return "%vmovq\t{%1, %0|%0, %1}";
1990
1991 case TYPE_MMXMOV:
1992 /* Handle broken assemblers that require movd instead of movq. */
1993 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1994 return "movd\t{%1, %0|%0, %1}";
1995 else
1996 return "movq\t{%1, %0|%0, %1}";
1997
1998 case TYPE_SSELOG1:
1999 return standard_sse_constant_opcode (insn, operands[1]);
2000
2001 case TYPE_MMX:
2002 return "pxor\t%0, %0";
2003
2004 case TYPE_MULTI:
2005 return "#";
2006
2007 case TYPE_LEA:
2008 return "lea{q}\t{%E1, %0|%0, %E1}";
2009
2010 default:
2011 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2012 if (get_attr_mode (insn) == MODE_SI)
2013 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2014 else if (which_alternative == 2)
2015 return "movabs{q}\t{%1, %0|%0, %1}";
2016 else if (ix86_use_lea_for_mov (insn, operands))
2017 return "lea{q}\t{%E1, %0|%0, %E1}";
2018 else
2019 return "mov{q}\t{%1, %0|%0, %1}";
2020 }
2021 }
2022 [(set (attr "type")
2023 (cond [(eq_attr "alternative" "4")
2024 (const_string "multi")
2025 (eq_attr "alternative" "5")
2026 (const_string "mmx")
2027 (eq_attr "alternative" "6,7,8,9")
2028 (const_string "mmxmov")
2029 (eq_attr "alternative" "10")
2030 (const_string "sselog1")
2031 (eq_attr "alternative" "11,12,13,14,15")
2032 (const_string "ssemov")
2033 (eq_attr "alternative" "16,17")
2034 (const_string "ssecvt")
2035 (match_operand 1 "pic_32bit_operand")
2036 (const_string "lea")
2037 ]
2038 (const_string "imov")))
2039 (set (attr "modrm")
2040 (if_then_else
2041 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2042 (const_string "0")
2043 (const_string "*")))
2044 (set (attr "length_immediate")
2045 (if_then_else
2046 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2047 (const_string "8")
2048 (const_string "*")))
2049 (set (attr "prefix_rex")
2050 (if_then_else (eq_attr "alternative" "8,9")
2051 (const_string "1")
2052 (const_string "*")))
2053 (set (attr "prefix_data16")
2054 (if_then_else (eq_attr "alternative" "11")
2055 (const_string "1")
2056 (const_string "*")))
2057 (set (attr "prefix")
2058 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2059 (const_string "maybe_vex")
2060 (const_string "orig")))
2061 (set (attr "mode")
2062 (cond [(eq_attr "alternative" "0,4")
2063 (const_string "SI")
2064 (eq_attr "alternative" "10,12")
2065 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2066 (const_string "V4SF")
2067 (match_test "TARGET_AVX")
2068 (const_string "TI")
2069 (match_test "optimize_function_for_size_p (cfun)")
2070 (const_string "V4SF")
2071 ]
2072 (const_string "TI"))
2073 ]
2074 (const_string "DI")))])
2075
2076 ;; Reload patterns to support multi-word load/store
2077 ;; with non-offsetable address.
2078 (define_expand "reload_noff_store"
2079 [(parallel [(match_operand 0 "memory_operand" "=m")
2080 (match_operand 1 "register_operand" "r")
2081 (match_operand:DI 2 "register_operand" "=&r")])]
2082 "TARGET_64BIT"
2083 {
2084 rtx mem = operands[0];
2085 rtx addr = XEXP (mem, 0);
2086
2087 emit_move_insn (operands[2], addr);
2088 mem = replace_equiv_address_nv (mem, operands[2]);
2089
2090 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2091 DONE;
2092 })
2093
2094 (define_expand "reload_noff_load"
2095 [(parallel [(match_operand 0 "register_operand" "=r")
2096 (match_operand 1 "memory_operand" "m")
2097 (match_operand:DI 2 "register_operand" "=r")])]
2098 "TARGET_64BIT"
2099 {
2100 rtx mem = operands[1];
2101 rtx addr = XEXP (mem, 0);
2102
2103 emit_move_insn (operands[2], addr);
2104 mem = replace_equiv_address_nv (mem, operands[2]);
2105
2106 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2107 DONE;
2108 })
2109
2110 ;; Convert impossible stores of immediate to existing instructions.
2111 ;; First try to get scratch register and go through it. In case this
2112 ;; fails, move by 32bit parts.
2113 (define_peephole2
2114 [(match_scratch:DI 2 "r")
2115 (set (match_operand:DI 0 "memory_operand")
2116 (match_operand:DI 1 "immediate_operand"))]
2117 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2118 && !x86_64_immediate_operand (operands[1], DImode)"
2119 [(set (match_dup 2) (match_dup 1))
2120 (set (match_dup 0) (match_dup 2))])
2121
2122 ;; We need to define this as both peepholer and splitter for case
2123 ;; peephole2 pass is not run.
2124 ;; "&& 1" is needed to keep it from matching the previous pattern.
2125 (define_peephole2
2126 [(set (match_operand:DI 0 "memory_operand")
2127 (match_operand:DI 1 "immediate_operand"))]
2128 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2129 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2130 [(set (match_dup 2) (match_dup 3))
2131 (set (match_dup 4) (match_dup 5))]
2132 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2133
2134 (define_split
2135 [(set (match_operand:DI 0 "memory_operand")
2136 (match_operand:DI 1 "immediate_operand"))]
2137 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2138 ? epilogue_completed : reload_completed)
2139 && !symbolic_operand (operands[1], DImode)
2140 && !x86_64_immediate_operand (operands[1], DImode)"
2141 [(set (match_dup 2) (match_dup 3))
2142 (set (match_dup 4) (match_dup 5))]
2143 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2144
2145 (define_insn "*movdi_internal"
2146 [(set (match_operand:DI 0 "nonimmediate_operand"
2147 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2148 (match_operand:DI 1 "general_operand"
2149 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2150 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2151 {
2152 switch (get_attr_type (insn))
2153 {
2154 case TYPE_SSECVT:
2155 if (SSE_REG_P (operands[0]))
2156 return "movq2dq\t{%1, %0|%0, %1}";
2157 else
2158 return "movdq2q\t{%1, %0|%0, %1}";
2159
2160 case TYPE_SSEMOV:
2161 switch (get_attr_mode (insn))
2162 {
2163 case MODE_TI:
2164 return "%vmovdqa\t{%1, %0|%0, %1}";
2165 case MODE_DI:
2166 return "%vmovq\t{%1, %0|%0, %1}";
2167 case MODE_V4SF:
2168 return "%vmovaps\t{%1, %0|%0, %1}";
2169 case MODE_V2SF:
2170 return "movlps\t{%1, %0|%0, %1}";
2171 default:
2172 gcc_unreachable ();
2173 }
2174
2175 case TYPE_MMXMOV:
2176 return "movq\t{%1, %0|%0, %1}";
2177
2178 case TYPE_SSELOG1:
2179 return standard_sse_constant_opcode (insn, operands[1]);
2180
2181 case TYPE_MMX:
2182 return "pxor\t%0, %0";
2183
2184 case TYPE_MULTI:
2185 return "#";
2186
2187 default:
2188 gcc_unreachable ();
2189 }
2190 }
2191 [(set (attr "isa")
2192 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2193 (const_string "sse2")
2194 (eq_attr "alternative" "9,10,11,12")
2195 (const_string "noavx")
2196 ]
2197 (const_string "*")))
2198 (set (attr "type")
2199 (cond [(eq_attr "alternative" "0,1")
2200 (const_string "multi")
2201 (eq_attr "alternative" "2")
2202 (const_string "mmx")
2203 (eq_attr "alternative" "3,4")
2204 (const_string "mmxmov")
2205 (eq_attr "alternative" "5,9")
2206 (const_string "sselog1")
2207 (eq_attr "alternative" "13,14")
2208 (const_string "ssecvt")
2209 ]
2210 (const_string "ssemov")))
2211 (set (attr "prefix")
2212 (if_then_else (eq_attr "alternative" "5,6,7,8")
2213 (const_string "maybe_vex")
2214 (const_string "orig")))
2215 (set (attr "mode")
2216 (cond [(eq_attr "alternative" "9,11")
2217 (const_string "V4SF")
2218 (eq_attr "alternative" "10,12")
2219 (const_string "V2SF")
2220 (eq_attr "alternative" "5,7")
2221 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2222 (const_string "V4SF")
2223 (match_test "TARGET_AVX")
2224 (const_string "TI")
2225 (match_test "optimize_function_for_size_p (cfun)")
2226 (const_string "V4SF")
2227 ]
2228 (const_string "TI"))
2229 ]
2230 (const_string "DI")))])
2231
2232 (define_split
2233 [(set (match_operand:DI 0 "nonimmediate_operand")
2234 (match_operand:DI 1 "general_operand"))]
2235 "!TARGET_64BIT && reload_completed
2236 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2237 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2238 [(const_int 0)]
2239 "ix86_split_long_move (operands); DONE;")
2240
2241 (define_insn "*movsi_internal"
2242 [(set (match_operand:SI 0 "nonimmediate_operand"
2243 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2244 (match_operand:SI 1 "general_operand"
2245 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2246 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2247 {
2248 switch (get_attr_type (insn))
2249 {
2250 case TYPE_SSELOG1:
2251 return standard_sse_constant_opcode (insn, operands[1]);
2252
2253 case TYPE_SSEMOV:
2254 switch (get_attr_mode (insn))
2255 {
2256 case MODE_TI:
2257 return "%vmovdqa\t{%1, %0|%0, %1}";
2258 case MODE_V4SF:
2259 return "%vmovaps\t{%1, %0|%0, %1}";
2260 case MODE_SI:
2261 return "%vmovd\t{%1, %0|%0, %1}";
2262 case MODE_SF:
2263 return "%vmovss\t{%1, %0|%0, %1}";
2264 default:
2265 gcc_unreachable ();
2266 }
2267
2268 case TYPE_MMX:
2269 return "pxor\t%0, %0";
2270
2271 case TYPE_MMXMOV:
2272 if (get_attr_mode (insn) == MODE_DI)
2273 return "movq\t{%1, %0|%0, %1}";
2274 return "movd\t{%1, %0|%0, %1}";
2275
2276 case TYPE_LEA:
2277 return "lea{l}\t{%E1, %0|%0, %E1}";
2278
2279 default:
2280 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2281 if (ix86_use_lea_for_mov (insn, operands))
2282 return "lea{l}\t{%E1, %0|%0, %E1}";
2283 else
2284 return "mov{l}\t{%1, %0|%0, %1}";
2285 }
2286 }
2287 [(set (attr "type")
2288 (cond [(eq_attr "alternative" "2")
2289 (const_string "mmx")
2290 (eq_attr "alternative" "3,4,5")
2291 (const_string "mmxmov")
2292 (eq_attr "alternative" "6")
2293 (const_string "sselog1")
2294 (eq_attr "alternative" "7,8,9,10,11")
2295 (const_string "ssemov")
2296 (match_operand 1 "pic_32bit_operand")
2297 (const_string "lea")
2298 ]
2299 (const_string "imov")))
2300 (set (attr "prefix")
2301 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2302 (const_string "orig")
2303 (const_string "maybe_vex")))
2304 (set (attr "prefix_data16")
2305 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2306 (const_string "1")
2307 (const_string "*")))
2308 (set (attr "mode")
2309 (cond [(eq_attr "alternative" "2,3")
2310 (const_string "DI")
2311 (eq_attr "alternative" "6,7")
2312 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2313 (const_string "V4SF")
2314 (match_test "TARGET_AVX")
2315 (const_string "TI")
2316 (ior (not (match_test "TARGET_SSE2"))
2317 (match_test "optimize_function_for_size_p (cfun)"))
2318 (const_string "V4SF")
2319 ]
2320 (const_string "TI"))
2321 (and (eq_attr "alternative" "8,9,10,11")
2322 (not (match_test "TARGET_SSE2")))
2323 (const_string "SF")
2324 ]
2325 (const_string "SI")))])
2326
2327 (define_insn "*movhi_internal"
2328 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2329 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2330 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2331 {
2332 switch (get_attr_type (insn))
2333 {
2334 case TYPE_IMOVX:
2335 /* movzwl is faster than movw on p2 due to partial word stalls,
2336 though not as fast as an aligned movl. */
2337 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2338 default:
2339 if (get_attr_mode (insn) == MODE_SI)
2340 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2341 else
2342 return "mov{w}\t{%1, %0|%0, %1}";
2343 }
2344 }
2345 [(set (attr "type")
2346 (cond [(match_test "optimize_function_for_size_p (cfun)")
2347 (const_string "imov")
2348 (and (eq_attr "alternative" "0")
2349 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2350 (not (match_test "TARGET_HIMODE_MATH"))))
2351 (const_string "imov")
2352 (and (eq_attr "alternative" "1,2")
2353 (match_operand:HI 1 "aligned_operand"))
2354 (const_string "imov")
2355 (and (match_test "TARGET_MOVX")
2356 (eq_attr "alternative" "0,2"))
2357 (const_string "imovx")
2358 ]
2359 (const_string "imov")))
2360 (set (attr "mode")
2361 (cond [(eq_attr "type" "imovx")
2362 (const_string "SI")
2363 (and (eq_attr "alternative" "1,2")
2364 (match_operand:HI 1 "aligned_operand"))
2365 (const_string "SI")
2366 (and (eq_attr "alternative" "0")
2367 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2368 (not (match_test "TARGET_HIMODE_MATH"))))
2369 (const_string "SI")
2370 ]
2371 (const_string "HI")))])
2372
2373 ;; Situation is quite tricky about when to choose full sized (SImode) move
2374 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2375 ;; partial register dependency machines (such as AMD Athlon), where QImode
2376 ;; moves issue extra dependency and for partial register stalls machines
2377 ;; that don't use QImode patterns (and QImode move cause stall on the next
2378 ;; instruction).
2379 ;;
2380 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2381 ;; register stall machines with, where we use QImode instructions, since
2382 ;; partial register stall can be caused there. Then we use movzx.
2383 (define_insn "*movqi_internal"
2384 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2385 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2386 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2387 {
2388 switch (get_attr_type (insn))
2389 {
2390 case TYPE_IMOVX:
2391 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2392 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2393 default:
2394 if (get_attr_mode (insn) == MODE_SI)
2395 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2396 else
2397 return "mov{b}\t{%1, %0|%0, %1}";
2398 }
2399 }
2400 [(set (attr "type")
2401 (cond [(and (eq_attr "alternative" "5")
2402 (not (match_operand:QI 1 "aligned_operand")))
2403 (const_string "imovx")
2404 (match_test "optimize_function_for_size_p (cfun)")
2405 (const_string "imov")
2406 (and (eq_attr "alternative" "3")
2407 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2408 (not (match_test "TARGET_QIMODE_MATH"))))
2409 (const_string "imov")
2410 (eq_attr "alternative" "3,5")
2411 (const_string "imovx")
2412 (and (match_test "TARGET_MOVX")
2413 (eq_attr "alternative" "2"))
2414 (const_string "imovx")
2415 ]
2416 (const_string "imov")))
2417 (set (attr "mode")
2418 (cond [(eq_attr "alternative" "3,4,5")
2419 (const_string "SI")
2420 (eq_attr "alternative" "6")
2421 (const_string "QI")
2422 (eq_attr "type" "imovx")
2423 (const_string "SI")
2424 (and (eq_attr "type" "imov")
2425 (and (eq_attr "alternative" "0,1")
2426 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2427 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2428 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2429 (const_string "SI")
2430 ;; Avoid partial register stalls when not using QImode arithmetic
2431 (and (eq_attr "type" "imov")
2432 (and (eq_attr "alternative" "0,1")
2433 (and (match_test "TARGET_PARTIAL_REG_STALL")
2434 (not (match_test "TARGET_QIMODE_MATH")))))
2435 (const_string "SI")
2436 ]
2437 (const_string "QI")))])
2438
2439 ;; Stores and loads of ax to arbitrary constant address.
2440 ;; We fake an second form of instruction to force reload to load address
2441 ;; into register when rax is not available
2442 (define_insn "*movabs<mode>_1"
2443 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2444 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2445 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2446 "@
2447 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2448 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2449 [(set_attr "type" "imov")
2450 (set_attr "modrm" "0,*")
2451 (set_attr "length_address" "8,0")
2452 (set_attr "length_immediate" "0,*")
2453 (set_attr "memory" "store")
2454 (set_attr "mode" "<MODE>")])
2455
2456 (define_insn "*movabs<mode>_2"
2457 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2458 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2459 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2460 "@
2461 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2462 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2463 [(set_attr "type" "imov")
2464 (set_attr "modrm" "0,*")
2465 (set_attr "length_address" "8,0")
2466 (set_attr "length_immediate" "0")
2467 (set_attr "memory" "load")
2468 (set_attr "mode" "<MODE>")])
2469
2470 (define_insn "swap<mode>"
2471 [(set (match_operand:SWI48 0 "register_operand" "+r")
2472 (match_operand:SWI48 1 "register_operand" "+r"))
2473 (set (match_dup 1)
2474 (match_dup 0))]
2475 ""
2476 "xchg{<imodesuffix>}\t%1, %0"
2477 [(set_attr "type" "imov")
2478 (set_attr "mode" "<MODE>")
2479 (set_attr "pent_pair" "np")
2480 (set_attr "athlon_decode" "vector")
2481 (set_attr "amdfam10_decode" "double")
2482 (set_attr "bdver1_decode" "double")])
2483
2484 (define_insn "*swap<mode>_1"
2485 [(set (match_operand:SWI12 0 "register_operand" "+r")
2486 (match_operand:SWI12 1 "register_operand" "+r"))
2487 (set (match_dup 1)
2488 (match_dup 0))]
2489 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2490 "xchg{l}\t%k1, %k0"
2491 [(set_attr "type" "imov")
2492 (set_attr "mode" "SI")
2493 (set_attr "pent_pair" "np")
2494 (set_attr "athlon_decode" "vector")
2495 (set_attr "amdfam10_decode" "double")
2496 (set_attr "bdver1_decode" "double")])
2497
2498 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2499 ;; is disabled for AMDFAM10
2500 (define_insn "*swap<mode>_2"
2501 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2502 (match_operand:SWI12 1 "register_operand" "+<r>"))
2503 (set (match_dup 1)
2504 (match_dup 0))]
2505 "TARGET_PARTIAL_REG_STALL"
2506 "xchg{<imodesuffix>}\t%1, %0"
2507 [(set_attr "type" "imov")
2508 (set_attr "mode" "<MODE>")
2509 (set_attr "pent_pair" "np")
2510 (set_attr "athlon_decode" "vector")])
2511
2512 (define_expand "movstrict<mode>"
2513 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2514 (match_operand:SWI12 1 "general_operand"))]
2515 ""
2516 {
2517 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2518 FAIL;
2519 if (GET_CODE (operands[0]) == SUBREG
2520 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2521 FAIL;
2522 /* Don't generate memory->memory moves, go through a register */
2523 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2524 operands[1] = force_reg (<MODE>mode, operands[1]);
2525 })
2526
2527 (define_insn "*movstrict<mode>_1"
2528 [(set (strict_low_part
2529 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2530 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2531 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2532 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2533 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2534 [(set_attr "type" "imov")
2535 (set_attr "mode" "<MODE>")])
2536
2537 (define_insn "*movstrict<mode>_xor"
2538 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2539 (match_operand:SWI12 1 "const0_operand"))
2540 (clobber (reg:CC FLAGS_REG))]
2541 "reload_completed"
2542 "xor{<imodesuffix>}\t%0, %0"
2543 [(set_attr "type" "alu1")
2544 (set_attr "mode" "<MODE>")
2545 (set_attr "length_immediate" "0")])
2546
2547 (define_insn "*mov<mode>_extv_1"
2548 [(set (match_operand:SWI24 0 "register_operand" "=R")
2549 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2550 (const_int 8)
2551 (const_int 8)))]
2552 ""
2553 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2554 [(set_attr "type" "imovx")
2555 (set_attr "mode" "SI")])
2556
2557 (define_insn "*movqi_extv_1_rex64"
2558 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2559 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2560 (const_int 8)
2561 (const_int 8)))]
2562 "TARGET_64BIT"
2563 {
2564 switch (get_attr_type (insn))
2565 {
2566 case TYPE_IMOVX:
2567 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2568 default:
2569 return "mov{b}\t{%h1, %0|%0, %h1}";
2570 }
2571 }
2572 [(set (attr "type")
2573 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2574 (match_test "TARGET_MOVX"))
2575 (const_string "imovx")
2576 (const_string "imov")))
2577 (set (attr "mode")
2578 (if_then_else (eq_attr "type" "imovx")
2579 (const_string "SI")
2580 (const_string "QI")))])
2581
2582 (define_insn "*movqi_extv_1"
2583 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2584 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2585 (const_int 8)
2586 (const_int 8)))]
2587 "!TARGET_64BIT"
2588 {
2589 switch (get_attr_type (insn))
2590 {
2591 case TYPE_IMOVX:
2592 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2593 default:
2594 return "mov{b}\t{%h1, %0|%0, %h1}";
2595 }
2596 }
2597 [(set (attr "type")
2598 (if_then_else (and (match_operand:QI 0 "register_operand")
2599 (ior (not (match_operand:QI 0 "QIreg_operand"))
2600 (match_test "TARGET_MOVX")))
2601 (const_string "imovx")
2602 (const_string "imov")))
2603 (set (attr "mode")
2604 (if_then_else (eq_attr "type" "imovx")
2605 (const_string "SI")
2606 (const_string "QI")))])
2607
2608 (define_insn "*mov<mode>_extzv_1"
2609 [(set (match_operand:SWI48 0 "register_operand" "=R")
2610 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2611 (const_int 8)
2612 (const_int 8)))]
2613 ""
2614 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2615 [(set_attr "type" "imovx")
2616 (set_attr "mode" "SI")])
2617
2618 (define_insn "*movqi_extzv_2_rex64"
2619 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2620 (subreg:QI
2621 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2622 (const_int 8)
2623 (const_int 8)) 0))]
2624 "TARGET_64BIT"
2625 {
2626 switch (get_attr_type (insn))
2627 {
2628 case TYPE_IMOVX:
2629 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2630 default:
2631 return "mov{b}\t{%h1, %0|%0, %h1}";
2632 }
2633 }
2634 [(set (attr "type")
2635 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2636 (match_test "TARGET_MOVX"))
2637 (const_string "imovx")
2638 (const_string "imov")))
2639 (set (attr "mode")
2640 (if_then_else (eq_attr "type" "imovx")
2641 (const_string "SI")
2642 (const_string "QI")))])
2643
2644 (define_insn "*movqi_extzv_2"
2645 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2646 (subreg:QI
2647 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2648 (const_int 8)
2649 (const_int 8)) 0))]
2650 "!TARGET_64BIT"
2651 {
2652 switch (get_attr_type (insn))
2653 {
2654 case TYPE_IMOVX:
2655 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2656 default:
2657 return "mov{b}\t{%h1, %0|%0, %h1}";
2658 }
2659 }
2660 [(set (attr "type")
2661 (if_then_else (and (match_operand:QI 0 "register_operand")
2662 (ior (not (match_operand:QI 0 "QIreg_operand"))
2663 (match_test "TARGET_MOVX")))
2664 (const_string "imovx")
2665 (const_string "imov")))
2666 (set (attr "mode")
2667 (if_then_else (eq_attr "type" "imovx")
2668 (const_string "SI")
2669 (const_string "QI")))])
2670
2671 (define_expand "mov<mode>_insv_1"
2672 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2673 (const_int 8)
2674 (const_int 8))
2675 (match_operand:SWI48 1 "nonmemory_operand"))])
2676
2677 (define_insn "*mov<mode>_insv_1_rex64"
2678 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2679 (const_int 8)
2680 (const_int 8))
2681 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2682 "TARGET_64BIT"
2683 "mov{b}\t{%b1, %h0|%h0, %b1}"
2684 [(set_attr "type" "imov")
2685 (set_attr "mode" "QI")])
2686
2687 (define_insn "*movsi_insv_1"
2688 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2689 (const_int 8)
2690 (const_int 8))
2691 (match_operand:SI 1 "general_operand" "Qmn"))]
2692 "!TARGET_64BIT"
2693 "mov{b}\t{%b1, %h0|%h0, %b1}"
2694 [(set_attr "type" "imov")
2695 (set_attr "mode" "QI")])
2696
2697 (define_insn "*movqi_insv_2"
2698 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2699 (const_int 8)
2700 (const_int 8))
2701 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2702 (const_int 8)))]
2703 ""
2704 "mov{b}\t{%h1, %h0|%h0, %h1}"
2705 [(set_attr "type" "imov")
2706 (set_attr "mode" "QI")])
2707 \f
2708 ;; Floating point push instructions.
2709
2710 (define_insn "*pushtf"
2711 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2712 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2713 "TARGET_SSE"
2714 {
2715 /* This insn should be already split before reg-stack. */
2716 gcc_unreachable ();
2717 }
2718 [(set_attr "type" "multi")
2719 (set_attr "unit" "sse,*,*")
2720 (set_attr "mode" "TF,SI,SI")])
2721
2722 ;; %%% Kill this when call knows how to work this out.
2723 (define_split
2724 [(set (match_operand:TF 0 "push_operand")
2725 (match_operand:TF 1 "sse_reg_operand"))]
2726 "TARGET_SSE && reload_completed"
2727 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2728 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2729
2730 (define_insn "*pushxf"
2731 [(set (match_operand:XF 0 "push_operand" "=<,<")
2732 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2733 "optimize_function_for_speed_p (cfun)"
2734 {
2735 /* This insn should be already split before reg-stack. */
2736 gcc_unreachable ();
2737 }
2738 [(set_attr "type" "multi")
2739 (set_attr "unit" "i387,*")
2740 (set_attr "mode" "XF,SI")])
2741
2742 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2743 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2744 ;; Pushing using integer instructions is longer except for constants
2745 ;; and direct memory references (assuming that any given constant is pushed
2746 ;; only once, but this ought to be handled elsewhere).
2747
2748 (define_insn "*pushxf_nointeger"
2749 [(set (match_operand:XF 0 "push_operand" "=<,<")
2750 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2751 "optimize_function_for_size_p (cfun)"
2752 {
2753 /* This insn should be already split before reg-stack. */
2754 gcc_unreachable ();
2755 }
2756 [(set_attr "type" "multi")
2757 (set_attr "unit" "i387,*")
2758 (set_attr "mode" "XF,SI")])
2759
2760 ;; %%% Kill this when call knows how to work this out.
2761 (define_split
2762 [(set (match_operand:XF 0 "push_operand")
2763 (match_operand:XF 1 "fp_register_operand"))]
2764 "reload_completed"
2765 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2766 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2767 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2768
2769 (define_insn "*pushdf_rex64"
2770 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2771 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2772 "TARGET_64BIT"
2773 {
2774 /* This insn should be already split before reg-stack. */
2775 gcc_unreachable ();
2776 }
2777 [(set_attr "type" "multi")
2778 (set_attr "unit" "i387,*,*")
2779 (set_attr "mode" "DF,DI,DF")])
2780
2781 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2782 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2783 ;; On the average, pushdf using integers can be still shorter.
2784
2785 (define_insn "*pushdf"
2786 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2787 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2788 "!TARGET_64BIT"
2789 {
2790 /* This insn should be already split before reg-stack. */
2791 gcc_unreachable ();
2792 }
2793 [(set_attr "isa" "*,*,sse2")
2794 (set_attr "type" "multi")
2795 (set_attr "unit" "i387,*,*")
2796 (set_attr "mode" "DF,DI,DF")])
2797
2798 ;; %%% Kill this when call knows how to work this out.
2799 (define_split
2800 [(set (match_operand:DF 0 "push_operand")
2801 (match_operand:DF 1 "any_fp_register_operand"))]
2802 "reload_completed"
2803 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2804 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2805
2806 (define_insn "*pushsf_rex64"
2807 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2808 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2809 "TARGET_64BIT"
2810 {
2811 /* Anything else should be already split before reg-stack. */
2812 gcc_assert (which_alternative == 1);
2813 return "push{q}\t%q1";
2814 }
2815 [(set_attr "type" "multi,push,multi")
2816 (set_attr "unit" "i387,*,*")
2817 (set_attr "mode" "SF,DI,SF")])
2818
2819 (define_insn "*pushsf"
2820 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2821 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2822 "!TARGET_64BIT"
2823 {
2824 /* Anything else should be already split before reg-stack. */
2825 gcc_assert (which_alternative == 1);
2826 return "push{l}\t%1";
2827 }
2828 [(set_attr "type" "multi,push,multi")
2829 (set_attr "unit" "i387,*,*")
2830 (set_attr "mode" "SF,SI,SF")])
2831
2832 ;; %%% Kill this when call knows how to work this out.
2833 (define_split
2834 [(set (match_operand:SF 0 "push_operand")
2835 (match_operand:SF 1 "any_fp_register_operand"))]
2836 "reload_completed"
2837 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2838 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2839 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2840
2841 (define_split
2842 [(set (match_operand:SF 0 "push_operand")
2843 (match_operand:SF 1 "memory_operand"))]
2844 "reload_completed
2845 && (operands[2] = find_constant_src (insn))"
2846 [(set (match_dup 0) (match_dup 2))])
2847
2848 (define_split
2849 [(set (match_operand 0 "push_operand")
2850 (match_operand 1 "general_operand"))]
2851 "reload_completed
2852 && (GET_MODE (operands[0]) == TFmode
2853 || GET_MODE (operands[0]) == XFmode
2854 || GET_MODE (operands[0]) == DFmode)
2855 && !ANY_FP_REG_P (operands[1])"
2856 [(const_int 0)]
2857 "ix86_split_long_move (operands); DONE;")
2858 \f
2859 ;; Floating point move instructions.
2860
2861 (define_expand "movtf"
2862 [(set (match_operand:TF 0 "nonimmediate_operand")
2863 (match_operand:TF 1 "nonimmediate_operand"))]
2864 "TARGET_SSE"
2865 {
2866 ix86_expand_move (TFmode, operands);
2867 DONE;
2868 })
2869
2870 (define_expand "mov<mode>"
2871 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2872 (match_operand:X87MODEF 1 "general_operand"))]
2873 ""
2874 "ix86_expand_move (<MODE>mode, operands); DONE;")
2875
2876 (define_insn "*movtf_internal"
2877 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2878 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,F*r"))]
2879 "TARGET_SSE
2880 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2881 && (!can_create_pseudo_p ()
2882 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2883 || GET_CODE (operands[1]) != CONST_DOUBLE
2884 || (optimize_function_for_size_p (cfun)
2885 && standard_sse_constant_p (operands[1])
2886 && !memory_operand (operands[0], TFmode))
2887 || (!TARGET_MEMORY_MISMATCH_STALL
2888 && memory_operand (operands[0], TFmode)))"
2889 {
2890 switch (which_alternative)
2891 {
2892 case 0:
2893 return standard_sse_constant_opcode (insn, operands[1]);
2894 case 1:
2895 case 2:
2896 /* Handle misaligned load/store since we
2897 don't have movmisaligntf pattern. */
2898 if (misaligned_operand (operands[0], TFmode)
2899 || misaligned_operand (operands[1], TFmode))
2900 {
2901 if (get_attr_mode (insn) == MODE_V4SF)
2902 return "%vmovups\t{%1, %0|%0, %1}";
2903 else
2904 return "%vmovdqu\t{%1, %0|%0, %1}";
2905 }
2906 else
2907 {
2908 if (get_attr_mode (insn) == MODE_V4SF)
2909 return "%vmovaps\t{%1, %0|%0, %1}";
2910 else
2911 return "%vmovdqa\t{%1, %0|%0, %1}";
2912 }
2913
2914 case 3:
2915 case 4:
2916 return "#";
2917
2918 default:
2919 gcc_unreachable ();
2920 }
2921 }
2922 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2923 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2924 (set (attr "mode")
2925 (cond [(eq_attr "alternative" "3,4")
2926 (const_string "DI")
2927 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2928 (const_string "V4SF")
2929 (and (eq_attr "alternative" "2")
2930 (match_test "TARGET_SSE_TYPELESS_STORES"))
2931 (const_string "V4SF")
2932 (match_test "TARGET_AVX")
2933 (const_string "TI")
2934 (ior (not (match_test "TARGET_SSE2"))
2935 (match_test "optimize_function_for_size_p (cfun)"))
2936 (const_string "V4SF")
2937 ]
2938 (const_string "TI")))])
2939
2940 ;; Possible store forwarding (partial memory) stall in alternative 4.
2941 (define_insn "*movxf_internal"
2942 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2943 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2944 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2945 && (!can_create_pseudo_p ()
2946 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2947 || GET_CODE (operands[1]) != CONST_DOUBLE
2948 || (optimize_function_for_size_p (cfun)
2949 && standard_80387_constant_p (operands[1]) > 0
2950 && !memory_operand (operands[0], XFmode))
2951 || (!TARGET_MEMORY_MISMATCH_STALL
2952 && memory_operand (operands[0], XFmode)))"
2953 {
2954 switch (which_alternative)
2955 {
2956 case 0:
2957 case 1:
2958 return output_387_reg_move (insn, operands);
2959
2960 case 2:
2961 return standard_80387_constant_opcode (operands[1]);
2962
2963 case 3:
2964 case 4:
2965 return "#";
2966
2967 default:
2968 gcc_unreachable ();
2969 }
2970 }
2971 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2972 (set_attr "mode" "XF,XF,XF,SI,SI")])
2973
2974 (define_insn "*movdf_internal_rex64"
2975 [(set (match_operand:DF 0 "nonimmediate_operand"
2976 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2977 (match_operand:DF 1 "general_operand"
2978 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2979 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2980 && (!can_create_pseudo_p ()
2981 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2982 || GET_CODE (operands[1]) != CONST_DOUBLE
2983 || (optimize_function_for_size_p (cfun)
2984 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2985 && standard_80387_constant_p (operands[1]) > 0)
2986 || (TARGET_SSE2 && TARGET_SSE_MATH
2987 && standard_sse_constant_p (operands[1]))))
2988 || memory_operand (operands[0], DFmode))"
2989 {
2990 switch (which_alternative)
2991 {
2992 case 0:
2993 case 1:
2994 return output_387_reg_move (insn, operands);
2995
2996 case 2:
2997 return standard_80387_constant_opcode (operands[1]);
2998
2999 case 3:
3000 case 4:
3001 return "mov{q}\t{%1, %0|%0, %1}";
3002
3003 case 5:
3004 return "movabs{q}\t{%1, %0|%0, %1}";
3005
3006 case 6:
3007 return "#";
3008
3009 case 7:
3010 return standard_sse_constant_opcode (insn, operands[1]);
3011
3012 case 8:
3013 case 9:
3014 case 10:
3015 switch (get_attr_mode (insn))
3016 {
3017 case MODE_V2DF:
3018 return "%vmovapd\t{%1, %0|%0, %1}";
3019 case MODE_V4SF:
3020 return "%vmovaps\t{%1, %0|%0, %1}";
3021
3022 case MODE_DI:
3023 return "%vmovq\t{%1, %0|%0, %1}";
3024 case MODE_DF:
3025 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3026 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3027 return "%vmovsd\t{%1, %0|%0, %1}";
3028 case MODE_V1DF:
3029 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3030 case MODE_V2SF:
3031 return "%vmovlps\t{%1, %d0|%d0, %1}";
3032 default:
3033 gcc_unreachable ();
3034 }
3035
3036 case 11:
3037 case 12:
3038 /* Handle broken assemblers that require movd instead of movq. */
3039 return "%vmovd\t{%1, %0|%0, %1}";
3040
3041 default:
3042 gcc_unreachable();
3043 }
3044 }
3045 [(set (attr "type")
3046 (cond [(eq_attr "alternative" "0,1,2")
3047 (const_string "fmov")
3048 (eq_attr "alternative" "3,4,5")
3049 (const_string "imov")
3050 (eq_attr "alternative" "6")
3051 (const_string "multi")
3052 (eq_attr "alternative" "7")
3053 (const_string "sselog1")
3054 ]
3055 (const_string "ssemov")))
3056 (set (attr "modrm")
3057 (if_then_else
3058 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3059 (const_string "0")
3060 (const_string "*")))
3061 (set (attr "length_immediate")
3062 (if_then_else
3063 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3064 (const_string "8")
3065 (const_string "*")))
3066 (set (attr "prefix")
3067 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3068 (const_string "orig")
3069 (const_string "maybe_vex")))
3070 (set (attr "prefix_data16")
3071 (if_then_else (eq_attr "mode" "V1DF")
3072 (const_string "1")
3073 (const_string "*")))
3074 (set (attr "mode")
3075 (cond [(eq_attr "alternative" "0,1,2")
3076 (const_string "DF")
3077 (eq_attr "alternative" "3,4,5,6,11,12")
3078 (const_string "DI")
3079
3080 /* xorps is one byte shorter for !TARGET_AVX. */
3081 (eq_attr "alternative" "7")
3082 (cond [(match_test "TARGET_AVX")
3083 (const_string "V2DF")
3084 (match_test "optimize_function_for_size_p (cfun)")
3085 (const_string "V4SF")
3086 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3087 (const_string "TI")
3088 ]
3089 (const_string "V2DF"))
3090
3091 /* For architectures resolving dependencies on
3092 whole SSE registers use APD move to break dependency
3093 chains, otherwise use short move to avoid extra work.
3094
3095 movaps encodes one byte shorter for !TARGET_AVX. */
3096 (eq_attr "alternative" "8")
3097 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3098 (const_string "V4SF")
3099 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3100 (const_string "V2DF")
3101 (match_test "TARGET_AVX")
3102 (const_string "DF")
3103 (match_test "optimize_function_for_size_p (cfun)")
3104 (const_string "V4SF")
3105 ]
3106 (const_string "DF"))
3107 /* For architectures resolving dependencies on register
3108 parts we may avoid extra work to zero out upper part
3109 of register. */
3110 (eq_attr "alternative" "9")
3111 (if_then_else
3112 (match_test "TARGET_SSE_SPLIT_REGS")
3113 (const_string "V1DF")
3114 (const_string "DF"))
3115 ]
3116 (const_string "DF")))])
3117
3118 ;; Possible store forwarding (partial memory) stall in alternative 4.
3119 (define_insn "*movdf_internal"
3120 [(set (match_operand:DF 0 "nonimmediate_operand"
3121 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3122 (match_operand:DF 1 "general_operand"
3123 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3124 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3125 && (!can_create_pseudo_p ()
3126 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3127 || GET_CODE (operands[1]) != CONST_DOUBLE
3128 || (optimize_function_for_size_p (cfun)
3129 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3130 && standard_80387_constant_p (operands[1]) > 0)
3131 || (TARGET_SSE2 && TARGET_SSE_MATH
3132 && standard_sse_constant_p (operands[1])))
3133 && !memory_operand (operands[0], DFmode))
3134 || (!TARGET_MEMORY_MISMATCH_STALL
3135 && memory_operand (operands[0], DFmode)))"
3136 {
3137 switch (which_alternative)
3138 {
3139 case 0:
3140 case 1:
3141 return output_387_reg_move (insn, operands);
3142
3143 case 2:
3144 return standard_80387_constant_opcode (operands[1]);
3145
3146 case 3:
3147 case 4:
3148 return "#";
3149
3150 case 5:
3151 case 9:
3152 return standard_sse_constant_opcode (insn, operands[1]);
3153
3154 case 6:
3155 case 7:
3156 case 8:
3157 case 10:
3158 case 11:
3159 case 12:
3160 switch (get_attr_mode (insn))
3161 {
3162 case MODE_V2DF:
3163 return "%vmovapd\t{%1, %0|%0, %1}";
3164 case MODE_V4SF:
3165 return "%vmovaps\t{%1, %0|%0, %1}";
3166
3167 case MODE_DI:
3168 return "%vmovq\t{%1, %0|%0, %1}";
3169 case MODE_DF:
3170 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3171 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3172 return "%vmovsd\t{%1, %0|%0, %1}";
3173 case MODE_V1DF:
3174 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3175 case MODE_V2SF:
3176 return "%vmovlps\t{%1, %d0|%d0, %1}";
3177 default:
3178 gcc_unreachable ();
3179 }
3180
3181 default:
3182 gcc_unreachable ();
3183 }
3184 }
3185 [(set (attr "isa")
3186 (if_then_else (eq_attr "alternative" "5,6,7,8")
3187 (const_string "sse2")
3188 (const_string "*")))
3189 (set (attr "type")
3190 (cond [(eq_attr "alternative" "0,1,2")
3191 (const_string "fmov")
3192 (eq_attr "alternative" "3,4")
3193 (const_string "multi")
3194 (eq_attr "alternative" "5,9")
3195 (const_string "sselog1")
3196 ]
3197 (const_string "ssemov")))
3198 (set (attr "prefix")
3199 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3200 (const_string "orig")
3201 (const_string "maybe_vex")))
3202 (set (attr "prefix_data16")
3203 (if_then_else (eq_attr "mode" "V1DF")
3204 (const_string "1")
3205 (const_string "*")))
3206 (set (attr "mode")
3207 (cond [(eq_attr "alternative" "0,1,2")
3208 (const_string "DF")
3209 (eq_attr "alternative" "3,4")
3210 (const_string "SI")
3211
3212 /* For SSE1, we have many fewer alternatives. */
3213 (not (match_test "TARGET_SSE2"))
3214 (if_then_else
3215 (eq_attr "alternative" "5,6,9,10")
3216 (const_string "V4SF")
3217 (const_string "V2SF"))
3218
3219 /* xorps is one byte shorter for !TARGET_AVX. */
3220 (eq_attr "alternative" "5,9")
3221 (cond [(match_test "TARGET_AVX")
3222 (const_string "V2DF")
3223 (match_test "optimize_function_for_size_p (cfun)")
3224 (const_string "V4SF")
3225 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3226 (const_string "TI")
3227 ]
3228 (const_string "V2DF"))
3229
3230 /* For architectures resolving dependencies on
3231 whole SSE registers use APD move to break dependency
3232 chains, otherwise use short move to avoid extra work.
3233
3234 movaps encodes one byte shorter for !TARGET_AVX. */
3235 (eq_attr "alternative" "6,10")
3236 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3237 (const_string "V4SF")
3238 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3239 (const_string "V2DF")
3240 (match_test "TARGET_AVX")
3241 (const_string "DF")
3242 (match_test "optimize_function_for_size_p (cfun)")
3243 (const_string "V4SF")
3244 ]
3245 (const_string "DF"))
3246
3247 /* For architectures resolving dependencies on register
3248 parts we may avoid extra work to zero out upper part
3249 of register. */
3250 (eq_attr "alternative" "7,11")
3251 (if_then_else
3252 (match_test "TARGET_SSE_SPLIT_REGS")
3253 (const_string "V1DF")
3254 (const_string "DF"))
3255 ]
3256 (const_string "DF")))])
3257
3258 (define_insn "*movsf_internal"
3259 [(set (match_operand:SF 0 "nonimmediate_operand"
3260 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3261 (match_operand:SF 1 "general_operand"
3262 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3263 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3264 && (!can_create_pseudo_p ()
3265 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3266 || GET_CODE (operands[1]) != CONST_DOUBLE
3267 || (optimize_function_for_size_p (cfun)
3268 && ((!TARGET_SSE_MATH
3269 && standard_80387_constant_p (operands[1]) > 0)
3270 || (TARGET_SSE_MATH
3271 && standard_sse_constant_p (operands[1]))))
3272 || memory_operand (operands[0], SFmode))"
3273 {
3274 switch (which_alternative)
3275 {
3276 case 0:
3277 case 1:
3278 return output_387_reg_move (insn, operands);
3279
3280 case 2:
3281 return standard_80387_constant_opcode (operands[1]);
3282
3283 case 3:
3284 case 4:
3285 return "mov{l}\t{%1, %0|%0, %1}";
3286
3287 case 5:
3288 return standard_sse_constant_opcode (insn, operands[1]);
3289
3290 case 6:
3291 if (get_attr_mode (insn) == MODE_V4SF)
3292 return "%vmovaps\t{%1, %0|%0, %1}";
3293 if (TARGET_AVX)
3294 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3295
3296 case 7:
3297 case 8:
3298 return "%vmovss\t{%1, %0|%0, %1}";
3299
3300 case 9:
3301 case 10:
3302 case 14:
3303 case 15:
3304 return "movd\t{%1, %0|%0, %1}";
3305
3306 case 11:
3307 return "movq\t{%1, %0|%0, %1}";
3308
3309 case 12:
3310 case 13:
3311 return "%vmovd\t{%1, %0|%0, %1}";
3312
3313 default:
3314 gcc_unreachable ();
3315 }
3316 }
3317 [(set (attr "type")
3318 (cond [(eq_attr "alternative" "0,1,2")
3319 (const_string "fmov")
3320 (eq_attr "alternative" "3,4")
3321 (const_string "multi")
3322 (eq_attr "alternative" "5")
3323 (const_string "sselog1")
3324 (eq_attr "alternative" "9,10,11,14,15")
3325 (const_string "mmxmov")
3326 ]
3327 (const_string "ssemov")))
3328 (set (attr "prefix")
3329 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3330 (const_string "maybe_vex")
3331 (const_string "orig")))
3332 (set (attr "mode")
3333 (cond [(eq_attr "alternative" "3,4,9,10")
3334 (const_string "SI")
3335 (eq_attr "alternative" "5")
3336 (cond [(match_test "TARGET_AVX")
3337 (const_string "V4SF")
3338 (ior (not (match_test "TARGET_SSE2"))
3339 (match_test "optimize_function_for_size_p (cfun)"))
3340 (const_string "V4SF")
3341 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3342 (const_string "TI")
3343 ]
3344 (const_string "V4SF"))
3345
3346 /* For architectures resolving dependencies on
3347 whole SSE registers use APS move to break dependency
3348 chains, otherwise use short move to avoid extra work.
3349
3350 Do the same for architectures resolving dependencies on
3351 the parts. While in DF mode it is better to always handle
3352 just register parts, the SF mode is different due to lack
3353 of instructions to load just part of the register. It is
3354 better to maintain the whole registers in single format
3355 to avoid problems on using packed logical operations. */
3356 (eq_attr "alternative" "6")
3357 (if_then_else
3358 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3359 (match_test "TARGET_SSE_SPLIT_REGS"))
3360 (const_string "V4SF")
3361 (const_string "SF"))
3362 (eq_attr "alternative" "11")
3363 (const_string "DI")]
3364 (const_string "SF")))])
3365
3366 (define_split
3367 [(set (match_operand 0 "any_fp_register_operand")
3368 (match_operand 1 "memory_operand"))]
3369 "reload_completed
3370 && (GET_MODE (operands[0]) == TFmode
3371 || GET_MODE (operands[0]) == XFmode
3372 || GET_MODE (operands[0]) == DFmode
3373 || GET_MODE (operands[0]) == SFmode)
3374 && (operands[2] = find_constant_src (insn))"
3375 [(set (match_dup 0) (match_dup 2))]
3376 {
3377 rtx c = operands[2];
3378 int r = REGNO (operands[0]);
3379
3380 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3381 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3382 FAIL;
3383 })
3384
3385 (define_split
3386 [(set (match_operand 0 "any_fp_register_operand")
3387 (float_extend (match_operand 1 "memory_operand")))]
3388 "reload_completed
3389 && (GET_MODE (operands[0]) == TFmode
3390 || GET_MODE (operands[0]) == XFmode
3391 || GET_MODE (operands[0]) == DFmode)
3392 && (operands[2] = find_constant_src (insn))"
3393 [(set (match_dup 0) (match_dup 2))]
3394 {
3395 rtx c = operands[2];
3396 int r = REGNO (operands[0]);
3397
3398 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3399 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3400 FAIL;
3401 })
3402
3403 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3404 (define_split
3405 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3406 (match_operand:X87MODEF 1 "immediate_operand"))]
3407 "reload_completed
3408 && (standard_80387_constant_p (operands[1]) == 8
3409 || standard_80387_constant_p (operands[1]) == 9)"
3410 [(set (match_dup 0)(match_dup 1))
3411 (set (match_dup 0)
3412 (neg:X87MODEF (match_dup 0)))]
3413 {
3414 REAL_VALUE_TYPE r;
3415
3416 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3417 if (real_isnegzero (&r))
3418 operands[1] = CONST0_RTX (<MODE>mode);
3419 else
3420 operands[1] = CONST1_RTX (<MODE>mode);
3421 })
3422
3423 (define_split
3424 [(set (match_operand 0 "nonimmediate_operand")
3425 (match_operand 1 "general_operand"))]
3426 "reload_completed
3427 && (GET_MODE (operands[0]) == TFmode
3428 || GET_MODE (operands[0]) == XFmode
3429 || GET_MODE (operands[0]) == DFmode)
3430 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3431 [(const_int 0)]
3432 "ix86_split_long_move (operands); DONE;")
3433
3434 (define_insn "swapxf"
3435 [(set (match_operand:XF 0 "register_operand" "+f")
3436 (match_operand:XF 1 "register_operand" "+f"))
3437 (set (match_dup 1)
3438 (match_dup 0))]
3439 "TARGET_80387"
3440 {
3441 if (STACK_TOP_P (operands[0]))
3442 return "fxch\t%1";
3443 else
3444 return "fxch\t%0";
3445 }
3446 [(set_attr "type" "fxch")
3447 (set_attr "mode" "XF")])
3448
3449 (define_insn "*swap<mode>"
3450 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3451 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3452 (set (match_dup 1)
3453 (match_dup 0))]
3454 "TARGET_80387 || reload_completed"
3455 {
3456 if (STACK_TOP_P (operands[0]))
3457 return "fxch\t%1";
3458 else
3459 return "fxch\t%0";
3460 }
3461 [(set_attr "type" "fxch")
3462 (set_attr "mode" "<MODE>")])
3463 \f
3464 ;; Zero extension instructions
3465
3466 (define_expand "zero_extendsidi2"
3467 [(set (match_operand:DI 0 "nonimmediate_operand")
3468 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3469
3470 (define_insn "*zero_extendsidi2_rex64"
3471 [(set (match_operand:DI 0 "nonimmediate_operand"
3472 "=r ,o,?*Ym,?*y,?*Yi,?*x")
3473 (zero_extend:DI
3474 (match_operand:SI 1 "x86_64_zext_general_operand"
3475 "rmWz,0,r ,m ,r ,m")))]
3476 "TARGET_64BIT"
3477 {
3478 switch (get_attr_type (insn))
3479 {
3480 case TYPE_IMOVX:
3481 if (ix86_use_lea_for_mov (insn, operands))
3482 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3483 else
3484 return "mov{l}\t{%1, %k0|%k0, %1}";
3485
3486 case TYPE_MULTI:
3487 return "#";
3488
3489 case TYPE_MMXMOV:
3490 return "movd\t{%1, %0|%0, %1}";
3491
3492 case TYPE_SSEMOV:
3493 return "%vmovd\t{%1, %0|%0, %1}";
3494
3495 default:
3496 gcc_unreachable ();
3497 }
3498 }
3499 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3500 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3501 (set_attr "prefix_0f" "0,*,*,*,*,*")
3502 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3503
3504 (define_insn "*zero_extendsidi2"
3505 [(set (match_operand:DI 0 "nonimmediate_operand"
3506 "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3507 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3508 "0 ,rm,r ,r ,m ,r ,m")))]
3509 "!TARGET_64BIT"
3510 "@
3511 #
3512 #
3513 #
3514 movd\t{%1, %0|%0, %1}
3515 movd\t{%1, %0|%0, %1}
3516 %vmovd\t{%1, %0|%0, %1}
3517 %vmovd\t{%1, %0|%0, %1}"
3518 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3519 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3520 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3521 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3522
3523 (define_split
3524 [(set (match_operand:DI 0 "memory_operand")
3525 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3526 "reload_completed"
3527 [(set (match_dup 4) (const_int 0))]
3528 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3529
3530 (define_split
3531 [(set (match_operand:DI 0 "register_operand")
3532 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3533 "!TARGET_64BIT && reload_completed
3534 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3535 && true_regnum (operands[0]) == true_regnum (operands[1])"
3536 [(set (match_dup 4) (const_int 0))]
3537 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3538
3539 (define_split
3540 [(set (match_operand:DI 0 "nonimmediate_operand")
3541 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3542 "!TARGET_64BIT && reload_completed
3543 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3544 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3545 [(set (match_dup 3) (match_dup 1))
3546 (set (match_dup 4) (const_int 0))]
3547 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3548
3549 (define_insn "zero_extend<mode>di2"
3550 [(set (match_operand:DI 0 "register_operand" "=r")
3551 (zero_extend:DI
3552 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3553 "TARGET_64BIT"
3554 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3555 [(set_attr "type" "imovx")
3556 (set_attr "mode" "SI")])
3557
3558 (define_expand "zero_extend<mode>si2"
3559 [(set (match_operand:SI 0 "register_operand")
3560 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3561 ""
3562 {
3563 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3564 {
3565 operands[1] = force_reg (<MODE>mode, operands[1]);
3566 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3567 DONE;
3568 }
3569 })
3570
3571 (define_insn_and_split "zero_extend<mode>si2_and"
3572 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3573 (zero_extend:SI
3574 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3575 (clobber (reg:CC FLAGS_REG))]
3576 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3577 "#"
3578 "&& reload_completed"
3579 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3580 (clobber (reg:CC FLAGS_REG))])]
3581 {
3582 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3583 {
3584 ix86_expand_clear (operands[0]);
3585
3586 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3587 emit_insn (gen_movstrict<mode>
3588 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3589 DONE;
3590 }
3591
3592 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3593 }
3594 [(set_attr "type" "alu1")
3595 (set_attr "mode" "SI")])
3596
3597 (define_insn "*zero_extend<mode>si2"
3598 [(set (match_operand:SI 0 "register_operand" "=r")
3599 (zero_extend:SI
3600 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3601 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3602 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3603 [(set_attr "type" "imovx")
3604 (set_attr "mode" "SI")])
3605
3606 (define_expand "zero_extendqihi2"
3607 [(set (match_operand:HI 0 "register_operand")
3608 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3609 ""
3610 {
3611 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3612 {
3613 operands[1] = force_reg (QImode, operands[1]);
3614 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3615 DONE;
3616 }
3617 })
3618
3619 (define_insn_and_split "zero_extendqihi2_and"
3620 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3621 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3622 (clobber (reg:CC FLAGS_REG))]
3623 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3624 "#"
3625 "&& reload_completed"
3626 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3627 (clobber (reg:CC FLAGS_REG))])]
3628 {
3629 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3630 {
3631 ix86_expand_clear (operands[0]);
3632
3633 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3634 emit_insn (gen_movstrictqi
3635 (gen_lowpart (QImode, operands[0]), operands[1]));
3636 DONE;
3637 }
3638
3639 operands[0] = gen_lowpart (SImode, operands[0]);
3640 }
3641 [(set_attr "type" "alu1")
3642 (set_attr "mode" "SI")])
3643
3644 ; zero extend to SImode to avoid partial register stalls
3645 (define_insn "*zero_extendqihi2"
3646 [(set (match_operand:HI 0 "register_operand" "=r")
3647 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3648 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3649 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3650 [(set_attr "type" "imovx")
3651 (set_attr "mode" "SI")])
3652 \f
3653 ;; Sign extension instructions
3654
3655 (define_expand "extendsidi2"
3656 [(set (match_operand:DI 0 "register_operand")
3657 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3658 ""
3659 {
3660 if (!TARGET_64BIT)
3661 {
3662 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3663 DONE;
3664 }
3665 })
3666
3667 (define_insn "*extendsidi2_rex64"
3668 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3669 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3670 "TARGET_64BIT"
3671 "@
3672 {cltq|cdqe}
3673 movs{lq|x}\t{%1, %0|%0, %1}"
3674 [(set_attr "type" "imovx")
3675 (set_attr "mode" "DI")
3676 (set_attr "prefix_0f" "0")
3677 (set_attr "modrm" "0,1")])
3678
3679 (define_insn "extendsidi2_1"
3680 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3681 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3682 (clobber (reg:CC FLAGS_REG))
3683 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3684 "!TARGET_64BIT"
3685 "#")
3686
3687 ;; Extend to memory case when source register does die.
3688 (define_split
3689 [(set (match_operand:DI 0 "memory_operand")
3690 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3691 (clobber (reg:CC FLAGS_REG))
3692 (clobber (match_operand:SI 2 "register_operand"))]
3693 "(reload_completed
3694 && dead_or_set_p (insn, operands[1])
3695 && !reg_mentioned_p (operands[1], operands[0]))"
3696 [(set (match_dup 3) (match_dup 1))
3697 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3698 (clobber (reg:CC FLAGS_REG))])
3699 (set (match_dup 4) (match_dup 1))]
3700 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3701
3702 ;; Extend to memory case when source register does not die.
3703 (define_split
3704 [(set (match_operand:DI 0 "memory_operand")
3705 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3706 (clobber (reg:CC FLAGS_REG))
3707 (clobber (match_operand:SI 2 "register_operand"))]
3708 "reload_completed"
3709 [(const_int 0)]
3710 {
3711 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3712
3713 emit_move_insn (operands[3], operands[1]);
3714
3715 /* Generate a cltd if possible and doing so it profitable. */
3716 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3717 && true_regnum (operands[1]) == AX_REG
3718 && true_regnum (operands[2]) == DX_REG)
3719 {
3720 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3721 }
3722 else
3723 {
3724 emit_move_insn (operands[2], operands[1]);
3725 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3726 }
3727 emit_move_insn (operands[4], operands[2]);
3728 DONE;
3729 })
3730
3731 ;; Extend to register case. Optimize case where source and destination
3732 ;; registers match and cases where we can use cltd.
3733 (define_split
3734 [(set (match_operand:DI 0 "register_operand")
3735 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3736 (clobber (reg:CC FLAGS_REG))
3737 (clobber (match_scratch:SI 2))]
3738 "reload_completed"
3739 [(const_int 0)]
3740 {
3741 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3742
3743 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3744 emit_move_insn (operands[3], operands[1]);
3745
3746 /* Generate a cltd if possible and doing so it profitable. */
3747 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3748 && true_regnum (operands[3]) == AX_REG
3749 && true_regnum (operands[4]) == DX_REG)
3750 {
3751 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3752 DONE;
3753 }
3754
3755 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3756 emit_move_insn (operands[4], operands[1]);
3757
3758 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3759 DONE;
3760 })
3761
3762 (define_insn "extend<mode>di2"
3763 [(set (match_operand:DI 0 "register_operand" "=r")
3764 (sign_extend:DI
3765 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3766 "TARGET_64BIT"
3767 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3768 [(set_attr "type" "imovx")
3769 (set_attr "mode" "DI")])
3770
3771 (define_insn "extendhisi2"
3772 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3773 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3774 ""
3775 {
3776 switch (get_attr_prefix_0f (insn))
3777 {
3778 case 0:
3779 return "{cwtl|cwde}";
3780 default:
3781 return "movs{wl|x}\t{%1, %0|%0, %1}";
3782 }
3783 }
3784 [(set_attr "type" "imovx")
3785 (set_attr "mode" "SI")
3786 (set (attr "prefix_0f")
3787 ;; movsx is short decodable while cwtl is vector decoded.
3788 (if_then_else (and (eq_attr "cpu" "!k6")
3789 (eq_attr "alternative" "0"))
3790 (const_string "0")
3791 (const_string "1")))
3792 (set (attr "modrm")
3793 (if_then_else (eq_attr "prefix_0f" "0")
3794 (const_string "0")
3795 (const_string "1")))])
3796
3797 (define_insn "*extendhisi2_zext"
3798 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3799 (zero_extend:DI
3800 (sign_extend:SI
3801 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3802 "TARGET_64BIT"
3803 {
3804 switch (get_attr_prefix_0f (insn))
3805 {
3806 case 0:
3807 return "{cwtl|cwde}";
3808 default:
3809 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3810 }
3811 }
3812 [(set_attr "type" "imovx")
3813 (set_attr "mode" "SI")
3814 (set (attr "prefix_0f")
3815 ;; movsx is short decodable while cwtl is vector decoded.
3816 (if_then_else (and (eq_attr "cpu" "!k6")
3817 (eq_attr "alternative" "0"))
3818 (const_string "0")
3819 (const_string "1")))
3820 (set (attr "modrm")
3821 (if_then_else (eq_attr "prefix_0f" "0")
3822 (const_string "0")
3823 (const_string "1")))])
3824
3825 (define_insn "extendqisi2"
3826 [(set (match_operand:SI 0 "register_operand" "=r")
3827 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3828 ""
3829 "movs{bl|x}\t{%1, %0|%0, %1}"
3830 [(set_attr "type" "imovx")
3831 (set_attr "mode" "SI")])
3832
3833 (define_insn "*extendqisi2_zext"
3834 [(set (match_operand:DI 0 "register_operand" "=r")
3835 (zero_extend:DI
3836 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3837 "TARGET_64BIT"
3838 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3839 [(set_attr "type" "imovx")
3840 (set_attr "mode" "SI")])
3841
3842 (define_insn "extendqihi2"
3843 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3844 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3845 ""
3846 {
3847 switch (get_attr_prefix_0f (insn))
3848 {
3849 case 0:
3850 return "{cbtw|cbw}";
3851 default:
3852 return "movs{bw|x}\t{%1, %0|%0, %1}";
3853 }
3854 }
3855 [(set_attr "type" "imovx")
3856 (set_attr "mode" "HI")
3857 (set (attr "prefix_0f")
3858 ;; movsx is short decodable while cwtl is vector decoded.
3859 (if_then_else (and (eq_attr "cpu" "!k6")
3860 (eq_attr "alternative" "0"))
3861 (const_string "0")
3862 (const_string "1")))
3863 (set (attr "modrm")
3864 (if_then_else (eq_attr "prefix_0f" "0")
3865 (const_string "0")
3866 (const_string "1")))])
3867 \f
3868 ;; Conversions between float and double.
3869
3870 ;; These are all no-ops in the model used for the 80387.
3871 ;; So just emit moves.
3872
3873 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3874 (define_split
3875 [(set (match_operand:DF 0 "push_operand")
3876 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3877 "reload_completed"
3878 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3879 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3880
3881 (define_split
3882 [(set (match_operand:XF 0 "push_operand")
3883 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3884 "reload_completed"
3885 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3886 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3887 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3888
3889 (define_expand "extendsfdf2"
3890 [(set (match_operand:DF 0 "nonimmediate_operand")
3891 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3892 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3893 {
3894 /* ??? Needed for compress_float_constant since all fp constants
3895 are TARGET_LEGITIMATE_CONSTANT_P. */
3896 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3897 {
3898 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3899 && standard_80387_constant_p (operands[1]) > 0)
3900 {
3901 operands[1] = simplify_const_unary_operation
3902 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3903 emit_move_insn_1 (operands[0], operands[1]);
3904 DONE;
3905 }
3906 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3907 }
3908 })
3909
3910 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3911 cvtss2sd:
3912 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3913 cvtps2pd xmm2,xmm1
3914 We do the conversion post reload to avoid producing of 128bit spills
3915 that might lead to ICE on 32bit target. The sequence unlikely combine
3916 anyway. */
3917 (define_split
3918 [(set (match_operand:DF 0 "register_operand")
3919 (float_extend:DF
3920 (match_operand:SF 1 "nonimmediate_operand")))]
3921 "TARGET_USE_VECTOR_FP_CONVERTS
3922 && optimize_insn_for_speed_p ()
3923 && reload_completed && SSE_REG_P (operands[0])"
3924 [(set (match_dup 2)
3925 (float_extend:V2DF
3926 (vec_select:V2SF
3927 (match_dup 3)
3928 (parallel [(const_int 0) (const_int 1)]))))]
3929 {
3930 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3931 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3932 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3933 Try to avoid move when unpacking can be done in source. */
3934 if (REG_P (operands[1]))
3935 {
3936 /* If it is unsafe to overwrite upper half of source, we need
3937 to move to destination and unpack there. */
3938 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3939 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3940 && true_regnum (operands[0]) != true_regnum (operands[1]))
3941 {
3942 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3943 emit_move_insn (tmp, operands[1]);
3944 }
3945 else
3946 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3947 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3948 operands[3]));
3949 }
3950 else
3951 emit_insn (gen_vec_setv4sf_0 (operands[3],
3952 CONST0_RTX (V4SFmode), operands[1]));
3953 })
3954
3955 (define_insn "*extendsfdf2_mixed"
3956 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3957 (float_extend:DF
3958 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3959 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3960 {
3961 switch (which_alternative)
3962 {
3963 case 0:
3964 case 1:
3965 return output_387_reg_move (insn, operands);
3966
3967 case 2:
3968 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3969
3970 default:
3971 gcc_unreachable ();
3972 }
3973 }
3974 [(set_attr "type" "fmov,fmov,ssecvt")
3975 (set_attr "prefix" "orig,orig,maybe_vex")
3976 (set_attr "mode" "SF,XF,DF")])
3977
3978 (define_insn "*extendsfdf2_sse"
3979 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3980 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3981 "TARGET_SSE2 && TARGET_SSE_MATH"
3982 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3983 [(set_attr "type" "ssecvt")
3984 (set_attr "prefix" "maybe_vex")
3985 (set_attr "mode" "DF")])
3986
3987 (define_insn "*extendsfdf2_i387"
3988 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3989 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3990 "TARGET_80387"
3991 "* return output_387_reg_move (insn, operands);"
3992 [(set_attr "type" "fmov")
3993 (set_attr "mode" "SF,XF")])
3994
3995 (define_expand "extend<mode>xf2"
3996 [(set (match_operand:XF 0 "nonimmediate_operand")
3997 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3998 "TARGET_80387"
3999 {
4000 /* ??? Needed for compress_float_constant since all fp constants
4001 are TARGET_LEGITIMATE_CONSTANT_P. */
4002 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4003 {
4004 if (standard_80387_constant_p (operands[1]) > 0)
4005 {
4006 operands[1] = simplify_const_unary_operation
4007 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4008 emit_move_insn_1 (operands[0], operands[1]);
4009 DONE;
4010 }
4011 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4012 }
4013 })
4014
4015 (define_insn "*extend<mode>xf2_i387"
4016 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4017 (float_extend:XF
4018 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4019 "TARGET_80387"
4020 "* return output_387_reg_move (insn, operands);"
4021 [(set_attr "type" "fmov")
4022 (set_attr "mode" "<MODE>,XF")])
4023
4024 ;; %%% This seems bad bad news.
4025 ;; This cannot output into an f-reg because there is no way to be sure
4026 ;; of truncating in that case. Otherwise this is just like a simple move
4027 ;; insn. So we pretend we can output to a reg in order to get better
4028 ;; register preferencing, but we really use a stack slot.
4029
4030 ;; Conversion from DFmode to SFmode.
4031
4032 (define_expand "truncdfsf2"
4033 [(set (match_operand:SF 0 "nonimmediate_operand")
4034 (float_truncate:SF
4035 (match_operand:DF 1 "nonimmediate_operand")))]
4036 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4037 {
4038 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4039 ;
4040 else if (flag_unsafe_math_optimizations)
4041 ;
4042 else
4043 {
4044 enum ix86_stack_slot slot = (virtuals_instantiated
4045 ? SLOT_TEMP
4046 : SLOT_VIRTUAL);
4047 rtx temp = assign_386_stack_local (SFmode, slot);
4048 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4049 DONE;
4050 }
4051 })
4052
4053 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4054 cvtsd2ss:
4055 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4056 cvtpd2ps xmm2,xmm1
4057 We do the conversion post reload to avoid producing of 128bit spills
4058 that might lead to ICE on 32bit target. The sequence unlikely combine
4059 anyway. */
4060 (define_split
4061 [(set (match_operand:SF 0 "register_operand")
4062 (float_truncate:SF
4063 (match_operand:DF 1 "nonimmediate_operand")))]
4064 "TARGET_USE_VECTOR_FP_CONVERTS
4065 && optimize_insn_for_speed_p ()
4066 && reload_completed && SSE_REG_P (operands[0])"
4067 [(set (match_dup 2)
4068 (vec_concat:V4SF
4069 (float_truncate:V2SF
4070 (match_dup 4))
4071 (match_dup 3)))]
4072 {
4073 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4074 operands[3] = CONST0_RTX (V2SFmode);
4075 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4076 /* Use movsd for loading from memory, unpcklpd for registers.
4077 Try to avoid move when unpacking can be done in source, or SSE3
4078 movddup is available. */
4079 if (REG_P (operands[1]))
4080 {
4081 if (!TARGET_SSE3
4082 && true_regnum (operands[0]) != true_regnum (operands[1])
4083 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4084 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4085 {
4086 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4087 emit_move_insn (tmp, operands[1]);
4088 operands[1] = tmp;
4089 }
4090 else if (!TARGET_SSE3)
4091 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4092 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4093 }
4094 else
4095 emit_insn (gen_sse2_loadlpd (operands[4],
4096 CONST0_RTX (V2DFmode), operands[1]));
4097 })
4098
4099 (define_expand "truncdfsf2_with_temp"
4100 [(parallel [(set (match_operand:SF 0)
4101 (float_truncate:SF (match_operand:DF 1)))
4102 (clobber (match_operand:SF 2))])])
4103
4104 (define_insn "*truncdfsf_fast_mixed"
4105 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4106 (float_truncate:SF
4107 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4108 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4109 {
4110 switch (which_alternative)
4111 {
4112 case 0:
4113 return output_387_reg_move (insn, operands);
4114 case 1:
4115 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4116 default:
4117 gcc_unreachable ();
4118 }
4119 }
4120 [(set_attr "type" "fmov,ssecvt")
4121 (set_attr "prefix" "orig,maybe_vex")
4122 (set_attr "mode" "SF")])
4123
4124 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4125 ;; because nothing we do here is unsafe.
4126 (define_insn "*truncdfsf_fast_sse"
4127 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4128 (float_truncate:SF
4129 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4130 "TARGET_SSE2 && TARGET_SSE_MATH"
4131 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4132 [(set_attr "type" "ssecvt")
4133 (set_attr "prefix" "maybe_vex")
4134 (set_attr "mode" "SF")])
4135
4136 (define_insn "*truncdfsf_fast_i387"
4137 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4138 (float_truncate:SF
4139 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4140 "TARGET_80387 && flag_unsafe_math_optimizations"
4141 "* return output_387_reg_move (insn, operands);"
4142 [(set_attr "type" "fmov")
4143 (set_attr "mode" "SF")])
4144
4145 (define_insn "*truncdfsf_mixed"
4146 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4147 (float_truncate:SF
4148 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4149 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4150 "TARGET_MIX_SSE_I387"
4151 {
4152 switch (which_alternative)
4153 {
4154 case 0:
4155 return output_387_reg_move (insn, operands);
4156 case 1:
4157 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4158
4159 default:
4160 return "#";
4161 }
4162 }
4163 [(set_attr "isa" "*,sse2,*,*,*")
4164 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4165 (set_attr "unit" "*,*,i387,i387,i387")
4166 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4167 (set_attr "mode" "SF")])
4168
4169 (define_insn "*truncdfsf_i387"
4170 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4171 (float_truncate:SF
4172 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4173 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4174 "TARGET_80387"
4175 {
4176 switch (which_alternative)
4177 {
4178 case 0:
4179 return output_387_reg_move (insn, operands);
4180
4181 default:
4182 return "#";
4183 }
4184 }
4185 [(set_attr "type" "fmov,multi,multi,multi")
4186 (set_attr "unit" "*,i387,i387,i387")
4187 (set_attr "mode" "SF")])
4188
4189 (define_insn "*truncdfsf2_i387_1"
4190 [(set (match_operand:SF 0 "memory_operand" "=m")
4191 (float_truncate:SF
4192 (match_operand:DF 1 "register_operand" "f")))]
4193 "TARGET_80387
4194 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4195 && !TARGET_MIX_SSE_I387"
4196 "* return output_387_reg_move (insn, operands);"
4197 [(set_attr "type" "fmov")
4198 (set_attr "mode" "SF")])
4199
4200 (define_split
4201 [(set (match_operand:SF 0 "register_operand")
4202 (float_truncate:SF
4203 (match_operand:DF 1 "fp_register_operand")))
4204 (clobber (match_operand 2))]
4205 "reload_completed"
4206 [(set (match_dup 2) (match_dup 1))
4207 (set (match_dup 0) (match_dup 2))]
4208 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4209
4210 ;; Conversion from XFmode to {SF,DF}mode
4211
4212 (define_expand "truncxf<mode>2"
4213 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4214 (float_truncate:MODEF
4215 (match_operand:XF 1 "register_operand")))
4216 (clobber (match_dup 2))])]
4217 "TARGET_80387"
4218 {
4219 if (flag_unsafe_math_optimizations)
4220 {
4221 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4222 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4223 if (reg != operands[0])
4224 emit_move_insn (operands[0], reg);
4225 DONE;
4226 }
4227 else
4228 {
4229 enum ix86_stack_slot slot = (virtuals_instantiated
4230 ? SLOT_TEMP
4231 : SLOT_VIRTUAL);
4232 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4233 }
4234 })
4235
4236 (define_insn "*truncxfsf2_mixed"
4237 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4238 (float_truncate:SF
4239 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4240 (clobber (match_operand:SF 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 "type" "fmov,multi,multi,multi")
4247 (set_attr "unit" "*,i387,i387,i387")
4248 (set_attr "mode" "SF")])
4249
4250 (define_insn "*truncxfdf2_mixed"
4251 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4252 (float_truncate:DF
4253 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4254 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4255 "TARGET_80387"
4256 {
4257 gcc_assert (!which_alternative);
4258 return output_387_reg_move (insn, operands);
4259 }
4260 [(set_attr "isa" "*,*,sse2,*")
4261 (set_attr "type" "fmov,multi,multi,multi")
4262 (set_attr "unit" "*,i387,i387,i387")
4263 (set_attr "mode" "DF")])
4264
4265 (define_insn "truncxf<mode>2_i387_noop"
4266 [(set (match_operand:MODEF 0 "register_operand" "=f")
4267 (float_truncate:MODEF
4268 (match_operand:XF 1 "register_operand" "f")))]
4269 "TARGET_80387 && flag_unsafe_math_optimizations"
4270 "* return output_387_reg_move (insn, operands);"
4271 [(set_attr "type" "fmov")
4272 (set_attr "mode" "<MODE>")])
4273
4274 (define_insn "*truncxf<mode>2_i387"
4275 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4276 (float_truncate:MODEF
4277 (match_operand:XF 1 "register_operand" "f")))]
4278 "TARGET_80387"
4279 "* return output_387_reg_move (insn, operands);"
4280 [(set_attr "type" "fmov")
4281 (set_attr "mode" "<MODE>")])
4282
4283 (define_split
4284 [(set (match_operand:MODEF 0 "register_operand")
4285 (float_truncate:MODEF
4286 (match_operand:XF 1 "register_operand")))
4287 (clobber (match_operand:MODEF 2 "memory_operand"))]
4288 "TARGET_80387 && reload_completed"
4289 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4290 (set (match_dup 0) (match_dup 2))])
4291
4292 (define_split
4293 [(set (match_operand:MODEF 0 "memory_operand")
4294 (float_truncate:MODEF
4295 (match_operand:XF 1 "register_operand")))
4296 (clobber (match_operand:MODEF 2 "memory_operand"))]
4297 "TARGET_80387"
4298 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4299 \f
4300 ;; Signed conversion to DImode.
4301
4302 (define_expand "fix_truncxfdi2"
4303 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4304 (fix:DI (match_operand:XF 1 "register_operand")))
4305 (clobber (reg:CC FLAGS_REG))])]
4306 "TARGET_80387"
4307 {
4308 if (TARGET_FISTTP)
4309 {
4310 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4311 DONE;
4312 }
4313 })
4314
4315 (define_expand "fix_trunc<mode>di2"
4316 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4317 (fix:DI (match_operand:MODEF 1 "register_operand")))
4318 (clobber (reg:CC FLAGS_REG))])]
4319 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4320 {
4321 if (TARGET_FISTTP
4322 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4323 {
4324 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4325 DONE;
4326 }
4327 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4328 {
4329 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4330 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4331 if (out != operands[0])
4332 emit_move_insn (operands[0], out);
4333 DONE;
4334 }
4335 })
4336
4337 ;; Signed conversion to SImode.
4338
4339 (define_expand "fix_truncxfsi2"
4340 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4341 (fix:SI (match_operand:XF 1 "register_operand")))
4342 (clobber (reg:CC FLAGS_REG))])]
4343 "TARGET_80387"
4344 {
4345 if (TARGET_FISTTP)
4346 {
4347 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4348 DONE;
4349 }
4350 })
4351
4352 (define_expand "fix_trunc<mode>si2"
4353 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4354 (fix:SI (match_operand:MODEF 1 "register_operand")))
4355 (clobber (reg:CC FLAGS_REG))])]
4356 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4357 {
4358 if (TARGET_FISTTP
4359 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4360 {
4361 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4362 DONE;
4363 }
4364 if (SSE_FLOAT_MODE_P (<MODE>mode))
4365 {
4366 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4367 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4368 if (out != operands[0])
4369 emit_move_insn (operands[0], out);
4370 DONE;
4371 }
4372 })
4373
4374 ;; Signed conversion to HImode.
4375
4376 (define_expand "fix_trunc<mode>hi2"
4377 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4378 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4379 (clobber (reg:CC FLAGS_REG))])]
4380 "TARGET_80387
4381 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4382 {
4383 if (TARGET_FISTTP)
4384 {
4385 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4386 DONE;
4387 }
4388 })
4389
4390 ;; Unsigned conversion to SImode.
4391
4392 (define_expand "fixuns_trunc<mode>si2"
4393 [(parallel
4394 [(set (match_operand:SI 0 "register_operand")
4395 (unsigned_fix:SI
4396 (match_operand:MODEF 1 "nonimmediate_operand")))
4397 (use (match_dup 2))
4398 (clobber (match_scratch:<ssevecmode> 3))
4399 (clobber (match_scratch:<ssevecmode> 4))])]
4400 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4401 {
4402 enum machine_mode mode = <MODE>mode;
4403 enum machine_mode vecmode = <ssevecmode>mode;
4404 REAL_VALUE_TYPE TWO31r;
4405 rtx two31;
4406
4407 if (optimize_insn_for_size_p ())
4408 FAIL;
4409
4410 real_ldexp (&TWO31r, &dconst1, 31);
4411 two31 = const_double_from_real_value (TWO31r, mode);
4412 two31 = ix86_build_const_vector (vecmode, true, two31);
4413 operands[2] = force_reg (vecmode, two31);
4414 })
4415
4416 (define_insn_and_split "*fixuns_trunc<mode>_1"
4417 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4418 (unsigned_fix:SI
4419 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4420 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4421 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4422 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4423 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4424 && optimize_function_for_speed_p (cfun)"
4425 "#"
4426 "&& reload_completed"
4427 [(const_int 0)]
4428 {
4429 ix86_split_convert_uns_si_sse (operands);
4430 DONE;
4431 })
4432
4433 ;; Unsigned conversion to HImode.
4434 ;; Without these patterns, we'll try the unsigned SI conversion which
4435 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4436
4437 (define_expand "fixuns_trunc<mode>hi2"
4438 [(set (match_dup 2)
4439 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4440 (set (match_operand:HI 0 "nonimmediate_operand")
4441 (subreg:HI (match_dup 2) 0))]
4442 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4443 "operands[2] = gen_reg_rtx (SImode);")
4444
4445 ;; When SSE is available, it is always faster to use it!
4446 (define_insn "fix_trunc<mode>di_sse"
4447 [(set (match_operand:DI 0 "register_operand" "=r,r")
4448 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4449 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4450 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4451 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4452 [(set_attr "type" "sseicvt")
4453 (set_attr "prefix" "maybe_vex")
4454 (set_attr "prefix_rex" "1")
4455 (set_attr "mode" "<MODE>")
4456 (set_attr "athlon_decode" "double,vector")
4457 (set_attr "amdfam10_decode" "double,double")
4458 (set_attr "bdver1_decode" "double,double")])
4459
4460 (define_insn "fix_trunc<mode>si_sse"
4461 [(set (match_operand:SI 0 "register_operand" "=r,r")
4462 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4463 "SSE_FLOAT_MODE_P (<MODE>mode)
4464 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4465 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4466 [(set_attr "type" "sseicvt")
4467 (set_attr "prefix" "maybe_vex")
4468 (set_attr "mode" "<MODE>")
4469 (set_attr "athlon_decode" "double,vector")
4470 (set_attr "amdfam10_decode" "double,double")
4471 (set_attr "bdver1_decode" "double,double")])
4472
4473 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4474 (define_peephole2
4475 [(set (match_operand:MODEF 0 "register_operand")
4476 (match_operand:MODEF 1 "memory_operand"))
4477 (set (match_operand:SWI48x 2 "register_operand")
4478 (fix:SWI48x (match_dup 0)))]
4479 "TARGET_SHORTEN_X87_SSE
4480 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4481 && peep2_reg_dead_p (2, operands[0])"
4482 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4483
4484 ;; Avoid vector decoded forms of the instruction.
4485 (define_peephole2
4486 [(match_scratch:DF 2 "x")
4487 (set (match_operand:SWI48x 0 "register_operand")
4488 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4489 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4490 [(set (match_dup 2) (match_dup 1))
4491 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4492
4493 (define_peephole2
4494 [(match_scratch:SF 2 "x")
4495 (set (match_operand:SWI48x 0 "register_operand")
4496 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4497 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4498 [(set (match_dup 2) (match_dup 1))
4499 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4500
4501 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4502 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4503 (fix:SWI248x (match_operand 1 "register_operand")))]
4504 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4505 && TARGET_FISTTP
4506 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4507 && (TARGET_64BIT || <MODE>mode != DImode))
4508 && TARGET_SSE_MATH)
4509 && can_create_pseudo_p ()"
4510 "#"
4511 "&& 1"
4512 [(const_int 0)]
4513 {
4514 if (memory_operand (operands[0], VOIDmode))
4515 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4516 else
4517 {
4518 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4519 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4520 operands[1],
4521 operands[2]));
4522 }
4523 DONE;
4524 }
4525 [(set_attr "type" "fisttp")
4526 (set_attr "mode" "<MODE>")])
4527
4528 (define_insn "fix_trunc<mode>_i387_fisttp"
4529 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4530 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4531 (clobber (match_scratch:XF 2 "=&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 "* return output_fix_trunc (insn, operands, true);"
4538 [(set_attr "type" "fisttp")
4539 (set_attr "mode" "<MODE>")])
4540
4541 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4542 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4543 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4544 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4545 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4546 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4547 && TARGET_FISTTP
4548 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4549 && (TARGET_64BIT || <MODE>mode != DImode))
4550 && TARGET_SSE_MATH)"
4551 "#"
4552 [(set_attr "type" "fisttp")
4553 (set_attr "mode" "<MODE>")])
4554
4555 (define_split
4556 [(set (match_operand:SWI248x 0 "register_operand")
4557 (fix:SWI248x (match_operand 1 "register_operand")))
4558 (clobber (match_operand:SWI248x 2 "memory_operand"))
4559 (clobber (match_scratch 3))]
4560 "reload_completed"
4561 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4562 (clobber (match_dup 3))])
4563 (set (match_dup 0) (match_dup 2))])
4564
4565 (define_split
4566 [(set (match_operand:SWI248x 0 "memory_operand")
4567 (fix:SWI248x (match_operand 1 "register_operand")))
4568 (clobber (match_operand:SWI248x 2 "memory_operand"))
4569 (clobber (match_scratch 3))]
4570 "reload_completed"
4571 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4572 (clobber (match_dup 3))])])
4573
4574 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4575 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4576 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4577 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4578 ;; function in i386.c.
4579 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4580 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4581 (fix:SWI248x (match_operand 1 "register_operand")))
4582 (clobber (reg:CC FLAGS_REG))]
4583 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4584 && !TARGET_FISTTP
4585 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4586 && (TARGET_64BIT || <MODE>mode != DImode))
4587 && can_create_pseudo_p ()"
4588 "#"
4589 "&& 1"
4590 [(const_int 0)]
4591 {
4592 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4593
4594 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4595 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4596 if (memory_operand (operands[0], VOIDmode))
4597 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4598 operands[2], operands[3]));
4599 else
4600 {
4601 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4602 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4603 operands[2], operands[3],
4604 operands[4]));
4605 }
4606 DONE;
4607 }
4608 [(set_attr "type" "fistp")
4609 (set_attr "i387_cw" "trunc")
4610 (set_attr "mode" "<MODE>")])
4611
4612 (define_insn "fix_truncdi_i387"
4613 [(set (match_operand:DI 0 "memory_operand" "=m")
4614 (fix:DI (match_operand 1 "register_operand" "f")))
4615 (use (match_operand:HI 2 "memory_operand" "m"))
4616 (use (match_operand:HI 3 "memory_operand" "m"))
4617 (clobber (match_scratch:XF 4 "=&1f"))]
4618 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4619 && !TARGET_FISTTP
4620 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4621 "* return output_fix_trunc (insn, operands, false);"
4622 [(set_attr "type" "fistp")
4623 (set_attr "i387_cw" "trunc")
4624 (set_attr "mode" "DI")])
4625
4626 (define_insn "fix_truncdi_i387_with_temp"
4627 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4628 (fix:DI (match_operand 1 "register_operand" "f,f")))
4629 (use (match_operand:HI 2 "memory_operand" "m,m"))
4630 (use (match_operand:HI 3 "memory_operand" "m,m"))
4631 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4632 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4633 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4634 && !TARGET_FISTTP
4635 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4636 "#"
4637 [(set_attr "type" "fistp")
4638 (set_attr "i387_cw" "trunc")
4639 (set_attr "mode" "DI")])
4640
4641 (define_split
4642 [(set (match_operand:DI 0 "register_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 4) (fix:DI (match_dup 1)))
4650 (use (match_dup 2))
4651 (use (match_dup 3))
4652 (clobber (match_dup 5))])
4653 (set (match_dup 0) (match_dup 4))])
4654
4655 (define_split
4656 [(set (match_operand:DI 0 "memory_operand")
4657 (fix:DI (match_operand 1 "register_operand")))
4658 (use (match_operand:HI 2 "memory_operand"))
4659 (use (match_operand:HI 3 "memory_operand"))
4660 (clobber (match_operand:DI 4 "memory_operand"))
4661 (clobber (match_scratch 5))]
4662 "reload_completed"
4663 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4664 (use (match_dup 2))
4665 (use (match_dup 3))
4666 (clobber (match_dup 5))])])
4667
4668 (define_insn "fix_trunc<mode>_i387"
4669 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4670 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4671 (use (match_operand:HI 2 "memory_operand" "m"))
4672 (use (match_operand:HI 3 "memory_operand" "m"))]
4673 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4674 && !TARGET_FISTTP
4675 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4676 "* return output_fix_trunc (insn, operands, false);"
4677 [(set_attr "type" "fistp")
4678 (set_attr "i387_cw" "trunc")
4679 (set_attr "mode" "<MODE>")])
4680
4681 (define_insn "fix_trunc<mode>_i387_with_temp"
4682 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4683 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4684 (use (match_operand:HI 2 "memory_operand" "m,m"))
4685 (use (match_operand:HI 3 "memory_operand" "m,m"))
4686 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4687 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4688 && !TARGET_FISTTP
4689 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4690 "#"
4691 [(set_attr "type" "fistp")
4692 (set_attr "i387_cw" "trunc")
4693 (set_attr "mode" "<MODE>")])
4694
4695 (define_split
4696 [(set (match_operand:SWI24 0 "register_operand")
4697 (fix:SWI24 (match_operand 1 "register_operand")))
4698 (use (match_operand:HI 2 "memory_operand"))
4699 (use (match_operand:HI 3 "memory_operand"))
4700 (clobber (match_operand:SWI24 4 "memory_operand"))]
4701 "reload_completed"
4702 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4703 (use (match_dup 2))
4704 (use (match_dup 3))])
4705 (set (match_dup 0) (match_dup 4))])
4706
4707 (define_split
4708 [(set (match_operand:SWI24 0 "memory_operand")
4709 (fix:SWI24 (match_operand 1 "register_operand")))
4710 (use (match_operand:HI 2 "memory_operand"))
4711 (use (match_operand:HI 3 "memory_operand"))
4712 (clobber (match_operand:SWI24 4 "memory_operand"))]
4713 "reload_completed"
4714 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4715 (use (match_dup 2))
4716 (use (match_dup 3))])])
4717
4718 (define_insn "x86_fnstcw_1"
4719 [(set (match_operand:HI 0 "memory_operand" "=m")
4720 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4721 "TARGET_80387"
4722 "fnstcw\t%0"
4723 [(set (attr "length")
4724 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4725 (set_attr "mode" "HI")
4726 (set_attr "unit" "i387")
4727 (set_attr "bdver1_decode" "vector")])
4728
4729 (define_insn "x86_fldcw_1"
4730 [(set (reg:HI FPCR_REG)
4731 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4732 "TARGET_80387"
4733 "fldcw\t%0"
4734 [(set (attr "length")
4735 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4736 (set_attr "mode" "HI")
4737 (set_attr "unit" "i387")
4738 (set_attr "athlon_decode" "vector")
4739 (set_attr "amdfam10_decode" "vector")
4740 (set_attr "bdver1_decode" "vector")])
4741 \f
4742 ;; Conversion between fixed point and floating point.
4743
4744 ;; Even though we only accept memory inputs, the backend _really_
4745 ;; wants to be able to do this between registers.
4746
4747 (define_expand "floathi<mode>2"
4748 [(set (match_operand:X87MODEF 0 "register_operand")
4749 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4750 "TARGET_80387
4751 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4752 || TARGET_MIX_SSE_I387)")
4753
4754 ;; Pre-reload splitter to add memory clobber to the pattern.
4755 (define_insn_and_split "*floathi<mode>2_1"
4756 [(set (match_operand:X87MODEF 0 "register_operand")
4757 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4758 "TARGET_80387
4759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4760 || TARGET_MIX_SSE_I387)
4761 && can_create_pseudo_p ()"
4762 "#"
4763 "&& 1"
4764 [(parallel [(set (match_dup 0)
4765 (float:X87MODEF (match_dup 1)))
4766 (clobber (match_dup 2))])]
4767 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4768
4769 (define_insn "*floathi<mode>2_i387_with_temp"
4770 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4771 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4772 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4773 "TARGET_80387
4774 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4775 || TARGET_MIX_SSE_I387)"
4776 "#"
4777 [(set_attr "type" "fmov,multi")
4778 (set_attr "mode" "<MODE>")
4779 (set_attr "unit" "*,i387")
4780 (set_attr "fp_int_src" "true")])
4781
4782 (define_insn "*floathi<mode>2_i387"
4783 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4784 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4785 "TARGET_80387
4786 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4787 || TARGET_MIX_SSE_I387)"
4788 "fild%Z1\t%1"
4789 [(set_attr "type" "fmov")
4790 (set_attr "mode" "<MODE>")
4791 (set_attr "fp_int_src" "true")])
4792
4793 (define_split
4794 [(set (match_operand:X87MODEF 0 "register_operand")
4795 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4796 (clobber (match_operand:HI 2 "memory_operand"))]
4797 "TARGET_80387
4798 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4799 || TARGET_MIX_SSE_I387)
4800 && reload_completed"
4801 [(set (match_dup 2) (match_dup 1))
4802 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4803
4804 (define_split
4805 [(set (match_operand:X87MODEF 0 "register_operand")
4806 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4807 (clobber (match_operand:HI 2 "memory_operand"))]
4808 "TARGET_80387
4809 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4810 || TARGET_MIX_SSE_I387)
4811 && reload_completed"
4812 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4813
4814 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4815 [(set (match_operand:X87MODEF 0 "register_operand")
4816 (float:X87MODEF
4817 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4818 "TARGET_80387
4819 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4820 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4821 {
4822 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4823 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4824 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4825 {
4826 rtx reg = gen_reg_rtx (XFmode);
4827 rtx (*insn)(rtx, rtx);
4828
4829 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4830
4831 if (<X87MODEF:MODE>mode == SFmode)
4832 insn = gen_truncxfsf2;
4833 else if (<X87MODEF:MODE>mode == DFmode)
4834 insn = gen_truncxfdf2;
4835 else
4836 gcc_unreachable ();
4837
4838 emit_insn (insn (operands[0], reg));
4839 DONE;
4840 }
4841 })
4842
4843 ;; Pre-reload splitter to add memory clobber to the pattern.
4844 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4845 [(set (match_operand:X87MODEF 0 "register_operand")
4846 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4847 "((TARGET_80387
4848 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4849 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4850 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4851 || TARGET_MIX_SSE_I387))
4852 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4853 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4854 && ((<SWI48x:MODE>mode == SImode
4855 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4856 && optimize_function_for_speed_p (cfun)
4857 && flag_trapping_math)
4858 || !(TARGET_INTER_UNIT_CONVERSIONS
4859 || optimize_function_for_size_p (cfun)))))
4860 && can_create_pseudo_p ()"
4861 "#"
4862 "&& 1"
4863 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4864 (clobber (match_dup 2))])]
4865 {
4866 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4867
4868 /* Avoid store forwarding (partial memory) stall penalty
4869 by passing DImode value through XMM registers. */
4870 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4871 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4872 && optimize_function_for_speed_p (cfun))
4873 {
4874 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4875 operands[1],
4876 operands[2]));
4877 DONE;
4878 }
4879 })
4880
4881 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4882 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4883 (float:MODEF
4884 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4885 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4886 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4887 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4888 "#"
4889 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4890 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4891 (set_attr "unit" "*,i387,*,*,*")
4892 (set_attr "athlon_decode" "*,*,double,direct,double")
4893 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4894 (set_attr "bdver1_decode" "*,*,double,direct,double")
4895 (set_attr "fp_int_src" "true")])
4896
4897 (define_insn "*floatsi<mode>2_vector_mixed"
4898 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4899 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4900 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4901 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4902 "@
4903 fild%Z1\t%1
4904 #"
4905 [(set_attr "type" "fmov,sseicvt")
4906 (set_attr "mode" "<MODE>,<ssevecmode>")
4907 (set_attr "unit" "i387,*")
4908 (set_attr "athlon_decode" "*,direct")
4909 (set_attr "amdfam10_decode" "*,double")
4910 (set_attr "bdver1_decode" "*,direct")
4911 (set_attr "fp_int_src" "true")])
4912
4913 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4914 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4915 (float:MODEF
4916 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4917 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4918 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4919 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4920 "#"
4921 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4922 (set_attr "mode" "<MODEF:MODE>")
4923 (set_attr "unit" "*,i387,*,*")
4924 (set_attr "athlon_decode" "*,*,double,direct")
4925 (set_attr "amdfam10_decode" "*,*,vector,double")
4926 (set_attr "bdver1_decode" "*,*,double,direct")
4927 (set_attr "fp_int_src" "true")])
4928
4929 (define_split
4930 [(set (match_operand:MODEF 0 "register_operand")
4931 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4932 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4933 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4934 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4935 && TARGET_INTER_UNIT_CONVERSIONS
4936 && reload_completed
4937 && (SSE_REG_P (operands[0])
4938 || (GET_CODE (operands[0]) == SUBREG
4939 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4940 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4941
4942 (define_split
4943 [(set (match_operand:MODEF 0 "register_operand")
4944 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4945 (clobber (match_operand:SWI48x 2 "memory_operand"))]
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 && reload_completed
4950 && (SSE_REG_P (operands[0])
4951 || (GET_CODE (operands[0]) == SUBREG
4952 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4953 [(set (match_dup 2) (match_dup 1))
4954 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4955
4956 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4957 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4958 (float:MODEF
4959 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4960 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4961 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4962 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4963 "@
4964 fild%Z1\t%1
4965 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4966 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4967 [(set_attr "type" "fmov,sseicvt,sseicvt")
4968 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4969 (set_attr "mode" "<MODEF:MODE>")
4970 (set (attr "prefix_rex")
4971 (if_then_else
4972 (and (eq_attr "prefix" "maybe_vex")
4973 (match_test "<SWI48x:MODE>mode == DImode"))
4974 (const_string "1")
4975 (const_string "*")))
4976 (set_attr "unit" "i387,*,*")
4977 (set_attr "athlon_decode" "*,double,direct")
4978 (set_attr "amdfam10_decode" "*,vector,double")
4979 (set_attr "bdver1_decode" "*,double,direct")
4980 (set_attr "fp_int_src" "true")])
4981
4982 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4983 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4984 (float:MODEF
4985 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4986 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4987 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4988 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4989 "@
4990 fild%Z1\t%1
4991 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4992 [(set_attr "type" "fmov,sseicvt")
4993 (set_attr "prefix" "orig,maybe_vex")
4994 (set_attr "mode" "<MODEF:MODE>")
4995 (set (attr "prefix_rex")
4996 (if_then_else
4997 (and (eq_attr "prefix" "maybe_vex")
4998 (match_test "<SWI48x:MODE>mode == DImode"))
4999 (const_string "1")
5000 (const_string "*")))
5001 (set_attr "athlon_decode" "*,direct")
5002 (set_attr "amdfam10_decode" "*,double")
5003 (set_attr "bdver1_decode" "*,direct")
5004 (set_attr "fp_int_src" "true")])
5005
5006 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5007 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5008 (float:MODEF
5009 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5010 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5011 "TARGET_SSE2 && TARGET_SSE_MATH
5012 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5013 "#"
5014 [(set_attr "type" "sseicvt")
5015 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5016 (set_attr "athlon_decode" "double,direct,double")
5017 (set_attr "amdfam10_decode" "vector,double,double")
5018 (set_attr "bdver1_decode" "double,direct,double")
5019 (set_attr "fp_int_src" "true")])
5020
5021 (define_insn "*floatsi<mode>2_vector_sse"
5022 [(set (match_operand:MODEF 0 "register_operand" "=x")
5023 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5024 "TARGET_SSE2 && TARGET_SSE_MATH
5025 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5026 "#"
5027 [(set_attr "type" "sseicvt")
5028 (set_attr "mode" "<MODE>")
5029 (set_attr "athlon_decode" "direct")
5030 (set_attr "amdfam10_decode" "double")
5031 (set_attr "bdver1_decode" "direct")
5032 (set_attr "fp_int_src" "true")])
5033
5034 (define_split
5035 [(set (match_operand:MODEF 0 "register_operand")
5036 (float:MODEF (match_operand:SI 1 "register_operand")))
5037 (clobber (match_operand:SI 2 "memory_operand"))]
5038 "TARGET_SSE2 && TARGET_SSE_MATH
5039 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5040 && reload_completed
5041 && (SSE_REG_P (operands[0])
5042 || (GET_CODE (operands[0]) == SUBREG
5043 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5044 [(const_int 0)]
5045 {
5046 rtx op1 = operands[1];
5047
5048 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5049 <MODE>mode, 0);
5050 if (GET_CODE (op1) == SUBREG)
5051 op1 = SUBREG_REG (op1);
5052
5053 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5054 {
5055 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5056 emit_insn (gen_sse2_loadld (operands[4],
5057 CONST0_RTX (V4SImode), operands[1]));
5058 }
5059 /* We can ignore possible trapping value in the
5060 high part of SSE register for non-trapping math. */
5061 else if (SSE_REG_P (op1) && !flag_trapping_math)
5062 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5063 else
5064 {
5065 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5066 emit_move_insn (operands[2], operands[1]);
5067 emit_insn (gen_sse2_loadld (operands[4],
5068 CONST0_RTX (V4SImode), operands[2]));
5069 }
5070 if (<ssevecmode>mode == V4SFmode)
5071 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5072 else
5073 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5074 DONE;
5075 })
5076
5077 (define_split
5078 [(set (match_operand:MODEF 0 "register_operand")
5079 (float:MODEF (match_operand:SI 1 "memory_operand")))
5080 (clobber (match_operand:SI 2 "memory_operand"))]
5081 "TARGET_SSE2 && TARGET_SSE_MATH
5082 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5083 && reload_completed
5084 && (SSE_REG_P (operands[0])
5085 || (GET_CODE (operands[0]) == SUBREG
5086 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5087 [(const_int 0)]
5088 {
5089 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5090 <MODE>mode, 0);
5091 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5092
5093 emit_insn (gen_sse2_loadld (operands[4],
5094 CONST0_RTX (V4SImode), operands[1]));
5095 if (<ssevecmode>mode == V4SFmode)
5096 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5097 else
5098 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5099 DONE;
5100 })
5101
5102 (define_split
5103 [(set (match_operand:MODEF 0 "register_operand")
5104 (float:MODEF (match_operand:SI 1 "register_operand")))]
5105 "TARGET_SSE2 && TARGET_SSE_MATH
5106 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5107 && reload_completed
5108 && (SSE_REG_P (operands[0])
5109 || (GET_CODE (operands[0]) == SUBREG
5110 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5111 [(const_int 0)]
5112 {
5113 rtx op1 = operands[1];
5114
5115 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5116 <MODE>mode, 0);
5117 if (GET_CODE (op1) == SUBREG)
5118 op1 = SUBREG_REG (op1);
5119
5120 if (GENERAL_REG_P (op1))
5121 {
5122 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5123 if (TARGET_INTER_UNIT_MOVES)
5124 emit_insn (gen_sse2_loadld (operands[4],
5125 CONST0_RTX (V4SImode), operands[1]));
5126 else
5127 {
5128 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5129 operands[1]);
5130 emit_insn (gen_sse2_loadld (operands[4],
5131 CONST0_RTX (V4SImode), operands[5]));
5132 ix86_free_from_memory (GET_MODE (operands[1]));
5133 }
5134 }
5135 /* We can ignore possible trapping value in the
5136 high part of SSE register for non-trapping math. */
5137 else if (SSE_REG_P (op1) && !flag_trapping_math)
5138 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5139 else
5140 gcc_unreachable ();
5141 if (<ssevecmode>mode == V4SFmode)
5142 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5143 else
5144 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5145 DONE;
5146 })
5147
5148 (define_split
5149 [(set (match_operand:MODEF 0 "register_operand")
5150 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5151 "TARGET_SSE2 && TARGET_SSE_MATH
5152 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5153 && reload_completed
5154 && (SSE_REG_P (operands[0])
5155 || (GET_CODE (operands[0]) == SUBREG
5156 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5157 [(const_int 0)]
5158 {
5159 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5160 <MODE>mode, 0);
5161 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5162
5163 emit_insn (gen_sse2_loadld (operands[4],
5164 CONST0_RTX (V4SImode), operands[1]));
5165 if (<ssevecmode>mode == V4SFmode)
5166 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5167 else
5168 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5169 DONE;
5170 })
5171
5172 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5173 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5174 (float:MODEF
5175 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5176 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5177 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5178 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5179 "#"
5180 [(set_attr "type" "sseicvt")
5181 (set_attr "mode" "<MODEF:MODE>")
5182 (set_attr "athlon_decode" "double,direct")
5183 (set_attr "amdfam10_decode" "vector,double")
5184 (set_attr "bdver1_decode" "double,direct")
5185 (set_attr "fp_int_src" "true")])
5186
5187 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5188 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5189 (float:MODEF
5190 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5191 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5192 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5193 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5194 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5195 [(set_attr "type" "sseicvt")
5196 (set_attr "prefix" "maybe_vex")
5197 (set_attr "mode" "<MODEF:MODE>")
5198 (set (attr "prefix_rex")
5199 (if_then_else
5200 (and (eq_attr "prefix" "maybe_vex")
5201 (match_test "<SWI48x:MODE>mode == DImode"))
5202 (const_string "1")
5203 (const_string "*")))
5204 (set_attr "athlon_decode" "double,direct")
5205 (set_attr "amdfam10_decode" "vector,double")
5206 (set_attr "bdver1_decode" "double,direct")
5207 (set_attr "fp_int_src" "true")])
5208
5209 (define_split
5210 [(set (match_operand:MODEF 0 "register_operand")
5211 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5212 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5213 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5214 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5215 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5216 && reload_completed
5217 && (SSE_REG_P (operands[0])
5218 || (GET_CODE (operands[0]) == SUBREG
5219 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5220 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5221
5222 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5223 [(set (match_operand:MODEF 0 "register_operand" "=x")
5224 (float:MODEF
5225 (match_operand:SWI48x 1 "memory_operand" "m")))]
5226 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5227 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5228 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5229 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5230 [(set_attr "type" "sseicvt")
5231 (set_attr "prefix" "maybe_vex")
5232 (set_attr "mode" "<MODEF:MODE>")
5233 (set (attr "prefix_rex")
5234 (if_then_else
5235 (and (eq_attr "prefix" "maybe_vex")
5236 (match_test "<SWI48x:MODE>mode == DImode"))
5237 (const_string "1")
5238 (const_string "*")))
5239 (set_attr "athlon_decode" "direct")
5240 (set_attr "amdfam10_decode" "double")
5241 (set_attr "bdver1_decode" "direct")
5242 (set_attr "fp_int_src" "true")])
5243
5244 (define_split
5245 [(set (match_operand:MODEF 0 "register_operand")
5246 (float:MODEF (match_operand:SWI48x 1 "register_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 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5251 && reload_completed
5252 && (SSE_REG_P (operands[0])
5253 || (GET_CODE (operands[0]) == SUBREG
5254 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5255 [(set (match_dup 2) (match_dup 1))
5256 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5257
5258 (define_split
5259 [(set (match_operand:MODEF 0 "register_operand")
5260 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5261 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5262 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5263 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5264 && reload_completed
5265 && (SSE_REG_P (operands[0])
5266 || (GET_CODE (operands[0]) == SUBREG
5267 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5268 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5269
5270 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5271 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5272 (float:X87MODEF
5273 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5274 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5275 "TARGET_80387
5276 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5277 "@
5278 fild%Z1\t%1
5279 #"
5280 [(set_attr "type" "fmov,multi")
5281 (set_attr "mode" "<X87MODEF:MODE>")
5282 (set_attr "unit" "*,i387")
5283 (set_attr "fp_int_src" "true")])
5284
5285 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5286 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5287 (float:X87MODEF
5288 (match_operand:SWI48x 1 "memory_operand" "m")))]
5289 "TARGET_80387
5290 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5291 "fild%Z1\t%1"
5292 [(set_attr "type" "fmov")
5293 (set_attr "mode" "<X87MODEF:MODE>")
5294 (set_attr "fp_int_src" "true")])
5295
5296 (define_split
5297 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5298 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5299 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5300 "TARGET_80387
5301 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5302 && reload_completed"
5303 [(set (match_dup 2) (match_dup 1))
5304 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5305
5306 (define_split
5307 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5308 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5309 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5310 "TARGET_80387
5311 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5312 && reload_completed"
5313 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5314
5315 ;; Avoid store forwarding (partial memory) stall penalty
5316 ;; by passing DImode value through XMM registers. */
5317
5318 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5319 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5320 (float:X87MODEF
5321 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5322 (clobber (match_scratch:V4SI 3 "=X,x"))
5323 (clobber (match_scratch:V4SI 4 "=X,x"))
5324 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5325 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5326 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5327 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5328 "#"
5329 [(set_attr "type" "multi")
5330 (set_attr "mode" "<X87MODEF:MODE>")
5331 (set_attr "unit" "i387")
5332 (set_attr "fp_int_src" "true")])
5333
5334 (define_split
5335 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5336 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5337 (clobber (match_scratch:V4SI 3))
5338 (clobber (match_scratch:V4SI 4))
5339 (clobber (match_operand:DI 2 "memory_operand"))]
5340 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5341 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5342 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5343 && reload_completed"
5344 [(set (match_dup 2) (match_dup 3))
5345 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5346 {
5347 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5348 Assemble the 64-bit DImode value in an xmm register. */
5349 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5350 gen_rtx_SUBREG (SImode, operands[1], 0)));
5351 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5352 gen_rtx_SUBREG (SImode, operands[1], 4)));
5353 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5354 operands[4]));
5355
5356 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5357 })
5358
5359 (define_split
5360 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5361 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5362 (clobber (match_scratch:V4SI 3))
5363 (clobber (match_scratch:V4SI 4))
5364 (clobber (match_operand:DI 2 "memory_operand"))]
5365 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5366 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5367 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5368 && reload_completed"
5369 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5370
5371 ;; Avoid store forwarding (partial memory) stall penalty by extending
5372 ;; SImode value to DImode through XMM register instead of pushing two
5373 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5374 ;; targets benefit from this optimization. Also note that fild
5375 ;; loads from memory only.
5376
5377 (define_insn "*floatunssi<mode>2_1"
5378 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5379 (unsigned_float:X87MODEF
5380 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5381 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5382 (clobber (match_scratch:SI 3 "=X,x"))]
5383 "!TARGET_64BIT
5384 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5385 && TARGET_SSE"
5386 "#"
5387 [(set_attr "type" "multi")
5388 (set_attr "mode" "<MODE>")])
5389
5390 (define_split
5391 [(set (match_operand:X87MODEF 0 "register_operand")
5392 (unsigned_float:X87MODEF
5393 (match_operand:SI 1 "register_operand")))
5394 (clobber (match_operand:DI 2 "memory_operand"))
5395 (clobber (match_scratch:SI 3))]
5396 "!TARGET_64BIT
5397 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5398 && TARGET_SSE
5399 && reload_completed"
5400 [(set (match_dup 2) (match_dup 1))
5401 (set (match_dup 0)
5402 (float:X87MODEF (match_dup 2)))]
5403 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5404
5405 (define_split
5406 [(set (match_operand:X87MODEF 0 "register_operand")
5407 (unsigned_float:X87MODEF
5408 (match_operand:SI 1 "memory_operand")))
5409 (clobber (match_operand:DI 2 "memory_operand"))
5410 (clobber (match_scratch:SI 3))]
5411 "!TARGET_64BIT
5412 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5413 && TARGET_SSE
5414 && reload_completed"
5415 [(set (match_dup 2) (match_dup 3))
5416 (set (match_dup 0)
5417 (float:X87MODEF (match_dup 2)))]
5418 {
5419 emit_move_insn (operands[3], operands[1]);
5420 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5421 })
5422
5423 (define_expand "floatunssi<mode>2"
5424 [(parallel
5425 [(set (match_operand:X87MODEF 0 "register_operand")
5426 (unsigned_float:X87MODEF
5427 (match_operand:SI 1 "nonimmediate_operand")))
5428 (clobber (match_dup 2))
5429 (clobber (match_scratch:SI 3))])]
5430 "!TARGET_64BIT
5431 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5432 && TARGET_SSE)
5433 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5434 {
5435 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5436 {
5437 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5438 DONE;
5439 }
5440 else
5441 {
5442 enum ix86_stack_slot slot = (virtuals_instantiated
5443 ? SLOT_TEMP
5444 : SLOT_VIRTUAL);
5445 operands[2] = assign_386_stack_local (DImode, slot);
5446 }
5447 })
5448
5449 (define_expand "floatunsdisf2"
5450 [(use (match_operand:SF 0 "register_operand"))
5451 (use (match_operand:DI 1 "nonimmediate_operand"))]
5452 "TARGET_64BIT && TARGET_SSE_MATH"
5453 "x86_emit_floatuns (operands); DONE;")
5454
5455 (define_expand "floatunsdidf2"
5456 [(use (match_operand:DF 0 "register_operand"))
5457 (use (match_operand:DI 1 "nonimmediate_operand"))]
5458 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5459 && TARGET_SSE2 && TARGET_SSE_MATH"
5460 {
5461 if (TARGET_64BIT)
5462 x86_emit_floatuns (operands);
5463 else
5464 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5465 DONE;
5466 })
5467 \f
5468 ;; Load effective address instructions
5469
5470 (define_insn_and_split "*lea<mode>"
5471 [(set (match_operand:SWI48 0 "register_operand" "=r")
5472 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5473 ""
5474 {
5475 rtx addr = operands[1];
5476
5477 if (GET_CODE (addr) == SUBREG)
5478 {
5479 gcc_assert (TARGET_64BIT);
5480 gcc_assert (<MODE>mode == SImode);
5481 gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
5482 return "lea{l}\t{%E1, %0|%0, %E1}";
5483 }
5484 else if (GET_CODE (addr) == ZERO_EXTEND
5485 || GET_CODE (addr) == AND)
5486 {
5487 gcc_assert (TARGET_64BIT);
5488 gcc_assert (<MODE>mode == DImode);
5489 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5490 }
5491 else
5492 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5493 }
5494 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5495 [(const_int 0)]
5496 {
5497 enum machine_mode mode = <MODE>mode;
5498 rtx pat;
5499
5500 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5501 change operands[] array behind our back. */
5502 pat = PATTERN (curr_insn);
5503
5504 operands[0] = SET_DEST (pat);
5505 operands[1] = SET_SRC (pat);
5506
5507 /* Emit all operations in SImode for zero-extended addresses. Recall
5508 that x86_64 inheretly zero-extends SImode operations to DImode. */
5509 if (GET_CODE (operands[1]) == ZERO_EXTEND
5510 || GET_CODE (operands[1]) == AND)
5511 mode = SImode;
5512
5513 ix86_split_lea_for_addr (operands, mode);
5514 DONE;
5515 }
5516 [(set_attr "type" "lea")
5517 (set_attr "mode" "<MODE>")])
5518 \f
5519 ;; Add instructions
5520
5521 (define_expand "add<mode>3"
5522 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5523 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5524 (match_operand:SDWIM 2 "<general_operand>")))]
5525 ""
5526 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5527
5528 (define_insn_and_split "*add<dwi>3_doubleword"
5529 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5530 (plus:<DWI>
5531 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5532 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5533 (clobber (reg:CC FLAGS_REG))]
5534 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5535 "#"
5536 "reload_completed"
5537 [(parallel [(set (reg:CC FLAGS_REG)
5538 (unspec:CC [(match_dup 1) (match_dup 2)]
5539 UNSPEC_ADD_CARRY))
5540 (set (match_dup 0)
5541 (plus:DWIH (match_dup 1) (match_dup 2)))])
5542 (parallel [(set (match_dup 3)
5543 (plus:DWIH
5544 (match_dup 4)
5545 (plus:DWIH
5546 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5547 (match_dup 5))))
5548 (clobber (reg:CC FLAGS_REG))])]
5549 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5550
5551 (define_insn "*add<mode>3_cc"
5552 [(set (reg:CC FLAGS_REG)
5553 (unspec:CC
5554 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5555 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5556 UNSPEC_ADD_CARRY))
5557 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5558 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5559 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5560 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5561 [(set_attr "type" "alu")
5562 (set_attr "mode" "<MODE>")])
5563
5564 (define_insn "addqi3_cc"
5565 [(set (reg:CC FLAGS_REG)
5566 (unspec:CC
5567 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5568 (match_operand:QI 2 "general_operand" "qn,qm")]
5569 UNSPEC_ADD_CARRY))
5570 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5571 (plus:QI (match_dup 1) (match_dup 2)))]
5572 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5573 "add{b}\t{%2, %0|%0, %2}"
5574 [(set_attr "type" "alu")
5575 (set_attr "mode" "QI")])
5576
5577 (define_insn "*add<mode>_1"
5578 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5579 (plus:SWI48
5580 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5581 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5582 (clobber (reg:CC FLAGS_REG))]
5583 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5584 {
5585 switch (get_attr_type (insn))
5586 {
5587 case TYPE_LEA:
5588 return "#";
5589
5590 case TYPE_INCDEC:
5591 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5592 if (operands[2] == const1_rtx)
5593 return "inc{<imodesuffix>}\t%0";
5594 else
5595 {
5596 gcc_assert (operands[2] == constm1_rtx);
5597 return "dec{<imodesuffix>}\t%0";
5598 }
5599
5600 default:
5601 /* For most processors, ADD is faster than LEA. This alternative
5602 was added to use ADD as much as possible. */
5603 if (which_alternative == 2)
5604 {
5605 rtx tmp;
5606 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5607 }
5608
5609 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5610 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5611 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5612
5613 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5614 }
5615 }
5616 [(set (attr "type")
5617 (cond [(eq_attr "alternative" "3")
5618 (const_string "lea")
5619 (match_operand:SWI48 2 "incdec_operand")
5620 (const_string "incdec")
5621 ]
5622 (const_string "alu")))
5623 (set (attr "length_immediate")
5624 (if_then_else
5625 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5626 (const_string "1")
5627 (const_string "*")))
5628 (set_attr "mode" "<MODE>")])
5629
5630 ;; It may seem that nonimmediate operand is proper one for operand 1.
5631 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5632 ;; we take care in ix86_binary_operator_ok to not allow two memory
5633 ;; operands so proper swapping will be done in reload. This allow
5634 ;; patterns constructed from addsi_1 to match.
5635
5636 (define_insn "addsi_1_zext"
5637 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5638 (zero_extend:DI
5639 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5640 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5641 (clobber (reg:CC FLAGS_REG))]
5642 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5643 {
5644 switch (get_attr_type (insn))
5645 {
5646 case TYPE_LEA:
5647 return "#";
5648
5649 case TYPE_INCDEC:
5650 if (operands[2] == const1_rtx)
5651 return "inc{l}\t%k0";
5652 else
5653 {
5654 gcc_assert (operands[2] == constm1_rtx);
5655 return "dec{l}\t%k0";
5656 }
5657
5658 default:
5659 /* For most processors, ADD is faster than LEA. This alternative
5660 was added to use ADD as much as possible. */
5661 if (which_alternative == 1)
5662 {
5663 rtx tmp;
5664 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5665 }
5666
5667 if (x86_maybe_negate_const_int (&operands[2], SImode))
5668 return "sub{l}\t{%2, %k0|%k0, %2}";
5669
5670 return "add{l}\t{%2, %k0|%k0, %2}";
5671 }
5672 }
5673 [(set (attr "type")
5674 (cond [(eq_attr "alternative" "2")
5675 (const_string "lea")
5676 (match_operand:SI 2 "incdec_operand")
5677 (const_string "incdec")
5678 ]
5679 (const_string "alu")))
5680 (set (attr "length_immediate")
5681 (if_then_else
5682 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5683 (const_string "1")
5684 (const_string "*")))
5685 (set_attr "mode" "SI")])
5686
5687 (define_insn "*addhi_1"
5688 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5689 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5690 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5691 (clobber (reg:CC FLAGS_REG))]
5692 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5693 {
5694 switch (get_attr_type (insn))
5695 {
5696 case TYPE_LEA:
5697 return "#";
5698
5699 case TYPE_INCDEC:
5700 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5701 if (operands[2] == const1_rtx)
5702 return "inc{w}\t%0";
5703 else
5704 {
5705 gcc_assert (operands[2] == constm1_rtx);
5706 return "dec{w}\t%0";
5707 }
5708
5709 default:
5710 /* For most processors, ADD is faster than LEA. This alternative
5711 was added to use ADD as much as possible. */
5712 if (which_alternative == 2)
5713 {
5714 rtx tmp;
5715 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5716 }
5717
5718 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5719 if (x86_maybe_negate_const_int (&operands[2], HImode))
5720 return "sub{w}\t{%2, %0|%0, %2}";
5721
5722 return "add{w}\t{%2, %0|%0, %2}";
5723 }
5724 }
5725 [(set (attr "type")
5726 (cond [(eq_attr "alternative" "3")
5727 (const_string "lea")
5728 (match_operand:HI 2 "incdec_operand")
5729 (const_string "incdec")
5730 ]
5731 (const_string "alu")))
5732 (set (attr "length_immediate")
5733 (if_then_else
5734 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5735 (const_string "1")
5736 (const_string "*")))
5737 (set_attr "mode" "HI,HI,HI,SI")])
5738
5739 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5740 (define_insn "*addqi_1"
5741 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5742 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5743 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5744 (clobber (reg:CC FLAGS_REG))]
5745 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5746 {
5747 bool widen = (which_alternative == 3 || which_alternative == 4);
5748
5749 switch (get_attr_type (insn))
5750 {
5751 case TYPE_LEA:
5752 return "#";
5753
5754 case TYPE_INCDEC:
5755 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5756 if (operands[2] == const1_rtx)
5757 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5758 else
5759 {
5760 gcc_assert (operands[2] == constm1_rtx);
5761 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5762 }
5763
5764 default:
5765 /* For most processors, ADD is faster than LEA. These alternatives
5766 were added to use ADD as much as possible. */
5767 if (which_alternative == 2 || which_alternative == 4)
5768 {
5769 rtx tmp;
5770 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5771 }
5772
5773 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5774 if (x86_maybe_negate_const_int (&operands[2], QImode))
5775 {
5776 if (widen)
5777 return "sub{l}\t{%2, %k0|%k0, %2}";
5778 else
5779 return "sub{b}\t{%2, %0|%0, %2}";
5780 }
5781 if (widen)
5782 return "add{l}\t{%k2, %k0|%k0, %k2}";
5783 else
5784 return "add{b}\t{%2, %0|%0, %2}";
5785 }
5786 }
5787 [(set (attr "type")
5788 (cond [(eq_attr "alternative" "5")
5789 (const_string "lea")
5790 (match_operand:QI 2 "incdec_operand")
5791 (const_string "incdec")
5792 ]
5793 (const_string "alu")))
5794 (set (attr "length_immediate")
5795 (if_then_else
5796 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5797 (const_string "1")
5798 (const_string "*")))
5799 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5800
5801 (define_insn "*addqi_1_slp"
5802 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5803 (plus:QI (match_dup 0)
5804 (match_operand:QI 1 "general_operand" "qn,qm")))
5805 (clobber (reg:CC FLAGS_REG))]
5806 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5808 {
5809 switch (get_attr_type (insn))
5810 {
5811 case TYPE_INCDEC:
5812 if (operands[1] == const1_rtx)
5813 return "inc{b}\t%0";
5814 else
5815 {
5816 gcc_assert (operands[1] == constm1_rtx);
5817 return "dec{b}\t%0";
5818 }
5819
5820 default:
5821 if (x86_maybe_negate_const_int (&operands[1], QImode))
5822 return "sub{b}\t{%1, %0|%0, %1}";
5823
5824 return "add{b}\t{%1, %0|%0, %1}";
5825 }
5826 }
5827 [(set (attr "type")
5828 (if_then_else (match_operand:QI 1 "incdec_operand")
5829 (const_string "incdec")
5830 (const_string "alu1")))
5831 (set (attr "memory")
5832 (if_then_else (match_operand 1 "memory_operand")
5833 (const_string "load")
5834 (const_string "none")))
5835 (set_attr "mode" "QI")])
5836
5837 ;; Split non destructive adds if we cannot use lea.
5838 (define_split
5839 [(set (match_operand:SWI48 0 "register_operand")
5840 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5841 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5842 (clobber (reg:CC FLAGS_REG))]
5843 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5844 [(set (match_dup 0) (match_dup 1))
5845 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5846 (clobber (reg:CC FLAGS_REG))])])
5847
5848 ;; Convert add to the lea pattern to avoid flags dependency.
5849 (define_split
5850 [(set (match_operand:SWI 0 "register_operand")
5851 (plus:SWI (match_operand:SWI 1 "register_operand")
5852 (match_operand:SWI 2 "<nonmemory_operand>")))
5853 (clobber (reg:CC FLAGS_REG))]
5854 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5855 [(const_int 0)]
5856 {
5857 enum machine_mode mode = <MODE>mode;
5858 rtx pat;
5859
5860 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5861 {
5862 mode = SImode;
5863 operands[0] = gen_lowpart (mode, operands[0]);
5864 operands[1] = gen_lowpart (mode, operands[1]);
5865 operands[2] = gen_lowpart (mode, operands[2]);
5866 }
5867
5868 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5869
5870 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5871 DONE;
5872 })
5873
5874 ;; Split non destructive adds if we cannot use lea.
5875 (define_split
5876 [(set (match_operand:DI 0 "register_operand")
5877 (zero_extend:DI
5878 (plus:SI (match_operand:SI 1 "register_operand")
5879 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5880 (clobber (reg:CC FLAGS_REG))]
5881 "TARGET_64BIT
5882 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5883 [(set (match_dup 3) (match_dup 1))
5884 (parallel [(set (match_dup 0)
5885 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5886 (clobber (reg:CC FLAGS_REG))])]
5887 "operands[3] = gen_lowpart (SImode, operands[0]);")
5888
5889 ;; Convert add to the lea pattern to avoid flags dependency.
5890 (define_split
5891 [(set (match_operand:DI 0 "register_operand")
5892 (zero_extend:DI
5893 (plus:SI (match_operand:SI 1 "register_operand")
5894 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5895 (clobber (reg:CC FLAGS_REG))]
5896 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5897 [(set (match_dup 0)
5898 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5899
5900 (define_insn "*add<mode>_2"
5901 [(set (reg FLAGS_REG)
5902 (compare
5903 (plus:SWI
5904 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5905 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5906 (const_int 0)))
5907 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5908 (plus:SWI (match_dup 1) (match_dup 2)))]
5909 "ix86_match_ccmode (insn, CCGOCmode)
5910 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5911 {
5912 switch (get_attr_type (insn))
5913 {
5914 case TYPE_INCDEC:
5915 if (operands[2] == const1_rtx)
5916 return "inc{<imodesuffix>}\t%0";
5917 else
5918 {
5919 gcc_assert (operands[2] == constm1_rtx);
5920 return "dec{<imodesuffix>}\t%0";
5921 }
5922
5923 default:
5924 if (which_alternative == 2)
5925 {
5926 rtx tmp;
5927 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5928 }
5929
5930 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5931 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5932 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5933
5934 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5935 }
5936 }
5937 [(set (attr "type")
5938 (if_then_else (match_operand:SWI 2 "incdec_operand")
5939 (const_string "incdec")
5940 (const_string "alu")))
5941 (set (attr "length_immediate")
5942 (if_then_else
5943 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5944 (const_string "1")
5945 (const_string "*")))
5946 (set_attr "mode" "<MODE>")])
5947
5948 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5949 (define_insn "*addsi_2_zext"
5950 [(set (reg FLAGS_REG)
5951 (compare
5952 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5953 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5954 (const_int 0)))
5955 (set (match_operand:DI 0 "register_operand" "=r,r")
5956 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5957 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5958 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5959 {
5960 switch (get_attr_type (insn))
5961 {
5962 case TYPE_INCDEC:
5963 if (operands[2] == const1_rtx)
5964 return "inc{l}\t%k0";
5965 else
5966 {
5967 gcc_assert (operands[2] == constm1_rtx);
5968 return "dec{l}\t%k0";
5969 }
5970
5971 default:
5972 if (which_alternative == 1)
5973 {
5974 rtx tmp;
5975 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5976 }
5977
5978 if (x86_maybe_negate_const_int (&operands[2], SImode))
5979 return "sub{l}\t{%2, %k0|%k0, %2}";
5980
5981 return "add{l}\t{%2, %k0|%k0, %2}";
5982 }
5983 }
5984 [(set (attr "type")
5985 (if_then_else (match_operand:SI 2 "incdec_operand")
5986 (const_string "incdec")
5987 (const_string "alu")))
5988 (set (attr "length_immediate")
5989 (if_then_else
5990 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5991 (const_string "1")
5992 (const_string "*")))
5993 (set_attr "mode" "SI")])
5994
5995 (define_insn "*add<mode>_3"
5996 [(set (reg FLAGS_REG)
5997 (compare
5998 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5999 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6000 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6001 "ix86_match_ccmode (insn, CCZmode)
6002 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6003 {
6004 switch (get_attr_type (insn))
6005 {
6006 case TYPE_INCDEC:
6007 if (operands[2] == const1_rtx)
6008 return "inc{<imodesuffix>}\t%0";
6009 else
6010 {
6011 gcc_assert (operands[2] == constm1_rtx);
6012 return "dec{<imodesuffix>}\t%0";
6013 }
6014
6015 default:
6016 if (which_alternative == 1)
6017 {
6018 rtx tmp;
6019 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6020 }
6021
6022 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6023 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6024 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6025
6026 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6027 }
6028 }
6029 [(set (attr "type")
6030 (if_then_else (match_operand:SWI 2 "incdec_operand")
6031 (const_string "incdec")
6032 (const_string "alu")))
6033 (set (attr "length_immediate")
6034 (if_then_else
6035 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6036 (const_string "1")
6037 (const_string "*")))
6038 (set_attr "mode" "<MODE>")])
6039
6040 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6041 (define_insn "*addsi_3_zext"
6042 [(set (reg FLAGS_REG)
6043 (compare
6044 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6045 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6046 (set (match_operand:DI 0 "register_operand" "=r,r")
6047 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6048 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6049 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6050 {
6051 switch (get_attr_type (insn))
6052 {
6053 case TYPE_INCDEC:
6054 if (operands[2] == const1_rtx)
6055 return "inc{l}\t%k0";
6056 else
6057 {
6058 gcc_assert (operands[2] == constm1_rtx);
6059 return "dec{l}\t%k0";
6060 }
6061
6062 default:
6063 if (which_alternative == 1)
6064 {
6065 rtx tmp;
6066 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6067 }
6068
6069 if (x86_maybe_negate_const_int (&operands[2], SImode))
6070 return "sub{l}\t{%2, %k0|%k0, %2}";
6071
6072 return "add{l}\t{%2, %k0|%k0, %2}";
6073 }
6074 }
6075 [(set (attr "type")
6076 (if_then_else (match_operand:SI 2 "incdec_operand")
6077 (const_string "incdec")
6078 (const_string "alu")))
6079 (set (attr "length_immediate")
6080 (if_then_else
6081 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6082 (const_string "1")
6083 (const_string "*")))
6084 (set_attr "mode" "SI")])
6085
6086 ; For comparisons against 1, -1 and 128, we may generate better code
6087 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6088 ; is matched then. We can't accept general immediate, because for
6089 ; case of overflows, the result is messed up.
6090 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6091 ; only for comparisons not depending on it.
6092
6093 (define_insn "*adddi_4"
6094 [(set (reg FLAGS_REG)
6095 (compare
6096 (match_operand:DI 1 "nonimmediate_operand" "0")
6097 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6098 (clobber (match_scratch:DI 0 "=rm"))]
6099 "TARGET_64BIT
6100 && ix86_match_ccmode (insn, CCGCmode)"
6101 {
6102 switch (get_attr_type (insn))
6103 {
6104 case TYPE_INCDEC:
6105 if (operands[2] == constm1_rtx)
6106 return "inc{q}\t%0";
6107 else
6108 {
6109 gcc_assert (operands[2] == const1_rtx);
6110 return "dec{q}\t%0";
6111 }
6112
6113 default:
6114 if (x86_maybe_negate_const_int (&operands[2], DImode))
6115 return "add{q}\t{%2, %0|%0, %2}";
6116
6117 return "sub{q}\t{%2, %0|%0, %2}";
6118 }
6119 }
6120 [(set (attr "type")
6121 (if_then_else (match_operand:DI 2 "incdec_operand")
6122 (const_string "incdec")
6123 (const_string "alu")))
6124 (set (attr "length_immediate")
6125 (if_then_else
6126 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6127 (const_string "1")
6128 (const_string "*")))
6129 (set_attr "mode" "DI")])
6130
6131 ; For comparisons against 1, -1 and 128, we may generate better code
6132 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6133 ; is matched then. We can't accept general immediate, because for
6134 ; case of overflows, the result is messed up.
6135 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6136 ; only for comparisons not depending on it.
6137
6138 (define_insn "*add<mode>_4"
6139 [(set (reg FLAGS_REG)
6140 (compare
6141 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6142 (match_operand:SWI124 2 "const_int_operand" "n")))
6143 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6144 "ix86_match_ccmode (insn, CCGCmode)"
6145 {
6146 switch (get_attr_type (insn))
6147 {
6148 case TYPE_INCDEC:
6149 if (operands[2] == constm1_rtx)
6150 return "inc{<imodesuffix>}\t%0";
6151 else
6152 {
6153 gcc_assert (operands[2] == const1_rtx);
6154 return "dec{<imodesuffix>}\t%0";
6155 }
6156
6157 default:
6158 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6159 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6160
6161 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6162 }
6163 }
6164 [(set (attr "type")
6165 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6166 (const_string "incdec")
6167 (const_string "alu")))
6168 (set (attr "length_immediate")
6169 (if_then_else
6170 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6171 (const_string "1")
6172 (const_string "*")))
6173 (set_attr "mode" "<MODE>")])
6174
6175 (define_insn "*add<mode>_5"
6176 [(set (reg FLAGS_REG)
6177 (compare
6178 (plus:SWI
6179 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6180 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6181 (const_int 0)))
6182 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6183 "ix86_match_ccmode (insn, CCGOCmode)
6184 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6185 {
6186 switch (get_attr_type (insn))
6187 {
6188 case TYPE_INCDEC:
6189 if (operands[2] == const1_rtx)
6190 return "inc{<imodesuffix>}\t%0";
6191 else
6192 {
6193 gcc_assert (operands[2] == constm1_rtx);
6194 return "dec{<imodesuffix>}\t%0";
6195 }
6196
6197 default:
6198 if (which_alternative == 1)
6199 {
6200 rtx tmp;
6201 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6202 }
6203
6204 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6205 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6206 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6207
6208 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6209 }
6210 }
6211 [(set (attr "type")
6212 (if_then_else (match_operand:SWI 2 "incdec_operand")
6213 (const_string "incdec")
6214 (const_string "alu")))
6215 (set (attr "length_immediate")
6216 (if_then_else
6217 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6218 (const_string "1")
6219 (const_string "*")))
6220 (set_attr "mode" "<MODE>")])
6221
6222 (define_insn "*addqi_ext_1_rex64"
6223 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6224 (const_int 8)
6225 (const_int 8))
6226 (plus:SI
6227 (zero_extract:SI
6228 (match_operand 1 "ext_register_operand" "0")
6229 (const_int 8)
6230 (const_int 8))
6231 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6232 (clobber (reg:CC FLAGS_REG))]
6233 "TARGET_64BIT"
6234 {
6235 switch (get_attr_type (insn))
6236 {
6237 case TYPE_INCDEC:
6238 if (operands[2] == const1_rtx)
6239 return "inc{b}\t%h0";
6240 else
6241 {
6242 gcc_assert (operands[2] == constm1_rtx);
6243 return "dec{b}\t%h0";
6244 }
6245
6246 default:
6247 return "add{b}\t{%2, %h0|%h0, %2}";
6248 }
6249 }
6250 [(set (attr "type")
6251 (if_then_else (match_operand:QI 2 "incdec_operand")
6252 (const_string "incdec")
6253 (const_string "alu")))
6254 (set_attr "modrm" "1")
6255 (set_attr "mode" "QI")])
6256
6257 (define_insn "addqi_ext_1"
6258 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6259 (const_int 8)
6260 (const_int 8))
6261 (plus:SI
6262 (zero_extract:SI
6263 (match_operand 1 "ext_register_operand" "0")
6264 (const_int 8)
6265 (const_int 8))
6266 (match_operand:QI 2 "general_operand" "Qmn")))
6267 (clobber (reg:CC FLAGS_REG))]
6268 "!TARGET_64BIT"
6269 {
6270 switch (get_attr_type (insn))
6271 {
6272 case TYPE_INCDEC:
6273 if (operands[2] == const1_rtx)
6274 return "inc{b}\t%h0";
6275 else
6276 {
6277 gcc_assert (operands[2] == constm1_rtx);
6278 return "dec{b}\t%h0";
6279 }
6280
6281 default:
6282 return "add{b}\t{%2, %h0|%h0, %2}";
6283 }
6284 }
6285 [(set (attr "type")
6286 (if_then_else (match_operand:QI 2 "incdec_operand")
6287 (const_string "incdec")
6288 (const_string "alu")))
6289 (set_attr "modrm" "1")
6290 (set_attr "mode" "QI")])
6291
6292 (define_insn "*addqi_ext_2"
6293 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6294 (const_int 8)
6295 (const_int 8))
6296 (plus:SI
6297 (zero_extract:SI
6298 (match_operand 1 "ext_register_operand" "%0")
6299 (const_int 8)
6300 (const_int 8))
6301 (zero_extract:SI
6302 (match_operand 2 "ext_register_operand" "Q")
6303 (const_int 8)
6304 (const_int 8))))
6305 (clobber (reg:CC FLAGS_REG))]
6306 ""
6307 "add{b}\t{%h2, %h0|%h0, %h2}"
6308 [(set_attr "type" "alu")
6309 (set_attr "mode" "QI")])
6310
6311 ;; The lea patterns for modes less than 32 bits need to be matched by
6312 ;; several insns converted to real lea by splitters.
6313
6314 (define_insn_and_split "*lea_general_1"
6315 [(set (match_operand 0 "register_operand" "=r")
6316 (plus (plus (match_operand 1 "index_register_operand" "l")
6317 (match_operand 2 "register_operand" "r"))
6318 (match_operand 3 "immediate_operand" "i")))]
6319 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6320 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6321 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6322 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6323 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6324 || GET_MODE (operands[3]) == VOIDmode)"
6325 "#"
6326 "&& reload_completed"
6327 [(const_int 0)]
6328 {
6329 enum machine_mode mode = SImode;
6330 rtx pat;
6331
6332 operands[0] = gen_lowpart (mode, operands[0]);
6333 operands[1] = gen_lowpart (mode, operands[1]);
6334 operands[2] = gen_lowpart (mode, operands[2]);
6335 operands[3] = gen_lowpart (mode, operands[3]);
6336
6337 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6338 operands[3]);
6339
6340 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6341 DONE;
6342 }
6343 [(set_attr "type" "lea")
6344 (set_attr "mode" "SI")])
6345
6346 (define_insn_and_split "*lea_general_2"
6347 [(set (match_operand 0 "register_operand" "=r")
6348 (plus (mult (match_operand 1 "index_register_operand" "l")
6349 (match_operand 2 "const248_operand" "n"))
6350 (match_operand 3 "nonmemory_operand" "ri")))]
6351 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6352 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6353 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6354 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6355 || GET_MODE (operands[3]) == VOIDmode)"
6356 "#"
6357 "&& reload_completed"
6358 [(const_int 0)]
6359 {
6360 enum machine_mode mode = SImode;
6361 rtx pat;
6362
6363 operands[0] = gen_lowpart (mode, operands[0]);
6364 operands[1] = gen_lowpart (mode, operands[1]);
6365 operands[3] = gen_lowpart (mode, operands[3]);
6366
6367 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6368 operands[3]);
6369
6370 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6371 DONE;
6372 }
6373 [(set_attr "type" "lea")
6374 (set_attr "mode" "SI")])
6375
6376 (define_insn_and_split "*lea_general_3"
6377 [(set (match_operand 0 "register_operand" "=r")
6378 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6379 (match_operand 2 "const248_operand" "n"))
6380 (match_operand 3 "register_operand" "r"))
6381 (match_operand 4 "immediate_operand" "i")))]
6382 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6383 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6384 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6385 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6386 "#"
6387 "&& reload_completed"
6388 [(const_int 0)]
6389 {
6390 enum machine_mode mode = SImode;
6391 rtx pat;
6392
6393 operands[0] = gen_lowpart (mode, operands[0]);
6394 operands[1] = gen_lowpart (mode, operands[1]);
6395 operands[3] = gen_lowpart (mode, operands[3]);
6396 operands[4] = gen_lowpart (mode, operands[4]);
6397
6398 pat = gen_rtx_PLUS (mode,
6399 gen_rtx_PLUS (mode,
6400 gen_rtx_MULT (mode, operands[1],
6401 operands[2]),
6402 operands[3]),
6403 operands[4]);
6404
6405 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6406 DONE;
6407 }
6408 [(set_attr "type" "lea")
6409 (set_attr "mode" "SI")])
6410
6411 (define_insn_and_split "*lea_general_4"
6412 [(set (match_operand 0 "register_operand" "=r")
6413 (any_or (ashift
6414 (match_operand 1 "index_register_operand" "l")
6415 (match_operand 2 "const_int_operand" "n"))
6416 (match_operand 3 "const_int_operand" "n")))]
6417 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6418 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6419 || GET_MODE (operands[0]) == SImode
6420 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6421 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6422 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6423 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6424 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6425 "#"
6426 "&& reload_completed"
6427 [(const_int 0)]
6428 {
6429 enum machine_mode mode = GET_MODE (operands[0]);
6430 rtx pat;
6431
6432 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6433 {
6434 mode = SImode;
6435 operands[0] = gen_lowpart (mode, operands[0]);
6436 operands[1] = gen_lowpart (mode, operands[1]);
6437 }
6438
6439 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6440
6441 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6442 INTVAL (operands[3]));
6443
6444 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6445 DONE;
6446 }
6447 [(set_attr "type" "lea")
6448 (set (attr "mode")
6449 (if_then_else (match_operand:DI 0)
6450 (const_string "DI")
6451 (const_string "SI")))])
6452 \f
6453 ;; Subtract instructions
6454
6455 (define_expand "sub<mode>3"
6456 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6457 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6458 (match_operand:SDWIM 2 "<general_operand>")))]
6459 ""
6460 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6461
6462 (define_insn_and_split "*sub<dwi>3_doubleword"
6463 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6464 (minus:<DWI>
6465 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6466 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6467 (clobber (reg:CC FLAGS_REG))]
6468 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6469 "#"
6470 "reload_completed"
6471 [(parallel [(set (reg:CC FLAGS_REG)
6472 (compare:CC (match_dup 1) (match_dup 2)))
6473 (set (match_dup 0)
6474 (minus:DWIH (match_dup 1) (match_dup 2)))])
6475 (parallel [(set (match_dup 3)
6476 (minus:DWIH
6477 (match_dup 4)
6478 (plus:DWIH
6479 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6480 (match_dup 5))))
6481 (clobber (reg:CC FLAGS_REG))])]
6482 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6483
6484 (define_insn "*sub<mode>_1"
6485 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6486 (minus:SWI
6487 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6488 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6489 (clobber (reg:CC FLAGS_REG))]
6490 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6491 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6492 [(set_attr "type" "alu")
6493 (set_attr "mode" "<MODE>")])
6494
6495 (define_insn "*subsi_1_zext"
6496 [(set (match_operand:DI 0 "register_operand" "=r")
6497 (zero_extend:DI
6498 (minus:SI (match_operand:SI 1 "register_operand" "0")
6499 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6500 (clobber (reg:CC FLAGS_REG))]
6501 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6502 "sub{l}\t{%2, %k0|%k0, %2}"
6503 [(set_attr "type" "alu")
6504 (set_attr "mode" "SI")])
6505
6506 (define_insn "*subqi_1_slp"
6507 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6508 (minus:QI (match_dup 0)
6509 (match_operand:QI 1 "general_operand" "qn,qm")))
6510 (clobber (reg:CC FLAGS_REG))]
6511 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6512 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6513 "sub{b}\t{%1, %0|%0, %1}"
6514 [(set_attr "type" "alu1")
6515 (set_attr "mode" "QI")])
6516
6517 (define_insn "*sub<mode>_2"
6518 [(set (reg FLAGS_REG)
6519 (compare
6520 (minus:SWI
6521 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6522 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6523 (const_int 0)))
6524 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6525 (minus:SWI (match_dup 1) (match_dup 2)))]
6526 "ix86_match_ccmode (insn, CCGOCmode)
6527 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6528 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6529 [(set_attr "type" "alu")
6530 (set_attr "mode" "<MODE>")])
6531
6532 (define_insn "*subsi_2_zext"
6533 [(set (reg FLAGS_REG)
6534 (compare
6535 (minus:SI (match_operand:SI 1 "register_operand" "0")
6536 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6537 (const_int 0)))
6538 (set (match_operand:DI 0 "register_operand" "=r")
6539 (zero_extend:DI
6540 (minus:SI (match_dup 1)
6541 (match_dup 2))))]
6542 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6543 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6544 "sub{l}\t{%2, %k0|%k0, %2}"
6545 [(set_attr "type" "alu")
6546 (set_attr "mode" "SI")])
6547
6548 (define_insn "*sub<mode>_3"
6549 [(set (reg FLAGS_REG)
6550 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6551 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6552 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6553 (minus:SWI (match_dup 1) (match_dup 2)))]
6554 "ix86_match_ccmode (insn, CCmode)
6555 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6556 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6557 [(set_attr "type" "alu")
6558 (set_attr "mode" "<MODE>")])
6559
6560 (define_insn "*subsi_3_zext"
6561 [(set (reg FLAGS_REG)
6562 (compare (match_operand:SI 1 "register_operand" "0")
6563 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6564 (set (match_operand:DI 0 "register_operand" "=r")
6565 (zero_extend:DI
6566 (minus:SI (match_dup 1)
6567 (match_dup 2))))]
6568 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6569 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6570 "sub{l}\t{%2, %1|%1, %2}"
6571 [(set_attr "type" "alu")
6572 (set_attr "mode" "SI")])
6573 \f
6574 ;; Add with carry and subtract with borrow
6575
6576 (define_expand "<plusminus_insn><mode>3_carry"
6577 [(parallel
6578 [(set (match_operand:SWI 0 "nonimmediate_operand")
6579 (plusminus:SWI
6580 (match_operand:SWI 1 "nonimmediate_operand")
6581 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6582 [(match_operand 3 "flags_reg_operand")
6583 (const_int 0)])
6584 (match_operand:SWI 2 "<general_operand>"))))
6585 (clobber (reg:CC FLAGS_REG))])]
6586 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6587
6588 (define_insn "*<plusminus_insn><mode>3_carry"
6589 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6590 (plusminus:SWI
6591 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6592 (plus:SWI
6593 (match_operator 3 "ix86_carry_flag_operator"
6594 [(reg FLAGS_REG) (const_int 0)])
6595 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6598 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "use_carry" "1")
6601 (set_attr "pent_pair" "pu")
6602 (set_attr "mode" "<MODE>")])
6603
6604 (define_insn "*addsi3_carry_zext"
6605 [(set (match_operand:DI 0 "register_operand" "=r")
6606 (zero_extend:DI
6607 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6608 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6609 [(reg FLAGS_REG) (const_int 0)])
6610 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6613 "adc{l}\t{%2, %k0|%k0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "use_carry" "1")
6616 (set_attr "pent_pair" "pu")
6617 (set_attr "mode" "SI")])
6618
6619 (define_insn "*subsi3_carry_zext"
6620 [(set (match_operand:DI 0 "register_operand" "=r")
6621 (zero_extend:DI
6622 (minus:SI (match_operand:SI 1 "register_operand" "0")
6623 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6624 [(reg FLAGS_REG) (const_int 0)])
6625 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6626 (clobber (reg:CC FLAGS_REG))]
6627 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6628 "sbb{l}\t{%2, %k0|%k0, %2}"
6629 [(set_attr "type" "alu")
6630 (set_attr "pent_pair" "pu")
6631 (set_attr "mode" "SI")])
6632 \f
6633 ;; Overflow setting add and subtract instructions
6634
6635 (define_insn "*add<mode>3_cconly_overflow"
6636 [(set (reg:CCC FLAGS_REG)
6637 (compare:CCC
6638 (plus:SWI
6639 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6640 (match_operand:SWI 2 "<general_operand>" "<g>"))
6641 (match_dup 1)))
6642 (clobber (match_scratch:SWI 0 "=<r>"))]
6643 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6644 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6645 [(set_attr "type" "alu")
6646 (set_attr "mode" "<MODE>")])
6647
6648 (define_insn "*sub<mode>3_cconly_overflow"
6649 [(set (reg:CCC FLAGS_REG)
6650 (compare:CCC
6651 (minus:SWI
6652 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6653 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6654 (match_dup 0)))]
6655 ""
6656 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6657 [(set_attr "type" "icmp")
6658 (set_attr "mode" "<MODE>")])
6659
6660 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6661 [(set (reg:CCC FLAGS_REG)
6662 (compare:CCC
6663 (plusminus:SWI
6664 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6665 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6666 (match_dup 1)))
6667 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6668 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6669 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6670 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6671 [(set_attr "type" "alu")
6672 (set_attr "mode" "<MODE>")])
6673
6674 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6675 [(set (reg:CCC FLAGS_REG)
6676 (compare:CCC
6677 (plusminus:SI
6678 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6679 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6680 (match_dup 1)))
6681 (set (match_operand:DI 0 "register_operand" "=r")
6682 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6683 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6684 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6685 [(set_attr "type" "alu")
6686 (set_attr "mode" "SI")])
6687
6688 ;; The patterns that match these are at the end of this file.
6689
6690 (define_expand "<plusminus_insn>xf3"
6691 [(set (match_operand:XF 0 "register_operand")
6692 (plusminus:XF
6693 (match_operand:XF 1 "register_operand")
6694 (match_operand:XF 2 "register_operand")))]
6695 "TARGET_80387")
6696
6697 (define_expand "<plusminus_insn><mode>3"
6698 [(set (match_operand:MODEF 0 "register_operand")
6699 (plusminus:MODEF
6700 (match_operand:MODEF 1 "register_operand")
6701 (match_operand:MODEF 2 "nonimmediate_operand")))]
6702 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6703 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6704 \f
6705 ;; Multiply instructions
6706
6707 (define_expand "mul<mode>3"
6708 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6709 (mult:SWIM248
6710 (match_operand:SWIM248 1 "register_operand")
6711 (match_operand:SWIM248 2 "<general_operand>")))
6712 (clobber (reg:CC FLAGS_REG))])])
6713
6714 (define_expand "mulqi3"
6715 [(parallel [(set (match_operand:QI 0 "register_operand")
6716 (mult:QI
6717 (match_operand:QI 1 "register_operand")
6718 (match_operand:QI 2 "nonimmediate_operand")))
6719 (clobber (reg:CC FLAGS_REG))])]
6720 "TARGET_QIMODE_MATH")
6721
6722 ;; On AMDFAM10
6723 ;; IMUL reg32/64, reg32/64, imm8 Direct
6724 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6725 ;; IMUL reg32/64, reg32/64, imm32 Direct
6726 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6727 ;; IMUL reg32/64, reg32/64 Direct
6728 ;; IMUL reg32/64, mem32/64 Direct
6729 ;;
6730 ;; On BDVER1, all above IMULs use DirectPath
6731
6732 (define_insn "*mul<mode>3_1"
6733 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6734 (mult:SWI48
6735 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6736 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6737 (clobber (reg:CC FLAGS_REG))]
6738 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6739 "@
6740 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6741 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6742 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6743 [(set_attr "type" "imul")
6744 (set_attr "prefix_0f" "0,0,1")
6745 (set (attr "athlon_decode")
6746 (cond [(eq_attr "cpu" "athlon")
6747 (const_string "vector")
6748 (eq_attr "alternative" "1")
6749 (const_string "vector")
6750 (and (eq_attr "alternative" "2")
6751 (match_operand 1 "memory_operand"))
6752 (const_string "vector")]
6753 (const_string "direct")))
6754 (set (attr "amdfam10_decode")
6755 (cond [(and (eq_attr "alternative" "0,1")
6756 (match_operand 1 "memory_operand"))
6757 (const_string "vector")]
6758 (const_string "direct")))
6759 (set_attr "bdver1_decode" "direct")
6760 (set_attr "mode" "<MODE>")])
6761
6762 (define_insn "*mulsi3_1_zext"
6763 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6764 (zero_extend:DI
6765 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6766 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6767 (clobber (reg:CC FLAGS_REG))]
6768 "TARGET_64BIT
6769 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6770 "@
6771 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6772 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6773 imul{l}\t{%2, %k0|%k0, %2}"
6774 [(set_attr "type" "imul")
6775 (set_attr "prefix_0f" "0,0,1")
6776 (set (attr "athlon_decode")
6777 (cond [(eq_attr "cpu" "athlon")
6778 (const_string "vector")
6779 (eq_attr "alternative" "1")
6780 (const_string "vector")
6781 (and (eq_attr "alternative" "2")
6782 (match_operand 1 "memory_operand"))
6783 (const_string "vector")]
6784 (const_string "direct")))
6785 (set (attr "amdfam10_decode")
6786 (cond [(and (eq_attr "alternative" "0,1")
6787 (match_operand 1 "memory_operand"))
6788 (const_string "vector")]
6789 (const_string "direct")))
6790 (set_attr "bdver1_decode" "direct")
6791 (set_attr "mode" "SI")])
6792
6793 ;; On AMDFAM10
6794 ;; IMUL reg16, reg16, imm8 VectorPath
6795 ;; IMUL reg16, mem16, imm8 VectorPath
6796 ;; IMUL reg16, reg16, imm16 VectorPath
6797 ;; IMUL reg16, mem16, imm16 VectorPath
6798 ;; IMUL reg16, reg16 Direct
6799 ;; IMUL reg16, mem16 Direct
6800 ;;
6801 ;; On BDVER1, all HI MULs use DoublePath
6802
6803 (define_insn "*mulhi3_1"
6804 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6805 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6806 (match_operand:HI 2 "general_operand" "K,n,mr")))
6807 (clobber (reg:CC FLAGS_REG))]
6808 "TARGET_HIMODE_MATH
6809 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6810 "@
6811 imul{w}\t{%2, %1, %0|%0, %1, %2}
6812 imul{w}\t{%2, %1, %0|%0, %1, %2}
6813 imul{w}\t{%2, %0|%0, %2}"
6814 [(set_attr "type" "imul")
6815 (set_attr "prefix_0f" "0,0,1")
6816 (set (attr "athlon_decode")
6817 (cond [(eq_attr "cpu" "athlon")
6818 (const_string "vector")
6819 (eq_attr "alternative" "1,2")
6820 (const_string "vector")]
6821 (const_string "direct")))
6822 (set (attr "amdfam10_decode")
6823 (cond [(eq_attr "alternative" "0,1")
6824 (const_string "vector")]
6825 (const_string "direct")))
6826 (set_attr "bdver1_decode" "double")
6827 (set_attr "mode" "HI")])
6828
6829 ;;On AMDFAM10 and BDVER1
6830 ;; MUL reg8 Direct
6831 ;; MUL mem8 Direct
6832
6833 (define_insn "*mulqi3_1"
6834 [(set (match_operand:QI 0 "register_operand" "=a")
6835 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6836 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6837 (clobber (reg:CC FLAGS_REG))]
6838 "TARGET_QIMODE_MATH
6839 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6840 "mul{b}\t%2"
6841 [(set_attr "type" "imul")
6842 (set_attr "length_immediate" "0")
6843 (set (attr "athlon_decode")
6844 (if_then_else (eq_attr "cpu" "athlon")
6845 (const_string "vector")
6846 (const_string "direct")))
6847 (set_attr "amdfam10_decode" "direct")
6848 (set_attr "bdver1_decode" "direct")
6849 (set_attr "mode" "QI")])
6850
6851 (define_expand "<u>mul<mode><dwi>3"
6852 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6853 (mult:<DWI>
6854 (any_extend:<DWI>
6855 (match_operand:DWIH 1 "nonimmediate_operand"))
6856 (any_extend:<DWI>
6857 (match_operand:DWIH 2 "register_operand"))))
6858 (clobber (reg:CC FLAGS_REG))])])
6859
6860 (define_expand "<u>mulqihi3"
6861 [(parallel [(set (match_operand:HI 0 "register_operand")
6862 (mult:HI
6863 (any_extend:HI
6864 (match_operand:QI 1 "nonimmediate_operand"))
6865 (any_extend:HI
6866 (match_operand:QI 2 "register_operand"))))
6867 (clobber (reg:CC FLAGS_REG))])]
6868 "TARGET_QIMODE_MATH")
6869
6870 (define_insn "*bmi2_umulditi3_1"
6871 [(set (match_operand:DI 0 "register_operand" "=r")
6872 (mult:DI
6873 (match_operand:DI 2 "nonimmediate_operand" "%d")
6874 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6875 (set (match_operand:DI 1 "register_operand" "=r")
6876 (truncate:DI
6877 (lshiftrt:TI
6878 (mult:TI (zero_extend:TI (match_dup 2))
6879 (zero_extend:TI (match_dup 3)))
6880 (const_int 64))))]
6881 "TARGET_64BIT && TARGET_BMI2
6882 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6883 "mulx\t{%3, %0, %1|%1, %0, %3}"
6884 [(set_attr "type" "imulx")
6885 (set_attr "prefix" "vex")
6886 (set_attr "mode" "DI")])
6887
6888 (define_insn "*bmi2_umulsidi3_1"
6889 [(set (match_operand:SI 0 "register_operand" "=r")
6890 (mult:SI
6891 (match_operand:SI 2 "nonimmediate_operand" "%d")
6892 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6893 (set (match_operand:SI 1 "register_operand" "=r")
6894 (truncate:SI
6895 (lshiftrt:DI
6896 (mult:DI (zero_extend:DI (match_dup 2))
6897 (zero_extend:DI (match_dup 3)))
6898 (const_int 32))))]
6899 "!TARGET_64BIT && TARGET_BMI2
6900 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6901 "mulx\t{%3, %0, %1|%1, %0, %3}"
6902 [(set_attr "type" "imulx")
6903 (set_attr "prefix" "vex")
6904 (set_attr "mode" "SI")])
6905
6906 (define_insn "*umul<mode><dwi>3_1"
6907 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6908 (mult:<DWI>
6909 (zero_extend:<DWI>
6910 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6911 (zero_extend:<DWI>
6912 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6913 (clobber (reg:CC FLAGS_REG))]
6914 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6915 "@
6916 #
6917 mul{<imodesuffix>}\t%2"
6918 [(set_attr "isa" "bmi2,*")
6919 (set_attr "type" "imulx,imul")
6920 (set_attr "length_immediate" "*,0")
6921 (set (attr "athlon_decode")
6922 (cond [(eq_attr "alternative" "1")
6923 (if_then_else (eq_attr "cpu" "athlon")
6924 (const_string "vector")
6925 (const_string "double"))]
6926 (const_string "*")))
6927 (set_attr "amdfam10_decode" "*,double")
6928 (set_attr "bdver1_decode" "*,direct")
6929 (set_attr "prefix" "vex,orig")
6930 (set_attr "mode" "<MODE>")])
6931
6932 ;; Convert mul to the mulx pattern to avoid flags dependency.
6933 (define_split
6934 [(set (match_operand:<DWI> 0 "register_operand")
6935 (mult:<DWI>
6936 (zero_extend:<DWI>
6937 (match_operand:DWIH 1 "register_operand"))
6938 (zero_extend:<DWI>
6939 (match_operand:DWIH 2 "nonimmediate_operand"))))
6940 (clobber (reg:CC FLAGS_REG))]
6941 "TARGET_BMI2 && reload_completed
6942 && true_regnum (operands[1]) == DX_REG"
6943 [(parallel [(set (match_dup 3)
6944 (mult:DWIH (match_dup 1) (match_dup 2)))
6945 (set (match_dup 4)
6946 (truncate:DWIH
6947 (lshiftrt:<DWI>
6948 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6949 (zero_extend:<DWI> (match_dup 2)))
6950 (match_dup 5))))])]
6951 {
6952 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6953
6954 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6955 })
6956
6957 (define_insn "*mul<mode><dwi>3_1"
6958 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6959 (mult:<DWI>
6960 (sign_extend:<DWI>
6961 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6962 (sign_extend:<DWI>
6963 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6964 (clobber (reg:CC FLAGS_REG))]
6965 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6966 "imul{<imodesuffix>}\t%2"
6967 [(set_attr "type" "imul")
6968 (set_attr "length_immediate" "0")
6969 (set (attr "athlon_decode")
6970 (if_then_else (eq_attr "cpu" "athlon")
6971 (const_string "vector")
6972 (const_string "double")))
6973 (set_attr "amdfam10_decode" "double")
6974 (set_attr "bdver1_decode" "direct")
6975 (set_attr "mode" "<MODE>")])
6976
6977 (define_insn "*<u>mulqihi3_1"
6978 [(set (match_operand:HI 0 "register_operand" "=a")
6979 (mult:HI
6980 (any_extend:HI
6981 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6982 (any_extend:HI
6983 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6984 (clobber (reg:CC FLAGS_REG))]
6985 "TARGET_QIMODE_MATH
6986 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6987 "<sgnprefix>mul{b}\t%2"
6988 [(set_attr "type" "imul")
6989 (set_attr "length_immediate" "0")
6990 (set (attr "athlon_decode")
6991 (if_then_else (eq_attr "cpu" "athlon")
6992 (const_string "vector")
6993 (const_string "direct")))
6994 (set_attr "amdfam10_decode" "direct")
6995 (set_attr "bdver1_decode" "direct")
6996 (set_attr "mode" "QI")])
6997
6998 (define_expand "<s>mul<mode>3_highpart"
6999 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7000 (truncate:SWI48
7001 (lshiftrt:<DWI>
7002 (mult:<DWI>
7003 (any_extend:<DWI>
7004 (match_operand:SWI48 1 "nonimmediate_operand"))
7005 (any_extend:<DWI>
7006 (match_operand:SWI48 2 "register_operand")))
7007 (match_dup 4))))
7008 (clobber (match_scratch:SWI48 3))
7009 (clobber (reg:CC FLAGS_REG))])]
7010 ""
7011 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7012
7013 (define_insn "*<s>muldi3_highpart_1"
7014 [(set (match_operand:DI 0 "register_operand" "=d")
7015 (truncate:DI
7016 (lshiftrt:TI
7017 (mult:TI
7018 (any_extend:TI
7019 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7020 (any_extend:TI
7021 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7022 (const_int 64))))
7023 (clobber (match_scratch:DI 3 "=1"))
7024 (clobber (reg:CC FLAGS_REG))]
7025 "TARGET_64BIT
7026 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7027 "<sgnprefix>mul{q}\t%2"
7028 [(set_attr "type" "imul")
7029 (set_attr "length_immediate" "0")
7030 (set (attr "athlon_decode")
7031 (if_then_else (eq_attr "cpu" "athlon")
7032 (const_string "vector")
7033 (const_string "double")))
7034 (set_attr "amdfam10_decode" "double")
7035 (set_attr "bdver1_decode" "direct")
7036 (set_attr "mode" "DI")])
7037
7038 (define_insn "*<s>mulsi3_highpart_1"
7039 [(set (match_operand:SI 0 "register_operand" "=d")
7040 (truncate:SI
7041 (lshiftrt:DI
7042 (mult:DI
7043 (any_extend:DI
7044 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7045 (any_extend:DI
7046 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7047 (const_int 32))))
7048 (clobber (match_scratch:SI 3 "=1"))
7049 (clobber (reg:CC FLAGS_REG))]
7050 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7051 "<sgnprefix>mul{l}\t%2"
7052 [(set_attr "type" "imul")
7053 (set_attr "length_immediate" "0")
7054 (set (attr "athlon_decode")
7055 (if_then_else (eq_attr "cpu" "athlon")
7056 (const_string "vector")
7057 (const_string "double")))
7058 (set_attr "amdfam10_decode" "double")
7059 (set_attr "bdver1_decode" "direct")
7060 (set_attr "mode" "SI")])
7061
7062 (define_insn "*<s>mulsi3_highpart_zext"
7063 [(set (match_operand:DI 0 "register_operand" "=d")
7064 (zero_extend:DI (truncate:SI
7065 (lshiftrt:DI
7066 (mult:DI (any_extend:DI
7067 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7068 (any_extend:DI
7069 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7070 (const_int 32)))))
7071 (clobber (match_scratch:SI 3 "=1"))
7072 (clobber (reg:CC FLAGS_REG))]
7073 "TARGET_64BIT
7074 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7075 "<sgnprefix>mul{l}\t%2"
7076 [(set_attr "type" "imul")
7077 (set_attr "length_immediate" "0")
7078 (set (attr "athlon_decode")
7079 (if_then_else (eq_attr "cpu" "athlon")
7080 (const_string "vector")
7081 (const_string "double")))
7082 (set_attr "amdfam10_decode" "double")
7083 (set_attr "bdver1_decode" "direct")
7084 (set_attr "mode" "SI")])
7085
7086 ;; The patterns that match these are at the end of this file.
7087
7088 (define_expand "mulxf3"
7089 [(set (match_operand:XF 0 "register_operand")
7090 (mult:XF (match_operand:XF 1 "register_operand")
7091 (match_operand:XF 2 "register_operand")))]
7092 "TARGET_80387")
7093
7094 (define_expand "mul<mode>3"
7095 [(set (match_operand:MODEF 0 "register_operand")
7096 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7097 (match_operand:MODEF 2 "nonimmediate_operand")))]
7098 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7099 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7100 \f
7101 ;; Divide instructions
7102
7103 ;; The patterns that match these are at the end of this file.
7104
7105 (define_expand "divxf3"
7106 [(set (match_operand:XF 0 "register_operand")
7107 (div:XF (match_operand:XF 1 "register_operand")
7108 (match_operand:XF 2 "register_operand")))]
7109 "TARGET_80387")
7110
7111 (define_expand "divdf3"
7112 [(set (match_operand:DF 0 "register_operand")
7113 (div:DF (match_operand:DF 1 "register_operand")
7114 (match_operand:DF 2 "nonimmediate_operand")))]
7115 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7116 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7117
7118 (define_expand "divsf3"
7119 [(set (match_operand:SF 0 "register_operand")
7120 (div:SF (match_operand:SF 1 "register_operand")
7121 (match_operand:SF 2 "nonimmediate_operand")))]
7122 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7123 || TARGET_SSE_MATH"
7124 {
7125 if (TARGET_SSE_MATH
7126 && TARGET_RECIP_DIV
7127 && optimize_insn_for_speed_p ()
7128 && flag_finite_math_only && !flag_trapping_math
7129 && flag_unsafe_math_optimizations)
7130 {
7131 ix86_emit_swdivsf (operands[0], operands[1],
7132 operands[2], SFmode);
7133 DONE;
7134 }
7135 })
7136 \f
7137 ;; Divmod instructions.
7138
7139 (define_expand "divmod<mode>4"
7140 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7141 (div:SWIM248
7142 (match_operand:SWIM248 1 "register_operand")
7143 (match_operand:SWIM248 2 "nonimmediate_operand")))
7144 (set (match_operand:SWIM248 3 "register_operand")
7145 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7146 (clobber (reg:CC FLAGS_REG))])])
7147
7148 ;; Split with 8bit unsigned divide:
7149 ;; if (dividend an divisor are in [0-255])
7150 ;; use 8bit unsigned integer divide
7151 ;; else
7152 ;; use original integer divide
7153 (define_split
7154 [(set (match_operand:SWI48 0 "register_operand")
7155 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7156 (match_operand:SWI48 3 "nonimmediate_operand")))
7157 (set (match_operand:SWI48 1 "register_operand")
7158 (mod:SWI48 (match_dup 2) (match_dup 3)))
7159 (clobber (reg:CC FLAGS_REG))]
7160 "TARGET_USE_8BIT_IDIV
7161 && TARGET_QIMODE_MATH
7162 && can_create_pseudo_p ()
7163 && !optimize_insn_for_size_p ()"
7164 [(const_int 0)]
7165 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7166
7167 (define_insn_and_split "divmod<mode>4_1"
7168 [(set (match_operand:SWI48 0 "register_operand" "=a")
7169 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7170 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7171 (set (match_operand:SWI48 1 "register_operand" "=&d")
7172 (mod:SWI48 (match_dup 2) (match_dup 3)))
7173 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7174 (clobber (reg:CC FLAGS_REG))]
7175 ""
7176 "#"
7177 "reload_completed"
7178 [(parallel [(set (match_dup 1)
7179 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7180 (clobber (reg:CC FLAGS_REG))])
7181 (parallel [(set (match_dup 0)
7182 (div:SWI48 (match_dup 2) (match_dup 3)))
7183 (set (match_dup 1)
7184 (mod:SWI48 (match_dup 2) (match_dup 3)))
7185 (use (match_dup 1))
7186 (clobber (reg:CC FLAGS_REG))])]
7187 {
7188 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7189
7190 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7191 operands[4] = operands[2];
7192 else
7193 {
7194 /* Avoid use of cltd in favor of a mov+shift. */
7195 emit_move_insn (operands[1], operands[2]);
7196 operands[4] = operands[1];
7197 }
7198 }
7199 [(set_attr "type" "multi")
7200 (set_attr "mode" "<MODE>")])
7201
7202 (define_insn_and_split "*divmod<mode>4"
7203 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7204 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7205 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7206 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7207 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7208 (clobber (reg:CC FLAGS_REG))]
7209 ""
7210 "#"
7211 "reload_completed"
7212 [(parallel [(set (match_dup 1)
7213 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7214 (clobber (reg:CC FLAGS_REG))])
7215 (parallel [(set (match_dup 0)
7216 (div:SWIM248 (match_dup 2) (match_dup 3)))
7217 (set (match_dup 1)
7218 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7219 (use (match_dup 1))
7220 (clobber (reg:CC FLAGS_REG))])]
7221 {
7222 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7223
7224 if (<MODE>mode != HImode
7225 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7226 operands[4] = operands[2];
7227 else
7228 {
7229 /* Avoid use of cltd in favor of a mov+shift. */
7230 emit_move_insn (operands[1], operands[2]);
7231 operands[4] = operands[1];
7232 }
7233 }
7234 [(set_attr "type" "multi")
7235 (set_attr "mode" "<MODE>")])
7236
7237 (define_insn "*divmod<mode>4_noext"
7238 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7239 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7240 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7241 (set (match_operand:SWIM248 1 "register_operand" "=d")
7242 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7243 (use (match_operand:SWIM248 4 "register_operand" "1"))
7244 (clobber (reg:CC FLAGS_REG))]
7245 ""
7246 "idiv{<imodesuffix>}\t%3"
7247 [(set_attr "type" "idiv")
7248 (set_attr "mode" "<MODE>")])
7249
7250 (define_expand "divmodqi4"
7251 [(parallel [(set (match_operand:QI 0 "register_operand")
7252 (div:QI
7253 (match_operand:QI 1 "register_operand")
7254 (match_operand:QI 2 "nonimmediate_operand")))
7255 (set (match_operand:QI 3 "register_operand")
7256 (mod:QI (match_dup 1) (match_dup 2)))
7257 (clobber (reg:CC FLAGS_REG))])]
7258 "TARGET_QIMODE_MATH"
7259 {
7260 rtx div, mod, insn;
7261 rtx tmp0, tmp1;
7262
7263 tmp0 = gen_reg_rtx (HImode);
7264 tmp1 = gen_reg_rtx (HImode);
7265
7266 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7267 in AX. */
7268 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7269 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7270
7271 /* Extract remainder from AH. */
7272 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7273 insn = emit_move_insn (operands[3], tmp1);
7274
7275 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7276 set_unique_reg_note (insn, REG_EQUAL, mod);
7277
7278 /* Extract quotient from AL. */
7279 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7280
7281 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7282 set_unique_reg_note (insn, REG_EQUAL, div);
7283
7284 DONE;
7285 })
7286
7287 ;; Divide AX by r/m8, with result stored in
7288 ;; AL <- Quotient
7289 ;; AH <- Remainder
7290 ;; Change div/mod to HImode and extend the second argument to HImode
7291 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7292 ;; combine may fail.
7293 (define_insn "divmodhiqi3"
7294 [(set (match_operand:HI 0 "register_operand" "=a")
7295 (ior:HI
7296 (ashift:HI
7297 (zero_extend:HI
7298 (truncate:QI
7299 (mod:HI (match_operand:HI 1 "register_operand" "0")
7300 (sign_extend:HI
7301 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7302 (const_int 8))
7303 (zero_extend:HI
7304 (truncate:QI
7305 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7306 (clobber (reg:CC FLAGS_REG))]
7307 "TARGET_QIMODE_MATH"
7308 "idiv{b}\t%2"
7309 [(set_attr "type" "idiv")
7310 (set_attr "mode" "QI")])
7311
7312 (define_expand "udivmod<mode>4"
7313 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7314 (udiv:SWIM248
7315 (match_operand:SWIM248 1 "register_operand")
7316 (match_operand:SWIM248 2 "nonimmediate_operand")))
7317 (set (match_operand:SWIM248 3 "register_operand")
7318 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7319 (clobber (reg:CC FLAGS_REG))])])
7320
7321 ;; Split with 8bit unsigned divide:
7322 ;; if (dividend an divisor are in [0-255])
7323 ;; use 8bit unsigned integer divide
7324 ;; else
7325 ;; use original integer divide
7326 (define_split
7327 [(set (match_operand:SWI48 0 "register_operand")
7328 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7329 (match_operand:SWI48 3 "nonimmediate_operand")))
7330 (set (match_operand:SWI48 1 "register_operand")
7331 (umod:SWI48 (match_dup 2) (match_dup 3)))
7332 (clobber (reg:CC FLAGS_REG))]
7333 "TARGET_USE_8BIT_IDIV
7334 && TARGET_QIMODE_MATH
7335 && can_create_pseudo_p ()
7336 && !optimize_insn_for_size_p ()"
7337 [(const_int 0)]
7338 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7339
7340 (define_insn_and_split "udivmod<mode>4_1"
7341 [(set (match_operand:SWI48 0 "register_operand" "=a")
7342 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7343 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7344 (set (match_operand:SWI48 1 "register_operand" "=&d")
7345 (umod:SWI48 (match_dup 2) (match_dup 3)))
7346 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7347 (clobber (reg:CC FLAGS_REG))]
7348 ""
7349 "#"
7350 "reload_completed"
7351 [(set (match_dup 1) (const_int 0))
7352 (parallel [(set (match_dup 0)
7353 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7354 (set (match_dup 1)
7355 (umod:SWI48 (match_dup 2) (match_dup 3)))
7356 (use (match_dup 1))
7357 (clobber (reg:CC FLAGS_REG))])]
7358 ""
7359 [(set_attr "type" "multi")
7360 (set_attr "mode" "<MODE>")])
7361
7362 (define_insn_and_split "*udivmod<mode>4"
7363 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7364 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7365 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7366 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7367 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7368 (clobber (reg:CC FLAGS_REG))]
7369 ""
7370 "#"
7371 "reload_completed"
7372 [(set (match_dup 1) (const_int 0))
7373 (parallel [(set (match_dup 0)
7374 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7375 (set (match_dup 1)
7376 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7377 (use (match_dup 1))
7378 (clobber (reg:CC FLAGS_REG))])]
7379 ""
7380 [(set_attr "type" "multi")
7381 (set_attr "mode" "<MODE>")])
7382
7383 (define_insn "*udivmod<mode>4_noext"
7384 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7385 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7386 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7387 (set (match_operand:SWIM248 1 "register_operand" "=d")
7388 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7389 (use (match_operand:SWIM248 4 "register_operand" "1"))
7390 (clobber (reg:CC FLAGS_REG))]
7391 ""
7392 "div{<imodesuffix>}\t%3"
7393 [(set_attr "type" "idiv")
7394 (set_attr "mode" "<MODE>")])
7395
7396 (define_expand "udivmodqi4"
7397 [(parallel [(set (match_operand:QI 0 "register_operand")
7398 (udiv:QI
7399 (match_operand:QI 1 "register_operand")
7400 (match_operand:QI 2 "nonimmediate_operand")))
7401 (set (match_operand:QI 3 "register_operand")
7402 (umod:QI (match_dup 1) (match_dup 2)))
7403 (clobber (reg:CC FLAGS_REG))])]
7404 "TARGET_QIMODE_MATH"
7405 {
7406 rtx div, mod, insn;
7407 rtx tmp0, tmp1;
7408
7409 tmp0 = gen_reg_rtx (HImode);
7410 tmp1 = gen_reg_rtx (HImode);
7411
7412 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7413 in AX. */
7414 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7415 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7416
7417 /* Extract remainder from AH. */
7418 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7419 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7420 insn = emit_move_insn (operands[3], tmp1);
7421
7422 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7423 set_unique_reg_note (insn, REG_EQUAL, mod);
7424
7425 /* Extract quotient from AL. */
7426 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7427
7428 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7429 set_unique_reg_note (insn, REG_EQUAL, div);
7430
7431 DONE;
7432 })
7433
7434 (define_insn "udivmodhiqi3"
7435 [(set (match_operand:HI 0 "register_operand" "=a")
7436 (ior:HI
7437 (ashift:HI
7438 (zero_extend:HI
7439 (truncate:QI
7440 (mod:HI (match_operand:HI 1 "register_operand" "0")
7441 (zero_extend:HI
7442 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7443 (const_int 8))
7444 (zero_extend:HI
7445 (truncate:QI
7446 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7447 (clobber (reg:CC FLAGS_REG))]
7448 "TARGET_QIMODE_MATH"
7449 "div{b}\t%2"
7450 [(set_attr "type" "idiv")
7451 (set_attr "mode" "QI")])
7452
7453 ;; We cannot use div/idiv for double division, because it causes
7454 ;; "division by zero" on the overflow and that's not what we expect
7455 ;; from truncate. Because true (non truncating) double division is
7456 ;; never generated, we can't create this insn anyway.
7457 ;
7458 ;(define_insn ""
7459 ; [(set (match_operand:SI 0 "register_operand" "=a")
7460 ; (truncate:SI
7461 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7462 ; (zero_extend:DI
7463 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7464 ; (set (match_operand:SI 3 "register_operand" "=d")
7465 ; (truncate:SI
7466 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7467 ; (clobber (reg:CC FLAGS_REG))]
7468 ; ""
7469 ; "div{l}\t{%2, %0|%0, %2}"
7470 ; [(set_attr "type" "idiv")])
7471 \f
7472 ;;- Logical AND instructions
7473
7474 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7475 ;; Note that this excludes ah.
7476
7477 (define_expand "testsi_ccno_1"
7478 [(set (reg:CCNO FLAGS_REG)
7479 (compare:CCNO
7480 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7481 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7482 (const_int 0)))])
7483
7484 (define_expand "testqi_ccz_1"
7485 [(set (reg:CCZ FLAGS_REG)
7486 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7487 (match_operand:QI 1 "nonmemory_operand"))
7488 (const_int 0)))])
7489
7490 (define_expand "testdi_ccno_1"
7491 [(set (reg:CCNO FLAGS_REG)
7492 (compare:CCNO
7493 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7494 (match_operand:DI 1 "x86_64_szext_general_operand"))
7495 (const_int 0)))]
7496 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7497
7498 (define_insn "*testdi_1"
7499 [(set (reg FLAGS_REG)
7500 (compare
7501 (and:DI
7502 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7503 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7504 (const_int 0)))]
7505 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7506 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7507 "@
7508 test{l}\t{%k1, %k0|%k0, %k1}
7509 test{l}\t{%k1, %k0|%k0, %k1}
7510 test{q}\t{%1, %0|%0, %1}
7511 test{q}\t{%1, %0|%0, %1}
7512 test{q}\t{%1, %0|%0, %1}"
7513 [(set_attr "type" "test")
7514 (set_attr "modrm" "0,1,0,1,1")
7515 (set_attr "mode" "SI,SI,DI,DI,DI")])
7516
7517 (define_insn "*testqi_1_maybe_si"
7518 [(set (reg FLAGS_REG)
7519 (compare
7520 (and:QI
7521 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7522 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7523 (const_int 0)))]
7524 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7525 && ix86_match_ccmode (insn,
7526 CONST_INT_P (operands[1])
7527 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7528 {
7529 if (which_alternative == 3)
7530 {
7531 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7532 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7533 return "test{l}\t{%1, %k0|%k0, %1}";
7534 }
7535 return "test{b}\t{%1, %0|%0, %1}";
7536 }
7537 [(set_attr "type" "test")
7538 (set_attr "modrm" "0,1,1,1")
7539 (set_attr "mode" "QI,QI,QI,SI")
7540 (set_attr "pent_pair" "uv,np,uv,np")])
7541
7542 (define_insn "*test<mode>_1"
7543 [(set (reg FLAGS_REG)
7544 (compare
7545 (and:SWI124
7546 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7547 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7548 (const_int 0)))]
7549 "ix86_match_ccmode (insn, CCNOmode)
7550 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7551 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7552 [(set_attr "type" "test")
7553 (set_attr "modrm" "0,1,1")
7554 (set_attr "mode" "<MODE>")
7555 (set_attr "pent_pair" "uv,np,uv")])
7556
7557 (define_expand "testqi_ext_ccno_0"
7558 [(set (reg:CCNO FLAGS_REG)
7559 (compare:CCNO
7560 (and:SI
7561 (zero_extract:SI
7562 (match_operand 0 "ext_register_operand")
7563 (const_int 8)
7564 (const_int 8))
7565 (match_operand 1 "const_int_operand"))
7566 (const_int 0)))])
7567
7568 (define_insn "*testqi_ext_0"
7569 [(set (reg FLAGS_REG)
7570 (compare
7571 (and:SI
7572 (zero_extract:SI
7573 (match_operand 0 "ext_register_operand" "Q")
7574 (const_int 8)
7575 (const_int 8))
7576 (match_operand 1 "const_int_operand" "n"))
7577 (const_int 0)))]
7578 "ix86_match_ccmode (insn, CCNOmode)"
7579 "test{b}\t{%1, %h0|%h0, %1}"
7580 [(set_attr "type" "test")
7581 (set_attr "mode" "QI")
7582 (set_attr "length_immediate" "1")
7583 (set_attr "modrm" "1")
7584 (set_attr "pent_pair" "np")])
7585
7586 (define_insn "*testqi_ext_1_rex64"
7587 [(set (reg FLAGS_REG)
7588 (compare
7589 (and:SI
7590 (zero_extract:SI
7591 (match_operand 0 "ext_register_operand" "Q")
7592 (const_int 8)
7593 (const_int 8))
7594 (zero_extend:SI
7595 (match_operand:QI 1 "register_operand" "Q")))
7596 (const_int 0)))]
7597 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7598 "test{b}\t{%1, %h0|%h0, %1}"
7599 [(set_attr "type" "test")
7600 (set_attr "mode" "QI")])
7601
7602 (define_insn "*testqi_ext_1"
7603 [(set (reg FLAGS_REG)
7604 (compare
7605 (and:SI
7606 (zero_extract:SI
7607 (match_operand 0 "ext_register_operand" "Q")
7608 (const_int 8)
7609 (const_int 8))
7610 (zero_extend:SI
7611 (match_operand:QI 1 "general_operand" "Qm")))
7612 (const_int 0)))]
7613 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7614 "test{b}\t{%1, %h0|%h0, %1}"
7615 [(set_attr "type" "test")
7616 (set_attr "mode" "QI")])
7617
7618 (define_insn "*testqi_ext_2"
7619 [(set (reg FLAGS_REG)
7620 (compare
7621 (and:SI
7622 (zero_extract:SI
7623 (match_operand 0 "ext_register_operand" "Q")
7624 (const_int 8)
7625 (const_int 8))
7626 (zero_extract:SI
7627 (match_operand 1 "ext_register_operand" "Q")
7628 (const_int 8)
7629 (const_int 8)))
7630 (const_int 0)))]
7631 "ix86_match_ccmode (insn, CCNOmode)"
7632 "test{b}\t{%h1, %h0|%h0, %h1}"
7633 [(set_attr "type" "test")
7634 (set_attr "mode" "QI")])
7635
7636 (define_insn "*testqi_ext_3_rex64"
7637 [(set (reg FLAGS_REG)
7638 (compare (zero_extract:DI
7639 (match_operand 0 "nonimmediate_operand" "rm")
7640 (match_operand:DI 1 "const_int_operand")
7641 (match_operand:DI 2 "const_int_operand"))
7642 (const_int 0)))]
7643 "TARGET_64BIT
7644 && ix86_match_ccmode (insn, CCNOmode)
7645 && INTVAL (operands[1]) > 0
7646 && INTVAL (operands[2]) >= 0
7647 /* Ensure that resulting mask is zero or sign extended operand. */
7648 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7649 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7650 && INTVAL (operands[1]) > 32))
7651 && (GET_MODE (operands[0]) == SImode
7652 || GET_MODE (operands[0]) == DImode
7653 || GET_MODE (operands[0]) == HImode
7654 || GET_MODE (operands[0]) == QImode)"
7655 "#")
7656
7657 ;; Combine likes to form bit extractions for some tests. Humor it.
7658 (define_insn "*testqi_ext_3"
7659 [(set (reg FLAGS_REG)
7660 (compare (zero_extract:SI
7661 (match_operand 0 "nonimmediate_operand" "rm")
7662 (match_operand:SI 1 "const_int_operand")
7663 (match_operand:SI 2 "const_int_operand"))
7664 (const_int 0)))]
7665 "ix86_match_ccmode (insn, CCNOmode)
7666 && INTVAL (operands[1]) > 0
7667 && INTVAL (operands[2]) >= 0
7668 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7669 && (GET_MODE (operands[0]) == SImode
7670 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7671 || GET_MODE (operands[0]) == HImode
7672 || GET_MODE (operands[0]) == QImode)"
7673 "#")
7674
7675 (define_split
7676 [(set (match_operand 0 "flags_reg_operand")
7677 (match_operator 1 "compare_operator"
7678 [(zero_extract
7679 (match_operand 2 "nonimmediate_operand")
7680 (match_operand 3 "const_int_operand")
7681 (match_operand 4 "const_int_operand"))
7682 (const_int 0)]))]
7683 "ix86_match_ccmode (insn, CCNOmode)"
7684 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7685 {
7686 rtx val = operands[2];
7687 HOST_WIDE_INT len = INTVAL (operands[3]);
7688 HOST_WIDE_INT pos = INTVAL (operands[4]);
7689 HOST_WIDE_INT mask;
7690 enum machine_mode mode, submode;
7691
7692 mode = GET_MODE (val);
7693 if (MEM_P (val))
7694 {
7695 /* ??? Combine likes to put non-volatile mem extractions in QImode
7696 no matter the size of the test. So find a mode that works. */
7697 if (! MEM_VOLATILE_P (val))
7698 {
7699 mode = smallest_mode_for_size (pos + len, MODE_INT);
7700 val = adjust_address (val, mode, 0);
7701 }
7702 }
7703 else if (GET_CODE (val) == SUBREG
7704 && (submode = GET_MODE (SUBREG_REG (val)),
7705 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7706 && pos + len <= GET_MODE_BITSIZE (submode)
7707 && GET_MODE_CLASS (submode) == MODE_INT)
7708 {
7709 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7710 mode = submode;
7711 val = SUBREG_REG (val);
7712 }
7713 else if (mode == HImode && pos + len <= 8)
7714 {
7715 /* Small HImode tests can be converted to QImode. */
7716 mode = QImode;
7717 val = gen_lowpart (QImode, val);
7718 }
7719
7720 if (len == HOST_BITS_PER_WIDE_INT)
7721 mask = -1;
7722 else
7723 mask = ((HOST_WIDE_INT)1 << len) - 1;
7724 mask <<= pos;
7725
7726 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7727 })
7728
7729 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7730 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7731 ;; this is relatively important trick.
7732 ;; Do the conversion only post-reload to avoid limiting of the register class
7733 ;; to QI regs.
7734 (define_split
7735 [(set (match_operand 0 "flags_reg_operand")
7736 (match_operator 1 "compare_operator"
7737 [(and (match_operand 2 "register_operand")
7738 (match_operand 3 "const_int_operand"))
7739 (const_int 0)]))]
7740 "reload_completed
7741 && QI_REG_P (operands[2])
7742 && GET_MODE (operands[2]) != QImode
7743 && ((ix86_match_ccmode (insn, CCZmode)
7744 && !(INTVAL (operands[3]) & ~(255 << 8)))
7745 || (ix86_match_ccmode (insn, CCNOmode)
7746 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7747 [(set (match_dup 0)
7748 (match_op_dup 1
7749 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7750 (match_dup 3))
7751 (const_int 0)]))]
7752 {
7753 operands[2] = gen_lowpart (SImode, operands[2]);
7754 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7755 })
7756
7757 (define_split
7758 [(set (match_operand 0 "flags_reg_operand")
7759 (match_operator 1 "compare_operator"
7760 [(and (match_operand 2 "nonimmediate_operand")
7761 (match_operand 3 "const_int_operand"))
7762 (const_int 0)]))]
7763 "reload_completed
7764 && GET_MODE (operands[2]) != QImode
7765 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7766 && ((ix86_match_ccmode (insn, CCZmode)
7767 && !(INTVAL (operands[3]) & ~255))
7768 || (ix86_match_ccmode (insn, CCNOmode)
7769 && !(INTVAL (operands[3]) & ~127)))"
7770 [(set (match_dup 0)
7771 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7772 (const_int 0)]))]
7773 {
7774 operands[2] = gen_lowpart (QImode, operands[2]);
7775 operands[3] = gen_lowpart (QImode, operands[3]);
7776 })
7777
7778 ;; %%% This used to optimize known byte-wide and operations to memory,
7779 ;; and sometimes to QImode registers. If this is considered useful,
7780 ;; it should be done with splitters.
7781
7782 (define_expand "and<mode>3"
7783 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7784 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7785 (match_operand:SWIM 2 "<general_szext_operand>")))]
7786 ""
7787 {
7788 enum machine_mode mode = <MODE>mode;
7789 rtx (*insn) (rtx, rtx);
7790
7791 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7792 {
7793 HOST_WIDE_INT ival = INTVAL (operands[2]);
7794
7795 if (ival == (HOST_WIDE_INT) 0xffffffff)
7796 mode = SImode;
7797 else if (ival == 0xffff)
7798 mode = HImode;
7799 else if (ival == 0xff)
7800 mode = QImode;
7801 }
7802
7803 if (mode == <MODE>mode)
7804 {
7805 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7806 DONE;
7807 }
7808
7809 if (<MODE>mode == DImode)
7810 insn = (mode == SImode)
7811 ? gen_zero_extendsidi2
7812 : (mode == HImode)
7813 ? gen_zero_extendhidi2
7814 : gen_zero_extendqidi2;
7815 else if (<MODE>mode == SImode)
7816 insn = (mode == HImode)
7817 ? gen_zero_extendhisi2
7818 : gen_zero_extendqisi2;
7819 else if (<MODE>mode == HImode)
7820 insn = gen_zero_extendqihi2;
7821 else
7822 gcc_unreachable ();
7823
7824 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7825 DONE;
7826 })
7827
7828 (define_insn "*anddi_1"
7829 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7830 (and:DI
7831 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7832 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7833 (clobber (reg:CC FLAGS_REG))]
7834 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7835 {
7836 switch (get_attr_type (insn))
7837 {
7838 case TYPE_IMOVX:
7839 return "#";
7840
7841 default:
7842 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7843 if (get_attr_mode (insn) == MODE_SI)
7844 return "and{l}\t{%k2, %k0|%k0, %k2}";
7845 else
7846 return "and{q}\t{%2, %0|%0, %2}";
7847 }
7848 }
7849 [(set_attr "type" "alu,alu,alu,imovx")
7850 (set_attr "length_immediate" "*,*,*,0")
7851 (set (attr "prefix_rex")
7852 (if_then_else
7853 (and (eq_attr "type" "imovx")
7854 (and (match_test "INTVAL (operands[2]) == 0xff")
7855 (match_operand 1 "ext_QIreg_operand")))
7856 (const_string "1")
7857 (const_string "*")))
7858 (set_attr "mode" "SI,DI,DI,SI")])
7859
7860 (define_insn "*andsi_1"
7861 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7862 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7863 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7864 (clobber (reg:CC FLAGS_REG))]
7865 "ix86_binary_operator_ok (AND, SImode, operands)"
7866 {
7867 switch (get_attr_type (insn))
7868 {
7869 case TYPE_IMOVX:
7870 return "#";
7871
7872 default:
7873 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7874 return "and{l}\t{%2, %0|%0, %2}";
7875 }
7876 }
7877 [(set_attr "type" "alu,alu,imovx")
7878 (set (attr "prefix_rex")
7879 (if_then_else
7880 (and (eq_attr "type" "imovx")
7881 (and (match_test "INTVAL (operands[2]) == 0xff")
7882 (match_operand 1 "ext_QIreg_operand")))
7883 (const_string "1")
7884 (const_string "*")))
7885 (set_attr "length_immediate" "*,*,0")
7886 (set_attr "mode" "SI")])
7887
7888 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7889 (define_insn "*andsi_1_zext"
7890 [(set (match_operand:DI 0 "register_operand" "=r")
7891 (zero_extend:DI
7892 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7893 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7894 (clobber (reg:CC FLAGS_REG))]
7895 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7896 "and{l}\t{%2, %k0|%k0, %2}"
7897 [(set_attr "type" "alu")
7898 (set_attr "mode" "SI")])
7899
7900 (define_insn "*andhi_1"
7901 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7902 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7903 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7904 (clobber (reg:CC FLAGS_REG))]
7905 "ix86_binary_operator_ok (AND, HImode, operands)"
7906 {
7907 switch (get_attr_type (insn))
7908 {
7909 case TYPE_IMOVX:
7910 return "#";
7911
7912 default:
7913 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7914 return "and{w}\t{%2, %0|%0, %2}";
7915 }
7916 }
7917 [(set_attr "type" "alu,alu,imovx")
7918 (set_attr "length_immediate" "*,*,0")
7919 (set (attr "prefix_rex")
7920 (if_then_else
7921 (and (eq_attr "type" "imovx")
7922 (match_operand 1 "ext_QIreg_operand"))
7923 (const_string "1")
7924 (const_string "*")))
7925 (set_attr "mode" "HI,HI,SI")])
7926
7927 ;; %%% Potential partial reg stall on alternative 2. What to do?
7928 (define_insn "*andqi_1"
7929 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7930 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7931 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7932 (clobber (reg:CC FLAGS_REG))]
7933 "ix86_binary_operator_ok (AND, QImode, operands)"
7934 "@
7935 and{b}\t{%2, %0|%0, %2}
7936 and{b}\t{%2, %0|%0, %2}
7937 and{l}\t{%k2, %k0|%k0, %k2}"
7938 [(set_attr "type" "alu")
7939 (set_attr "mode" "QI,QI,SI")])
7940
7941 (define_insn "*andqi_1_slp"
7942 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7943 (and:QI (match_dup 0)
7944 (match_operand:QI 1 "general_operand" "qn,qmn")))
7945 (clobber (reg:CC FLAGS_REG))]
7946 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7947 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7948 "and{b}\t{%1, %0|%0, %1}"
7949 [(set_attr "type" "alu1")
7950 (set_attr "mode" "QI")])
7951
7952 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7953 (define_split
7954 [(set (match_operand:DI 0 "register_operand")
7955 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7956 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7957 (clobber (reg:CC FLAGS_REG))]
7958 "TARGET_64BIT"
7959 [(parallel [(set (match_dup 0)
7960 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7961 (clobber (reg:CC FLAGS_REG))])]
7962 "operands[2] = gen_lowpart (SImode, operands[2]);")
7963
7964 (define_split
7965 [(set (match_operand:SWI248 0 "register_operand")
7966 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7967 (match_operand:SWI248 2 "const_int_operand")))
7968 (clobber (reg:CC FLAGS_REG))]
7969 "reload_completed
7970 && true_regnum (operands[0]) != true_regnum (operands[1])"
7971 [(const_int 0)]
7972 {
7973 HOST_WIDE_INT ival = INTVAL (operands[2]);
7974 enum machine_mode mode;
7975 rtx (*insn) (rtx, rtx);
7976
7977 if (ival == (HOST_WIDE_INT) 0xffffffff)
7978 mode = SImode;
7979 else if (ival == 0xffff)
7980 mode = HImode;
7981 else
7982 {
7983 gcc_assert (ival == 0xff);
7984 mode = QImode;
7985 }
7986
7987 if (<MODE>mode == DImode)
7988 insn = (mode == SImode)
7989 ? gen_zero_extendsidi2
7990 : (mode == HImode)
7991 ? gen_zero_extendhidi2
7992 : gen_zero_extendqidi2;
7993 else
7994 {
7995 if (<MODE>mode != SImode)
7996 /* Zero extend to SImode to avoid partial register stalls. */
7997 operands[0] = gen_lowpart (SImode, operands[0]);
7998
7999 insn = (mode == HImode)
8000 ? gen_zero_extendhisi2
8001 : gen_zero_extendqisi2;
8002 }
8003 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8004 DONE;
8005 })
8006
8007 (define_split
8008 [(set (match_operand 0 "register_operand")
8009 (and (match_dup 0)
8010 (const_int -65536)))
8011 (clobber (reg:CC FLAGS_REG))]
8012 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8013 || optimize_function_for_size_p (cfun)"
8014 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8015 "operands[1] = gen_lowpart (HImode, operands[0]);")
8016
8017 (define_split
8018 [(set (match_operand 0 "ext_register_operand")
8019 (and (match_dup 0)
8020 (const_int -256)))
8021 (clobber (reg:CC FLAGS_REG))]
8022 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8023 && reload_completed"
8024 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8025 "operands[1] = gen_lowpart (QImode, operands[0]);")
8026
8027 (define_split
8028 [(set (match_operand 0 "ext_register_operand")
8029 (and (match_dup 0)
8030 (const_int -65281)))
8031 (clobber (reg:CC FLAGS_REG))]
8032 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8033 && reload_completed"
8034 [(parallel [(set (zero_extract:SI (match_dup 0)
8035 (const_int 8)
8036 (const_int 8))
8037 (xor:SI
8038 (zero_extract:SI (match_dup 0)
8039 (const_int 8)
8040 (const_int 8))
8041 (zero_extract:SI (match_dup 0)
8042 (const_int 8)
8043 (const_int 8))))
8044 (clobber (reg:CC FLAGS_REG))])]
8045 "operands[0] = gen_lowpart (SImode, operands[0]);")
8046
8047 (define_insn "*anddi_2"
8048 [(set (reg FLAGS_REG)
8049 (compare
8050 (and:DI
8051 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8052 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8053 (const_int 0)))
8054 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8055 (and:DI (match_dup 1) (match_dup 2)))]
8056 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8057 && ix86_binary_operator_ok (AND, DImode, operands)"
8058 "@
8059 and{l}\t{%k2, %k0|%k0, %k2}
8060 and{q}\t{%2, %0|%0, %2}
8061 and{q}\t{%2, %0|%0, %2}"
8062 [(set_attr "type" "alu")
8063 (set_attr "mode" "SI,DI,DI")])
8064
8065 (define_insn "*andqi_2_maybe_si"
8066 [(set (reg FLAGS_REG)
8067 (compare (and:QI
8068 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8069 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8070 (const_int 0)))
8071 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8072 (and:QI (match_dup 1) (match_dup 2)))]
8073 "ix86_binary_operator_ok (AND, QImode, operands)
8074 && ix86_match_ccmode (insn,
8075 CONST_INT_P (operands[2])
8076 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8077 {
8078 if (which_alternative == 2)
8079 {
8080 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8081 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8082 return "and{l}\t{%2, %k0|%k0, %2}";
8083 }
8084 return "and{b}\t{%2, %0|%0, %2}";
8085 }
8086 [(set_attr "type" "alu")
8087 (set_attr "mode" "QI,QI,SI")])
8088
8089 (define_insn "*and<mode>_2"
8090 [(set (reg FLAGS_REG)
8091 (compare (and:SWI124
8092 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8093 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8094 (const_int 0)))
8095 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8096 (and:SWI124 (match_dup 1) (match_dup 2)))]
8097 "ix86_match_ccmode (insn, CCNOmode)
8098 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8099 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8100 [(set_attr "type" "alu")
8101 (set_attr "mode" "<MODE>")])
8102
8103 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8104 (define_insn "*andsi_2_zext"
8105 [(set (reg FLAGS_REG)
8106 (compare (and:SI
8107 (match_operand:SI 1 "nonimmediate_operand" "%0")
8108 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8109 (const_int 0)))
8110 (set (match_operand:DI 0 "register_operand" "=r")
8111 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8112 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8113 && ix86_binary_operator_ok (AND, SImode, operands)"
8114 "and{l}\t{%2, %k0|%k0, %2}"
8115 [(set_attr "type" "alu")
8116 (set_attr "mode" "SI")])
8117
8118 (define_insn "*andqi_2_slp"
8119 [(set (reg FLAGS_REG)
8120 (compare (and:QI
8121 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8122 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8123 (const_int 0)))
8124 (set (strict_low_part (match_dup 0))
8125 (and:QI (match_dup 0) (match_dup 1)))]
8126 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8127 && ix86_match_ccmode (insn, CCNOmode)
8128 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8129 "and{b}\t{%1, %0|%0, %1}"
8130 [(set_attr "type" "alu1")
8131 (set_attr "mode" "QI")])
8132
8133 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8134 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8135 ;; for a QImode operand, which of course failed.
8136 (define_insn "andqi_ext_0"
8137 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8138 (const_int 8)
8139 (const_int 8))
8140 (and:SI
8141 (zero_extract:SI
8142 (match_operand 1 "ext_register_operand" "0")
8143 (const_int 8)
8144 (const_int 8))
8145 (match_operand 2 "const_int_operand" "n")))
8146 (clobber (reg:CC FLAGS_REG))]
8147 ""
8148 "and{b}\t{%2, %h0|%h0, %2}"
8149 [(set_attr "type" "alu")
8150 (set_attr "length_immediate" "1")
8151 (set_attr "modrm" "1")
8152 (set_attr "mode" "QI")])
8153
8154 ;; Generated by peephole translating test to and. This shows up
8155 ;; often in fp comparisons.
8156 (define_insn "*andqi_ext_0_cc"
8157 [(set (reg FLAGS_REG)
8158 (compare
8159 (and:SI
8160 (zero_extract:SI
8161 (match_operand 1 "ext_register_operand" "0")
8162 (const_int 8)
8163 (const_int 8))
8164 (match_operand 2 "const_int_operand" "n"))
8165 (const_int 0)))
8166 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8167 (const_int 8)
8168 (const_int 8))
8169 (and:SI
8170 (zero_extract:SI
8171 (match_dup 1)
8172 (const_int 8)
8173 (const_int 8))
8174 (match_dup 2)))]
8175 "ix86_match_ccmode (insn, CCNOmode)"
8176 "and{b}\t{%2, %h0|%h0, %2}"
8177 [(set_attr "type" "alu")
8178 (set_attr "length_immediate" "1")
8179 (set_attr "modrm" "1")
8180 (set_attr "mode" "QI")])
8181
8182 (define_insn "*andqi_ext_1_rex64"
8183 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8184 (const_int 8)
8185 (const_int 8))
8186 (and:SI
8187 (zero_extract:SI
8188 (match_operand 1 "ext_register_operand" "0")
8189 (const_int 8)
8190 (const_int 8))
8191 (zero_extend:SI
8192 (match_operand 2 "ext_register_operand" "Q"))))
8193 (clobber (reg:CC FLAGS_REG))]
8194 "TARGET_64BIT"
8195 "and{b}\t{%2, %h0|%h0, %2}"
8196 [(set_attr "type" "alu")
8197 (set_attr "length_immediate" "0")
8198 (set_attr "mode" "QI")])
8199
8200 (define_insn "*andqi_ext_1"
8201 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8202 (const_int 8)
8203 (const_int 8))
8204 (and:SI
8205 (zero_extract:SI
8206 (match_operand 1 "ext_register_operand" "0")
8207 (const_int 8)
8208 (const_int 8))
8209 (zero_extend:SI
8210 (match_operand:QI 2 "general_operand" "Qm"))))
8211 (clobber (reg:CC FLAGS_REG))]
8212 "!TARGET_64BIT"
8213 "and{b}\t{%2, %h0|%h0, %2}"
8214 [(set_attr "type" "alu")
8215 (set_attr "length_immediate" "0")
8216 (set_attr "mode" "QI")])
8217
8218 (define_insn "*andqi_ext_2"
8219 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8220 (const_int 8)
8221 (const_int 8))
8222 (and:SI
8223 (zero_extract:SI
8224 (match_operand 1 "ext_register_operand" "%0")
8225 (const_int 8)
8226 (const_int 8))
8227 (zero_extract:SI
8228 (match_operand 2 "ext_register_operand" "Q")
8229 (const_int 8)
8230 (const_int 8))))
8231 (clobber (reg:CC FLAGS_REG))]
8232 ""
8233 "and{b}\t{%h2, %h0|%h0, %h2}"
8234 [(set_attr "type" "alu")
8235 (set_attr "length_immediate" "0")
8236 (set_attr "mode" "QI")])
8237
8238 ;; Convert wide AND instructions with immediate operand to shorter QImode
8239 ;; equivalents when possible.
8240 ;; Don't do the splitting with memory operands, since it introduces risk
8241 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8242 ;; for size, but that can (should?) be handled by generic code instead.
8243 (define_split
8244 [(set (match_operand 0 "register_operand")
8245 (and (match_operand 1 "register_operand")
8246 (match_operand 2 "const_int_operand")))
8247 (clobber (reg:CC FLAGS_REG))]
8248 "reload_completed
8249 && QI_REG_P (operands[0])
8250 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8251 && !(~INTVAL (operands[2]) & ~(255 << 8))
8252 && GET_MODE (operands[0]) != QImode"
8253 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8254 (and:SI (zero_extract:SI (match_dup 1)
8255 (const_int 8) (const_int 8))
8256 (match_dup 2)))
8257 (clobber (reg:CC FLAGS_REG))])]
8258 {
8259 operands[0] = gen_lowpart (SImode, operands[0]);
8260 operands[1] = gen_lowpart (SImode, operands[1]);
8261 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8262 })
8263
8264 ;; Since AND can be encoded with sign extended immediate, this is only
8265 ;; profitable when 7th bit is not set.
8266 (define_split
8267 [(set (match_operand 0 "register_operand")
8268 (and (match_operand 1 "general_operand")
8269 (match_operand 2 "const_int_operand")))
8270 (clobber (reg:CC FLAGS_REG))]
8271 "reload_completed
8272 && ANY_QI_REG_P (operands[0])
8273 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8274 && !(~INTVAL (operands[2]) & ~255)
8275 && !(INTVAL (operands[2]) & 128)
8276 && GET_MODE (operands[0]) != QImode"
8277 [(parallel [(set (strict_low_part (match_dup 0))
8278 (and:QI (match_dup 1)
8279 (match_dup 2)))
8280 (clobber (reg:CC FLAGS_REG))])]
8281 {
8282 operands[0] = gen_lowpart (QImode, operands[0]);
8283 operands[1] = gen_lowpart (QImode, operands[1]);
8284 operands[2] = gen_lowpart (QImode, operands[2]);
8285 })
8286 \f
8287 ;; Logical inclusive and exclusive OR instructions
8288
8289 ;; %%% This used to optimize known byte-wide and operations to memory.
8290 ;; If this is considered useful, it should be done with splitters.
8291
8292 (define_expand "<code><mode>3"
8293 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8294 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8295 (match_operand:SWIM 2 "<general_operand>")))]
8296 ""
8297 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8298
8299 (define_insn "*<code><mode>_1"
8300 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8301 (any_or:SWI248
8302 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8303 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8304 (clobber (reg:CC FLAGS_REG))]
8305 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8306 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8307 [(set_attr "type" "alu")
8308 (set_attr "mode" "<MODE>")])
8309
8310 ;; %%% Potential partial reg stall on alternative 2. What to do?
8311 (define_insn "*<code>qi_1"
8312 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8313 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8314 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8315 (clobber (reg:CC FLAGS_REG))]
8316 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8317 "@
8318 <logic>{b}\t{%2, %0|%0, %2}
8319 <logic>{b}\t{%2, %0|%0, %2}
8320 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8321 [(set_attr "type" "alu")
8322 (set_attr "mode" "QI,QI,SI")])
8323
8324 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8325 (define_insn "*<code>si_1_zext"
8326 [(set (match_operand:DI 0 "register_operand" "=r")
8327 (zero_extend:DI
8328 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8329 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8330 (clobber (reg:CC FLAGS_REG))]
8331 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8332 "<logic>{l}\t{%2, %k0|%k0, %2}"
8333 [(set_attr "type" "alu")
8334 (set_attr "mode" "SI")])
8335
8336 (define_insn "*<code>si_1_zext_imm"
8337 [(set (match_operand:DI 0 "register_operand" "=r")
8338 (any_or:DI
8339 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8340 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8341 (clobber (reg:CC FLAGS_REG))]
8342 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8343 "<logic>{l}\t{%2, %k0|%k0, %2}"
8344 [(set_attr "type" "alu")
8345 (set_attr "mode" "SI")])
8346
8347 (define_insn "*<code>qi_1_slp"
8348 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8349 (any_or:QI (match_dup 0)
8350 (match_operand:QI 1 "general_operand" "qmn,qn")))
8351 (clobber (reg:CC FLAGS_REG))]
8352 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8353 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8354 "<logic>{b}\t{%1, %0|%0, %1}"
8355 [(set_attr "type" "alu1")
8356 (set_attr "mode" "QI")])
8357
8358 (define_insn "*<code><mode>_2"
8359 [(set (reg FLAGS_REG)
8360 (compare (any_or:SWI
8361 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8362 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8363 (const_int 0)))
8364 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8365 (any_or:SWI (match_dup 1) (match_dup 2)))]
8366 "ix86_match_ccmode (insn, CCNOmode)
8367 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8368 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8369 [(set_attr "type" "alu")
8370 (set_attr "mode" "<MODE>")])
8371
8372 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8373 ;; ??? Special case for immediate operand is missing - it is tricky.
8374 (define_insn "*<code>si_2_zext"
8375 [(set (reg FLAGS_REG)
8376 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8377 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8378 (const_int 0)))
8379 (set (match_operand:DI 0 "register_operand" "=r")
8380 (zero_extend:DI (any_or:SI (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>si_2_zext_imm"
8388 [(set (reg FLAGS_REG)
8389 (compare (any_or:SI
8390 (match_operand:SI 1 "nonimmediate_operand" "%0")
8391 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8392 (const_int 0)))
8393 (set (match_operand:DI 0 "register_operand" "=r")
8394 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8395 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8396 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8397 "<logic>{l}\t{%2, %k0|%k0, %2}"
8398 [(set_attr "type" "alu")
8399 (set_attr "mode" "SI")])
8400
8401 (define_insn "*<code>qi_2_slp"
8402 [(set (reg FLAGS_REG)
8403 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8404 (match_operand:QI 1 "general_operand" "qmn,qn"))
8405 (const_int 0)))
8406 (set (strict_low_part (match_dup 0))
8407 (any_or:QI (match_dup 0) (match_dup 1)))]
8408 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8409 && ix86_match_ccmode (insn, CCNOmode)
8410 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8411 "<logic>{b}\t{%1, %0|%0, %1}"
8412 [(set_attr "type" "alu1")
8413 (set_attr "mode" "QI")])
8414
8415 (define_insn "*<code><mode>_3"
8416 [(set (reg FLAGS_REG)
8417 (compare (any_or:SWI
8418 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8419 (match_operand:SWI 2 "<general_operand>" "<g>"))
8420 (const_int 0)))
8421 (clobber (match_scratch:SWI 0 "=<r>"))]
8422 "ix86_match_ccmode (insn, CCNOmode)
8423 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8424 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8425 [(set_attr "type" "alu")
8426 (set_attr "mode" "<MODE>")])
8427
8428 (define_insn "*<code>qi_ext_0"
8429 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8430 (const_int 8)
8431 (const_int 8))
8432 (any_or:SI
8433 (zero_extract:SI
8434 (match_operand 1 "ext_register_operand" "0")
8435 (const_int 8)
8436 (const_int 8))
8437 (match_operand 2 "const_int_operand" "n")))
8438 (clobber (reg:CC FLAGS_REG))]
8439 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8440 "<logic>{b}\t{%2, %h0|%h0, %2}"
8441 [(set_attr "type" "alu")
8442 (set_attr "length_immediate" "1")
8443 (set_attr "modrm" "1")
8444 (set_attr "mode" "QI")])
8445
8446 (define_insn "*<code>qi_ext_1_rex64"
8447 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8448 (const_int 8)
8449 (const_int 8))
8450 (any_or:SI
8451 (zero_extract:SI
8452 (match_operand 1 "ext_register_operand" "0")
8453 (const_int 8)
8454 (const_int 8))
8455 (zero_extend:SI
8456 (match_operand 2 "ext_register_operand" "Q"))))
8457 (clobber (reg:CC FLAGS_REG))]
8458 "TARGET_64BIT
8459 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8460 "<logic>{b}\t{%2, %h0|%h0, %2}"
8461 [(set_attr "type" "alu")
8462 (set_attr "length_immediate" "0")
8463 (set_attr "mode" "QI")])
8464
8465 (define_insn "*<code>qi_ext_1"
8466 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8467 (const_int 8)
8468 (const_int 8))
8469 (any_or:SI
8470 (zero_extract:SI
8471 (match_operand 1 "ext_register_operand" "0")
8472 (const_int 8)
8473 (const_int 8))
8474 (zero_extend:SI
8475 (match_operand:QI 2 "general_operand" "Qm"))))
8476 (clobber (reg:CC FLAGS_REG))]
8477 "!TARGET_64BIT
8478 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8479 "<logic>{b}\t{%2, %h0|%h0, %2}"
8480 [(set_attr "type" "alu")
8481 (set_attr "length_immediate" "0")
8482 (set_attr "mode" "QI")])
8483
8484 (define_insn "*<code>qi_ext_2"
8485 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8486 (const_int 8)
8487 (const_int 8))
8488 (any_or:SI
8489 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8490 (const_int 8)
8491 (const_int 8))
8492 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8493 (const_int 8)
8494 (const_int 8))))
8495 (clobber (reg:CC FLAGS_REG))]
8496 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8497 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8498 [(set_attr "type" "alu")
8499 (set_attr "length_immediate" "0")
8500 (set_attr "mode" "QI")])
8501
8502 (define_split
8503 [(set (match_operand 0 "register_operand")
8504 (any_or (match_operand 1 "register_operand")
8505 (match_operand 2 "const_int_operand")))
8506 (clobber (reg:CC FLAGS_REG))]
8507 "reload_completed
8508 && QI_REG_P (operands[0])
8509 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8510 && !(INTVAL (operands[2]) & ~(255 << 8))
8511 && GET_MODE (operands[0]) != QImode"
8512 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8513 (any_or:SI (zero_extract:SI (match_dup 1)
8514 (const_int 8) (const_int 8))
8515 (match_dup 2)))
8516 (clobber (reg:CC FLAGS_REG))])]
8517 {
8518 operands[0] = gen_lowpart (SImode, operands[0]);
8519 operands[1] = gen_lowpart (SImode, operands[1]);
8520 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8521 })
8522
8523 ;; Since OR can be encoded with sign extended immediate, this is only
8524 ;; profitable when 7th bit is set.
8525 (define_split
8526 [(set (match_operand 0 "register_operand")
8527 (any_or (match_operand 1 "general_operand")
8528 (match_operand 2 "const_int_operand")))
8529 (clobber (reg:CC FLAGS_REG))]
8530 "reload_completed
8531 && ANY_QI_REG_P (operands[0])
8532 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8533 && !(INTVAL (operands[2]) & ~255)
8534 && (INTVAL (operands[2]) & 128)
8535 && GET_MODE (operands[0]) != QImode"
8536 [(parallel [(set (strict_low_part (match_dup 0))
8537 (any_or:QI (match_dup 1)
8538 (match_dup 2)))
8539 (clobber (reg:CC FLAGS_REG))])]
8540 {
8541 operands[0] = gen_lowpart (QImode, operands[0]);
8542 operands[1] = gen_lowpart (QImode, operands[1]);
8543 operands[2] = gen_lowpart (QImode, operands[2]);
8544 })
8545
8546 (define_expand "xorqi_cc_ext_1"
8547 [(parallel [
8548 (set (reg:CCNO FLAGS_REG)
8549 (compare:CCNO
8550 (xor:SI
8551 (zero_extract:SI
8552 (match_operand 1 "ext_register_operand")
8553 (const_int 8)
8554 (const_int 8))
8555 (match_operand:QI 2 "general_operand"))
8556 (const_int 0)))
8557 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8558 (const_int 8)
8559 (const_int 8))
8560 (xor:SI
8561 (zero_extract:SI
8562 (match_dup 1)
8563 (const_int 8)
8564 (const_int 8))
8565 (match_dup 2)))])])
8566
8567 (define_insn "*xorqi_cc_ext_1_rex64"
8568 [(set (reg FLAGS_REG)
8569 (compare
8570 (xor:SI
8571 (zero_extract:SI
8572 (match_operand 1 "ext_register_operand" "0")
8573 (const_int 8)
8574 (const_int 8))
8575 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8576 (const_int 0)))
8577 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8578 (const_int 8)
8579 (const_int 8))
8580 (xor:SI
8581 (zero_extract:SI
8582 (match_dup 1)
8583 (const_int 8)
8584 (const_int 8))
8585 (match_dup 2)))]
8586 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8587 "xor{b}\t{%2, %h0|%h0, %2}"
8588 [(set_attr "type" "alu")
8589 (set_attr "modrm" "1")
8590 (set_attr "mode" "QI")])
8591
8592 (define_insn "*xorqi_cc_ext_1"
8593 [(set (reg FLAGS_REG)
8594 (compare
8595 (xor:SI
8596 (zero_extract:SI
8597 (match_operand 1 "ext_register_operand" "0")
8598 (const_int 8)
8599 (const_int 8))
8600 (match_operand:QI 2 "general_operand" "qmn"))
8601 (const_int 0)))
8602 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8603 (const_int 8)
8604 (const_int 8))
8605 (xor:SI
8606 (zero_extract:SI
8607 (match_dup 1)
8608 (const_int 8)
8609 (const_int 8))
8610 (match_dup 2)))]
8611 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8612 "xor{b}\t{%2, %h0|%h0, %2}"
8613 [(set_attr "type" "alu")
8614 (set_attr "modrm" "1")
8615 (set_attr "mode" "QI")])
8616 \f
8617 ;; Negation instructions
8618
8619 (define_expand "neg<mode>2"
8620 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8621 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8622 ""
8623 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8624
8625 (define_insn_and_split "*neg<dwi>2_doubleword"
8626 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8627 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8628 (clobber (reg:CC FLAGS_REG))]
8629 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8630 "#"
8631 "reload_completed"
8632 [(parallel
8633 [(set (reg:CCZ FLAGS_REG)
8634 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8635 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8636 (parallel
8637 [(set (match_dup 2)
8638 (plus:DWIH (match_dup 3)
8639 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8640 (const_int 0))))
8641 (clobber (reg:CC FLAGS_REG))])
8642 (parallel
8643 [(set (match_dup 2)
8644 (neg:DWIH (match_dup 2)))
8645 (clobber (reg:CC FLAGS_REG))])]
8646 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8647
8648 (define_insn "*neg<mode>2_1"
8649 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8650 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8651 (clobber (reg:CC FLAGS_REG))]
8652 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8653 "neg{<imodesuffix>}\t%0"
8654 [(set_attr "type" "negnot")
8655 (set_attr "mode" "<MODE>")])
8656
8657 ;; Combine is quite creative about this pattern.
8658 (define_insn "*negsi2_1_zext"
8659 [(set (match_operand:DI 0 "register_operand" "=r")
8660 (lshiftrt:DI
8661 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8662 (const_int 32)))
8663 (const_int 32)))
8664 (clobber (reg:CC FLAGS_REG))]
8665 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8666 "neg{l}\t%k0"
8667 [(set_attr "type" "negnot")
8668 (set_attr "mode" "SI")])
8669
8670 ;; The problem with neg is that it does not perform (compare x 0),
8671 ;; it really performs (compare 0 x), which leaves us with the zero
8672 ;; flag being the only useful item.
8673
8674 (define_insn "*neg<mode>2_cmpz"
8675 [(set (reg:CCZ FLAGS_REG)
8676 (compare:CCZ
8677 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8678 (const_int 0)))
8679 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8680 (neg:SWI (match_dup 1)))]
8681 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8682 "neg{<imodesuffix>}\t%0"
8683 [(set_attr "type" "negnot")
8684 (set_attr "mode" "<MODE>")])
8685
8686 (define_insn "*negsi2_cmpz_zext"
8687 [(set (reg:CCZ FLAGS_REG)
8688 (compare:CCZ
8689 (lshiftrt:DI
8690 (neg:DI (ashift:DI
8691 (match_operand:DI 1 "register_operand" "0")
8692 (const_int 32)))
8693 (const_int 32))
8694 (const_int 0)))
8695 (set (match_operand:DI 0 "register_operand" "=r")
8696 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8697 (const_int 32)))
8698 (const_int 32)))]
8699 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8700 "neg{l}\t%k0"
8701 [(set_attr "type" "negnot")
8702 (set_attr "mode" "SI")])
8703
8704 ;; Changing of sign for FP values is doable using integer unit too.
8705
8706 (define_expand "<code><mode>2"
8707 [(set (match_operand:X87MODEF 0 "register_operand")
8708 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8709 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8710 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8711
8712 (define_insn "*absneg<mode>2_mixed"
8713 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8714 (match_operator:MODEF 3 "absneg_operator"
8715 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8716 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8717 (clobber (reg:CC FLAGS_REG))]
8718 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8719 "#")
8720
8721 (define_insn "*absneg<mode>2_sse"
8722 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8723 (match_operator:MODEF 3 "absneg_operator"
8724 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8725 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8726 (clobber (reg:CC FLAGS_REG))]
8727 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8728 "#")
8729
8730 (define_insn "*absneg<mode>2_i387"
8731 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8732 (match_operator:X87MODEF 3 "absneg_operator"
8733 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8734 (use (match_operand 2))
8735 (clobber (reg:CC FLAGS_REG))]
8736 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8737 "#")
8738
8739 (define_expand "<code>tf2"
8740 [(set (match_operand:TF 0 "register_operand")
8741 (absneg:TF (match_operand:TF 1 "register_operand")))]
8742 "TARGET_SSE"
8743 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8744
8745 (define_insn "*absnegtf2_sse"
8746 [(set (match_operand:TF 0 "register_operand" "=x,x")
8747 (match_operator:TF 3 "absneg_operator"
8748 [(match_operand:TF 1 "register_operand" "0,x")]))
8749 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8750 (clobber (reg:CC FLAGS_REG))]
8751 "TARGET_SSE"
8752 "#")
8753
8754 ;; Splitters for fp abs and neg.
8755
8756 (define_split
8757 [(set (match_operand 0 "fp_register_operand")
8758 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8759 (use (match_operand 2))
8760 (clobber (reg:CC FLAGS_REG))]
8761 "reload_completed"
8762 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8763
8764 (define_split
8765 [(set (match_operand 0 "register_operand")
8766 (match_operator 3 "absneg_operator"
8767 [(match_operand 1 "register_operand")]))
8768 (use (match_operand 2 "nonimmediate_operand"))
8769 (clobber (reg:CC FLAGS_REG))]
8770 "reload_completed && SSE_REG_P (operands[0])"
8771 [(set (match_dup 0) (match_dup 3))]
8772 {
8773 enum machine_mode mode = GET_MODE (operands[0]);
8774 enum machine_mode vmode = GET_MODE (operands[2]);
8775 rtx tmp;
8776
8777 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8778 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8779 if (operands_match_p (operands[0], operands[2]))
8780 {
8781 tmp = operands[1];
8782 operands[1] = operands[2];
8783 operands[2] = tmp;
8784 }
8785 if (GET_CODE (operands[3]) == ABS)
8786 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8787 else
8788 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8789 operands[3] = tmp;
8790 })
8791
8792 (define_split
8793 [(set (match_operand:SF 0 "register_operand")
8794 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8795 (use (match_operand:V4SF 2))
8796 (clobber (reg:CC FLAGS_REG))]
8797 "reload_completed"
8798 [(parallel [(set (match_dup 0) (match_dup 1))
8799 (clobber (reg:CC FLAGS_REG))])]
8800 {
8801 rtx tmp;
8802 operands[0] = gen_lowpart (SImode, operands[0]);
8803 if (GET_CODE (operands[1]) == ABS)
8804 {
8805 tmp = gen_int_mode (0x7fffffff, SImode);
8806 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8807 }
8808 else
8809 {
8810 tmp = gen_int_mode (0x80000000, SImode);
8811 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8812 }
8813 operands[1] = tmp;
8814 })
8815
8816 (define_split
8817 [(set (match_operand:DF 0 "register_operand")
8818 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8819 (use (match_operand 2))
8820 (clobber (reg:CC FLAGS_REG))]
8821 "reload_completed"
8822 [(parallel [(set (match_dup 0) (match_dup 1))
8823 (clobber (reg:CC FLAGS_REG))])]
8824 {
8825 rtx tmp;
8826 if (TARGET_64BIT)
8827 {
8828 tmp = gen_lowpart (DImode, operands[0]);
8829 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8830 operands[0] = tmp;
8831
8832 if (GET_CODE (operands[1]) == ABS)
8833 tmp = const0_rtx;
8834 else
8835 tmp = gen_rtx_NOT (DImode, tmp);
8836 }
8837 else
8838 {
8839 operands[0] = gen_highpart (SImode, operands[0]);
8840 if (GET_CODE (operands[1]) == ABS)
8841 {
8842 tmp = gen_int_mode (0x7fffffff, SImode);
8843 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8844 }
8845 else
8846 {
8847 tmp = gen_int_mode (0x80000000, SImode);
8848 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8849 }
8850 }
8851 operands[1] = tmp;
8852 })
8853
8854 (define_split
8855 [(set (match_operand:XF 0 "register_operand")
8856 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8857 (use (match_operand 2))
8858 (clobber (reg:CC FLAGS_REG))]
8859 "reload_completed"
8860 [(parallel [(set (match_dup 0) (match_dup 1))
8861 (clobber (reg:CC FLAGS_REG))])]
8862 {
8863 rtx tmp;
8864 operands[0] = gen_rtx_REG (SImode,
8865 true_regnum (operands[0])
8866 + (TARGET_64BIT ? 1 : 2));
8867 if (GET_CODE (operands[1]) == ABS)
8868 {
8869 tmp = GEN_INT (0x7fff);
8870 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8871 }
8872 else
8873 {
8874 tmp = GEN_INT (0x8000);
8875 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8876 }
8877 operands[1] = tmp;
8878 })
8879
8880 ;; Conditionalize these after reload. If they match before reload, we
8881 ;; lose the clobber and ability to use integer instructions.
8882
8883 (define_insn "*<code><mode>2_1"
8884 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8885 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8886 "TARGET_80387
8887 && (reload_completed
8888 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8889 "f<absneg_mnemonic>"
8890 [(set_attr "type" "fsgn")
8891 (set_attr "mode" "<MODE>")])
8892
8893 (define_insn "*<code>extendsfdf2"
8894 [(set (match_operand:DF 0 "register_operand" "=f")
8895 (absneg:DF (float_extend:DF
8896 (match_operand:SF 1 "register_operand" "0"))))]
8897 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8898 "f<absneg_mnemonic>"
8899 [(set_attr "type" "fsgn")
8900 (set_attr "mode" "DF")])
8901
8902 (define_insn "*<code>extendsfxf2"
8903 [(set (match_operand:XF 0 "register_operand" "=f")
8904 (absneg:XF (float_extend:XF
8905 (match_operand:SF 1 "register_operand" "0"))))]
8906 "TARGET_80387"
8907 "f<absneg_mnemonic>"
8908 [(set_attr "type" "fsgn")
8909 (set_attr "mode" "XF")])
8910
8911 (define_insn "*<code>extenddfxf2"
8912 [(set (match_operand:XF 0 "register_operand" "=f")
8913 (absneg:XF (float_extend:XF
8914 (match_operand:DF 1 "register_operand" "0"))))]
8915 "TARGET_80387"
8916 "f<absneg_mnemonic>"
8917 [(set_attr "type" "fsgn")
8918 (set_attr "mode" "XF")])
8919
8920 ;; Copysign instructions
8921
8922 (define_mode_iterator CSGNMODE [SF DF TF])
8923 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8924
8925 (define_expand "copysign<mode>3"
8926 [(match_operand:CSGNMODE 0 "register_operand")
8927 (match_operand:CSGNMODE 1 "nonmemory_operand")
8928 (match_operand:CSGNMODE 2 "register_operand")]
8929 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8930 || (TARGET_SSE && (<MODE>mode == TFmode))"
8931 "ix86_expand_copysign (operands); DONE;")
8932
8933 (define_insn_and_split "copysign<mode>3_const"
8934 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8935 (unspec:CSGNMODE
8936 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8937 (match_operand:CSGNMODE 2 "register_operand" "0")
8938 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8939 UNSPEC_COPYSIGN))]
8940 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8941 || (TARGET_SSE && (<MODE>mode == TFmode))"
8942 "#"
8943 "&& reload_completed"
8944 [(const_int 0)]
8945 "ix86_split_copysign_const (operands); DONE;")
8946
8947 (define_insn "copysign<mode>3_var"
8948 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8949 (unspec:CSGNMODE
8950 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8951 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8952 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8953 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8954 UNSPEC_COPYSIGN))
8955 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8956 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8957 || (TARGET_SSE && (<MODE>mode == TFmode))"
8958 "#")
8959
8960 (define_split
8961 [(set (match_operand:CSGNMODE 0 "register_operand")
8962 (unspec:CSGNMODE
8963 [(match_operand:CSGNMODE 2 "register_operand")
8964 (match_operand:CSGNMODE 3 "register_operand")
8965 (match_operand:<CSGNVMODE> 4)
8966 (match_operand:<CSGNVMODE> 5)]
8967 UNSPEC_COPYSIGN))
8968 (clobber (match_scratch:<CSGNVMODE> 1))]
8969 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8970 || (TARGET_SSE && (<MODE>mode == TFmode)))
8971 && reload_completed"
8972 [(const_int 0)]
8973 "ix86_split_copysign_var (operands); DONE;")
8974 \f
8975 ;; One complement instructions
8976
8977 (define_expand "one_cmpl<mode>2"
8978 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8979 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8980 ""
8981 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8982
8983 (define_insn "*one_cmpl<mode>2_1"
8984 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8985 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8986 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8987 "not{<imodesuffix>}\t%0"
8988 [(set_attr "type" "negnot")
8989 (set_attr "mode" "<MODE>")])
8990
8991 ;; %%% Potential partial reg stall on alternative 1. What to do?
8992 (define_insn "*one_cmplqi2_1"
8993 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8994 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8995 "ix86_unary_operator_ok (NOT, QImode, operands)"
8996 "@
8997 not{b}\t%0
8998 not{l}\t%k0"
8999 [(set_attr "type" "negnot")
9000 (set_attr "mode" "QI,SI")])
9001
9002 ;; ??? Currently never generated - xor is used instead.
9003 (define_insn "*one_cmplsi2_1_zext"
9004 [(set (match_operand:DI 0 "register_operand" "=r")
9005 (zero_extend:DI
9006 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9007 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9008 "not{l}\t%k0"
9009 [(set_attr "type" "negnot")
9010 (set_attr "mode" "SI")])
9011
9012 (define_insn "*one_cmpl<mode>2_2"
9013 [(set (reg FLAGS_REG)
9014 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9015 (const_int 0)))
9016 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9017 (not:SWI (match_dup 1)))]
9018 "ix86_match_ccmode (insn, CCNOmode)
9019 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9020 "#"
9021 [(set_attr "type" "alu1")
9022 (set_attr "mode" "<MODE>")])
9023
9024 (define_split
9025 [(set (match_operand 0 "flags_reg_operand")
9026 (match_operator 2 "compare_operator"
9027 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9028 (const_int 0)]))
9029 (set (match_operand:SWI 1 "nonimmediate_operand")
9030 (not:SWI (match_dup 3)))]
9031 "ix86_match_ccmode (insn, CCNOmode)"
9032 [(parallel [(set (match_dup 0)
9033 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9034 (const_int 0)]))
9035 (set (match_dup 1)
9036 (xor:SWI (match_dup 3) (const_int -1)))])])
9037
9038 ;; ??? Currently never generated - xor is used instead.
9039 (define_insn "*one_cmplsi2_2_zext"
9040 [(set (reg FLAGS_REG)
9041 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9042 (const_int 0)))
9043 (set (match_operand:DI 0 "register_operand" "=r")
9044 (zero_extend:DI (not:SI (match_dup 1))))]
9045 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9046 && ix86_unary_operator_ok (NOT, SImode, operands)"
9047 "#"
9048 [(set_attr "type" "alu1")
9049 (set_attr "mode" "SI")])
9050
9051 (define_split
9052 [(set (match_operand 0 "flags_reg_operand")
9053 (match_operator 2 "compare_operator"
9054 [(not:SI (match_operand:SI 3 "register_operand"))
9055 (const_int 0)]))
9056 (set (match_operand:DI 1 "register_operand")
9057 (zero_extend:DI (not:SI (match_dup 3))))]
9058 "ix86_match_ccmode (insn, CCNOmode)"
9059 [(parallel [(set (match_dup 0)
9060 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9061 (const_int 0)]))
9062 (set (match_dup 1)
9063 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9064 \f
9065 ;; Shift instructions
9066
9067 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9068 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9069 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9070 ;; from the assembler input.
9071 ;;
9072 ;; This instruction shifts the target reg/mem as usual, but instead of
9073 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9074 ;; is a left shift double, bits are taken from the high order bits of
9075 ;; reg, else if the insn is a shift right double, bits are taken from the
9076 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9077 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9078 ;;
9079 ;; Since sh[lr]d does not change the `reg' operand, that is done
9080 ;; separately, making all shifts emit pairs of shift double and normal
9081 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9082 ;; support a 63 bit shift, each shift where the count is in a reg expands
9083 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9084 ;;
9085 ;; If the shift count is a constant, we need never emit more than one
9086 ;; shift pair, instead using moves and sign extension for counts greater
9087 ;; than 31.
9088
9089 (define_expand "ashl<mode>3"
9090 [(set (match_operand:SDWIM 0 "<shift_operand>")
9091 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9092 (match_operand:QI 2 "nonmemory_operand")))]
9093 ""
9094 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9095
9096 (define_insn "*ashl<mode>3_doubleword"
9097 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9098 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9099 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9100 (clobber (reg:CC FLAGS_REG))]
9101 ""
9102 "#"
9103 [(set_attr "type" "multi")])
9104
9105 (define_split
9106 [(set (match_operand:DWI 0 "register_operand")
9107 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9108 (match_operand:QI 2 "nonmemory_operand")))
9109 (clobber (reg:CC FLAGS_REG))]
9110 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9111 [(const_int 0)]
9112 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9113
9114 ;; By default we don't ask for a scratch register, because when DWImode
9115 ;; values are manipulated, registers are already at a premium. But if
9116 ;; we have one handy, we won't turn it away.
9117
9118 (define_peephole2
9119 [(match_scratch:DWIH 3 "r")
9120 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9121 (ashift:<DWI>
9122 (match_operand:<DWI> 1 "nonmemory_operand")
9123 (match_operand:QI 2 "nonmemory_operand")))
9124 (clobber (reg:CC FLAGS_REG))])
9125 (match_dup 3)]
9126 "TARGET_CMOVE"
9127 [(const_int 0)]
9128 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9129
9130 (define_insn "x86_64_shld"
9131 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9132 (ior:DI (ashift:DI (match_dup 0)
9133 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9134 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9135 (minus:QI (const_int 64) (match_dup 2)))))
9136 (clobber (reg:CC FLAGS_REG))]
9137 "TARGET_64BIT"
9138 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9139 [(set_attr "type" "ishift")
9140 (set_attr "prefix_0f" "1")
9141 (set_attr "mode" "DI")
9142 (set_attr "athlon_decode" "vector")
9143 (set_attr "amdfam10_decode" "vector")
9144 (set_attr "bdver1_decode" "vector")])
9145
9146 (define_insn "x86_shld"
9147 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9148 (ior:SI (ashift:SI (match_dup 0)
9149 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9150 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9151 (minus:QI (const_int 32) (match_dup 2)))))
9152 (clobber (reg:CC FLAGS_REG))]
9153 ""
9154 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9155 [(set_attr "type" "ishift")
9156 (set_attr "prefix_0f" "1")
9157 (set_attr "mode" "SI")
9158 (set_attr "pent_pair" "np")
9159 (set_attr "athlon_decode" "vector")
9160 (set_attr "amdfam10_decode" "vector")
9161 (set_attr "bdver1_decode" "vector")])
9162
9163 (define_expand "x86_shift<mode>_adj_1"
9164 [(set (reg:CCZ FLAGS_REG)
9165 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9166 (match_dup 4))
9167 (const_int 0)))
9168 (set (match_operand:SWI48 0 "register_operand")
9169 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9170 (match_operand:SWI48 1 "register_operand")
9171 (match_dup 0)))
9172 (set (match_dup 1)
9173 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9174 (match_operand:SWI48 3 "register_operand")
9175 (match_dup 1)))]
9176 "TARGET_CMOVE"
9177 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9178
9179 (define_expand "x86_shift<mode>_adj_2"
9180 [(use (match_operand:SWI48 0 "register_operand"))
9181 (use (match_operand:SWI48 1 "register_operand"))
9182 (use (match_operand:QI 2 "register_operand"))]
9183 ""
9184 {
9185 rtx label = gen_label_rtx ();
9186 rtx tmp;
9187
9188 emit_insn (gen_testqi_ccz_1 (operands[2],
9189 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9190
9191 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9192 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9193 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9194 gen_rtx_LABEL_REF (VOIDmode, label),
9195 pc_rtx);
9196 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9197 JUMP_LABEL (tmp) = label;
9198
9199 emit_move_insn (operands[0], operands[1]);
9200 ix86_expand_clear (operands[1]);
9201
9202 emit_label (label);
9203 LABEL_NUSES (label) = 1;
9204
9205 DONE;
9206 })
9207
9208 ;; Avoid useless masking of count operand.
9209 (define_insn_and_split "*ashl<mode>3_mask"
9210 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9211 (ashift:SWI48
9212 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9213 (subreg:QI
9214 (and:SI
9215 (match_operand:SI 2 "nonimmediate_operand" "c")
9216 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9217 (clobber (reg:CC FLAGS_REG))]
9218 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9219 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9220 == GET_MODE_BITSIZE (<MODE>mode)-1"
9221 "#"
9222 "&& 1"
9223 [(parallel [(set (match_dup 0)
9224 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9225 (clobber (reg:CC FLAGS_REG))])]
9226 {
9227 if (can_create_pseudo_p ())
9228 operands [2] = force_reg (SImode, operands[2]);
9229
9230 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9231 }
9232 [(set_attr "type" "ishift")
9233 (set_attr "mode" "<MODE>")])
9234
9235 (define_insn "*bmi2_ashl<mode>3_1"
9236 [(set (match_operand:SWI48 0 "register_operand" "=r")
9237 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9238 (match_operand:SWI48 2 "register_operand" "r")))]
9239 "TARGET_BMI2"
9240 "shlx\t{%2, %1, %0|%0, %1, %2}"
9241 [(set_attr "type" "ishiftx")
9242 (set_attr "mode" "<MODE>")])
9243
9244 (define_insn "*ashl<mode>3_1"
9245 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9246 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9247 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9248 (clobber (reg:CC FLAGS_REG))]
9249 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9250 {
9251 switch (get_attr_type (insn))
9252 {
9253 case TYPE_LEA:
9254 case TYPE_ISHIFTX:
9255 return "#";
9256
9257 case TYPE_ALU:
9258 gcc_assert (operands[2] == const1_rtx);
9259 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9260 return "add{<imodesuffix>}\t%0, %0";
9261
9262 default:
9263 if (operands[2] == const1_rtx
9264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265 return "sal{<imodesuffix>}\t%0";
9266 else
9267 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9268 }
9269 }
9270 [(set_attr "isa" "*,*,bmi2")
9271 (set (attr "type")
9272 (cond [(eq_attr "alternative" "1")
9273 (const_string "lea")
9274 (eq_attr "alternative" "2")
9275 (const_string "ishiftx")
9276 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9277 (match_operand 0 "register_operand"))
9278 (match_operand 2 "const1_operand"))
9279 (const_string "alu")
9280 ]
9281 (const_string "ishift")))
9282 (set (attr "length_immediate")
9283 (if_then_else
9284 (ior (eq_attr "type" "alu")
9285 (and (eq_attr "type" "ishift")
9286 (and (match_operand 2 "const1_operand")
9287 (ior (match_test "TARGET_SHIFT1")
9288 (match_test "optimize_function_for_size_p (cfun)")))))
9289 (const_string "0")
9290 (const_string "*")))
9291 (set_attr "mode" "<MODE>")])
9292
9293 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9294 (define_split
9295 [(set (match_operand:SWI48 0 "register_operand")
9296 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9297 (match_operand:QI 2 "register_operand")))
9298 (clobber (reg:CC FLAGS_REG))]
9299 "TARGET_BMI2 && reload_completed"
9300 [(set (match_dup 0)
9301 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9302 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9303
9304 (define_insn "*bmi2_ashlsi3_1_zext"
9305 [(set (match_operand:DI 0 "register_operand" "=r")
9306 (zero_extend:DI
9307 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9308 (match_operand:SI 2 "register_operand" "r"))))]
9309 "TARGET_64BIT && TARGET_BMI2"
9310 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9311 [(set_attr "type" "ishiftx")
9312 (set_attr "mode" "SI")])
9313
9314 (define_insn "*ashlsi3_1_zext"
9315 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9316 (zero_extend:DI
9317 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9318 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9319 (clobber (reg:CC FLAGS_REG))]
9320 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9321 {
9322 switch (get_attr_type (insn))
9323 {
9324 case TYPE_LEA:
9325 case TYPE_ISHIFTX:
9326 return "#";
9327
9328 case TYPE_ALU:
9329 gcc_assert (operands[2] == const1_rtx);
9330 return "add{l}\t%k0, %k0";
9331
9332 default:
9333 if (operands[2] == const1_rtx
9334 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9335 return "sal{l}\t%k0";
9336 else
9337 return "sal{l}\t{%2, %k0|%k0, %2}";
9338 }
9339 }
9340 [(set_attr "isa" "*,*,bmi2")
9341 (set (attr "type")
9342 (cond [(eq_attr "alternative" "1")
9343 (const_string "lea")
9344 (eq_attr "alternative" "2")
9345 (const_string "ishiftx")
9346 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9347 (match_operand 2 "const1_operand"))
9348 (const_string "alu")
9349 ]
9350 (const_string "ishift")))
9351 (set (attr "length_immediate")
9352 (if_then_else
9353 (ior (eq_attr "type" "alu")
9354 (and (eq_attr "type" "ishift")
9355 (and (match_operand 2 "const1_operand")
9356 (ior (match_test "TARGET_SHIFT1")
9357 (match_test "optimize_function_for_size_p (cfun)")))))
9358 (const_string "0")
9359 (const_string "*")))
9360 (set_attr "mode" "SI")])
9361
9362 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9363 (define_split
9364 [(set (match_operand:DI 0 "register_operand")
9365 (zero_extend:DI
9366 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9367 (match_operand:QI 2 "register_operand"))))
9368 (clobber (reg:CC FLAGS_REG))]
9369 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9370 [(set (match_dup 0)
9371 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9372 "operands[2] = gen_lowpart (SImode, operands[2]);")
9373
9374 (define_insn "*ashlhi3_1"
9375 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9376 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9377 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9378 (clobber (reg:CC FLAGS_REG))]
9379 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9380 {
9381 switch (get_attr_type (insn))
9382 {
9383 case TYPE_LEA:
9384 return "#";
9385
9386 case TYPE_ALU:
9387 gcc_assert (operands[2] == const1_rtx);
9388 return "add{w}\t%0, %0";
9389
9390 default:
9391 if (operands[2] == const1_rtx
9392 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9393 return "sal{w}\t%0";
9394 else
9395 return "sal{w}\t{%2, %0|%0, %2}";
9396 }
9397 }
9398 [(set (attr "type")
9399 (cond [(eq_attr "alternative" "1")
9400 (const_string "lea")
9401 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9402 (match_operand 0 "register_operand"))
9403 (match_operand 2 "const1_operand"))
9404 (const_string "alu")
9405 ]
9406 (const_string "ishift")))
9407 (set (attr "length_immediate")
9408 (if_then_else
9409 (ior (eq_attr "type" "alu")
9410 (and (eq_attr "type" "ishift")
9411 (and (match_operand 2 "const1_operand")
9412 (ior (match_test "TARGET_SHIFT1")
9413 (match_test "optimize_function_for_size_p (cfun)")))))
9414 (const_string "0")
9415 (const_string "*")))
9416 (set_attr "mode" "HI,SI")])
9417
9418 ;; %%% Potential partial reg stall on alternative 1. What to do?
9419 (define_insn "*ashlqi3_1"
9420 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9421 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9422 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9423 (clobber (reg:CC FLAGS_REG))]
9424 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9425 {
9426 switch (get_attr_type (insn))
9427 {
9428 case TYPE_LEA:
9429 return "#";
9430
9431 case TYPE_ALU:
9432 gcc_assert (operands[2] == const1_rtx);
9433 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9434 return "add{l}\t%k0, %k0";
9435 else
9436 return "add{b}\t%0, %0";
9437
9438 default:
9439 if (operands[2] == const1_rtx
9440 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9441 {
9442 if (get_attr_mode (insn) == MODE_SI)
9443 return "sal{l}\t%k0";
9444 else
9445 return "sal{b}\t%0";
9446 }
9447 else
9448 {
9449 if (get_attr_mode (insn) == MODE_SI)
9450 return "sal{l}\t{%2, %k0|%k0, %2}";
9451 else
9452 return "sal{b}\t{%2, %0|%0, %2}";
9453 }
9454 }
9455 }
9456 [(set (attr "type")
9457 (cond [(eq_attr "alternative" "2")
9458 (const_string "lea")
9459 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9460 (match_operand 0 "register_operand"))
9461 (match_operand 2 "const1_operand"))
9462 (const_string "alu")
9463 ]
9464 (const_string "ishift")))
9465 (set (attr "length_immediate")
9466 (if_then_else
9467 (ior (eq_attr "type" "alu")
9468 (and (eq_attr "type" "ishift")
9469 (and (match_operand 2 "const1_operand")
9470 (ior (match_test "TARGET_SHIFT1")
9471 (match_test "optimize_function_for_size_p (cfun)")))))
9472 (const_string "0")
9473 (const_string "*")))
9474 (set_attr "mode" "QI,SI,SI")])
9475
9476 (define_insn "*ashlqi3_1_slp"
9477 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9478 (ashift:QI (match_dup 0)
9479 (match_operand:QI 1 "nonmemory_operand" "cI")))
9480 (clobber (reg:CC FLAGS_REG))]
9481 "(optimize_function_for_size_p (cfun)
9482 || !TARGET_PARTIAL_FLAG_REG_STALL
9483 || (operands[1] == const1_rtx
9484 && (TARGET_SHIFT1
9485 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9486 {
9487 switch (get_attr_type (insn))
9488 {
9489 case TYPE_ALU:
9490 gcc_assert (operands[1] == const1_rtx);
9491 return "add{b}\t%0, %0";
9492
9493 default:
9494 if (operands[1] == const1_rtx
9495 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9496 return "sal{b}\t%0";
9497 else
9498 return "sal{b}\t{%1, %0|%0, %1}";
9499 }
9500 }
9501 [(set (attr "type")
9502 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9503 (match_operand 0 "register_operand"))
9504 (match_operand 1 "const1_operand"))
9505 (const_string "alu")
9506 ]
9507 (const_string "ishift1")))
9508 (set (attr "length_immediate")
9509 (if_then_else
9510 (ior (eq_attr "type" "alu")
9511 (and (eq_attr "type" "ishift1")
9512 (and (match_operand 1 "const1_operand")
9513 (ior (match_test "TARGET_SHIFT1")
9514 (match_test "optimize_function_for_size_p (cfun)")))))
9515 (const_string "0")
9516 (const_string "*")))
9517 (set_attr "mode" "QI")])
9518
9519 ;; Convert ashift to the lea pattern to avoid flags dependency.
9520 (define_split
9521 [(set (match_operand 0 "register_operand")
9522 (ashift (match_operand 1 "index_register_operand")
9523 (match_operand:QI 2 "const_int_operand")))
9524 (clobber (reg:CC FLAGS_REG))]
9525 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9526 && reload_completed
9527 && true_regnum (operands[0]) != true_regnum (operands[1])"
9528 [(const_int 0)]
9529 {
9530 enum machine_mode mode = GET_MODE (operands[0]);
9531 rtx pat;
9532
9533 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9534 {
9535 mode = SImode;
9536 operands[0] = gen_lowpart (mode, operands[0]);
9537 operands[1] = gen_lowpart (mode, operands[1]);
9538 }
9539
9540 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9541
9542 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9543
9544 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9545 DONE;
9546 })
9547
9548 ;; Convert ashift to the lea pattern to avoid flags dependency.
9549 (define_split
9550 [(set (match_operand:DI 0 "register_operand")
9551 (zero_extend:DI
9552 (ashift:SI (match_operand:SI 1 "index_register_operand")
9553 (match_operand:QI 2 "const_int_operand"))))
9554 (clobber (reg:CC FLAGS_REG))]
9555 "TARGET_64BIT && reload_completed
9556 && true_regnum (operands[0]) != true_regnum (operands[1])"
9557 [(set (match_dup 0)
9558 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9559 {
9560 operands[1] = gen_lowpart (DImode, operands[1]);
9561 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9562 })
9563
9564 ;; This pattern can't accept a variable shift count, since shifts by
9565 ;; zero don't affect the flags. We assume that shifts by constant
9566 ;; zero are optimized away.
9567 (define_insn "*ashl<mode>3_cmp"
9568 [(set (reg FLAGS_REG)
9569 (compare
9570 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9571 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9572 (const_int 0)))
9573 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9574 (ashift:SWI (match_dup 1) (match_dup 2)))]
9575 "(optimize_function_for_size_p (cfun)
9576 || !TARGET_PARTIAL_FLAG_REG_STALL
9577 || (operands[2] == const1_rtx
9578 && (TARGET_SHIFT1
9579 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9580 && ix86_match_ccmode (insn, CCGOCmode)
9581 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9582 {
9583 switch (get_attr_type (insn))
9584 {
9585 case TYPE_ALU:
9586 gcc_assert (operands[2] == const1_rtx);
9587 return "add{<imodesuffix>}\t%0, %0";
9588
9589 default:
9590 if (operands[2] == const1_rtx
9591 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9592 return "sal{<imodesuffix>}\t%0";
9593 else
9594 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9595 }
9596 }
9597 [(set (attr "type")
9598 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9599 (match_operand 0 "register_operand"))
9600 (match_operand 2 "const1_operand"))
9601 (const_string "alu")
9602 ]
9603 (const_string "ishift")))
9604 (set (attr "length_immediate")
9605 (if_then_else
9606 (ior (eq_attr "type" "alu")
9607 (and (eq_attr "type" "ishift")
9608 (and (match_operand 2 "const1_operand")
9609 (ior (match_test "TARGET_SHIFT1")
9610 (match_test "optimize_function_for_size_p (cfun)")))))
9611 (const_string "0")
9612 (const_string "*")))
9613 (set_attr "mode" "<MODE>")])
9614
9615 (define_insn "*ashlsi3_cmp_zext"
9616 [(set (reg FLAGS_REG)
9617 (compare
9618 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9619 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9620 (const_int 0)))
9621 (set (match_operand:DI 0 "register_operand" "=r")
9622 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9623 "TARGET_64BIT
9624 && (optimize_function_for_size_p (cfun)
9625 || !TARGET_PARTIAL_FLAG_REG_STALL
9626 || (operands[2] == const1_rtx
9627 && (TARGET_SHIFT1
9628 || TARGET_DOUBLE_WITH_ADD)))
9629 && ix86_match_ccmode (insn, CCGOCmode)
9630 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9631 {
9632 switch (get_attr_type (insn))
9633 {
9634 case TYPE_ALU:
9635 gcc_assert (operands[2] == const1_rtx);
9636 return "add{l}\t%k0, %k0";
9637
9638 default:
9639 if (operands[2] == const1_rtx
9640 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9641 return "sal{l}\t%k0";
9642 else
9643 return "sal{l}\t{%2, %k0|%k0, %2}";
9644 }
9645 }
9646 [(set (attr "type")
9647 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9648 (match_operand 2 "const1_operand"))
9649 (const_string "alu")
9650 ]
9651 (const_string "ishift")))
9652 (set (attr "length_immediate")
9653 (if_then_else
9654 (ior (eq_attr "type" "alu")
9655 (and (eq_attr "type" "ishift")
9656 (and (match_operand 2 "const1_operand")
9657 (ior (match_test "TARGET_SHIFT1")
9658 (match_test "optimize_function_for_size_p (cfun)")))))
9659 (const_string "0")
9660 (const_string "*")))
9661 (set_attr "mode" "SI")])
9662
9663 (define_insn "*ashl<mode>3_cconly"
9664 [(set (reg FLAGS_REG)
9665 (compare
9666 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9667 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9668 (const_int 0)))
9669 (clobber (match_scratch:SWI 0 "=<r>"))]
9670 "(optimize_function_for_size_p (cfun)
9671 || !TARGET_PARTIAL_FLAG_REG_STALL
9672 || (operands[2] == const1_rtx
9673 && (TARGET_SHIFT1
9674 || TARGET_DOUBLE_WITH_ADD)))
9675 && ix86_match_ccmode (insn, CCGOCmode)"
9676 {
9677 switch (get_attr_type (insn))
9678 {
9679 case TYPE_ALU:
9680 gcc_assert (operands[2] == const1_rtx);
9681 return "add{<imodesuffix>}\t%0, %0";
9682
9683 default:
9684 if (operands[2] == const1_rtx
9685 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9686 return "sal{<imodesuffix>}\t%0";
9687 else
9688 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9689 }
9690 }
9691 [(set (attr "type")
9692 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9693 (match_operand 0 "register_operand"))
9694 (match_operand 2 "const1_operand"))
9695 (const_string "alu")
9696 ]
9697 (const_string "ishift")))
9698 (set (attr "length_immediate")
9699 (if_then_else
9700 (ior (eq_attr "type" "alu")
9701 (and (eq_attr "type" "ishift")
9702 (and (match_operand 2 "const1_operand")
9703 (ior (match_test "TARGET_SHIFT1")
9704 (match_test "optimize_function_for_size_p (cfun)")))))
9705 (const_string "0")
9706 (const_string "*")))
9707 (set_attr "mode" "<MODE>")])
9708
9709 ;; See comment above `ashl<mode>3' about how this works.
9710
9711 (define_expand "<shift_insn><mode>3"
9712 [(set (match_operand:SDWIM 0 "<shift_operand>")
9713 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9714 (match_operand:QI 2 "nonmemory_operand")))]
9715 ""
9716 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9717
9718 ;; Avoid useless masking of count operand.
9719 (define_insn_and_split "*<shift_insn><mode>3_mask"
9720 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9721 (any_shiftrt:SWI48
9722 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9723 (subreg:QI
9724 (and:SI
9725 (match_operand:SI 2 "nonimmediate_operand" "c")
9726 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9727 (clobber (reg:CC FLAGS_REG))]
9728 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9729 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9730 == GET_MODE_BITSIZE (<MODE>mode)-1"
9731 "#"
9732 "&& 1"
9733 [(parallel [(set (match_dup 0)
9734 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9735 (clobber (reg:CC FLAGS_REG))])]
9736 {
9737 if (can_create_pseudo_p ())
9738 operands [2] = force_reg (SImode, operands[2]);
9739
9740 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9741 }
9742 [(set_attr "type" "ishift")
9743 (set_attr "mode" "<MODE>")])
9744
9745 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9746 [(set (match_operand:DWI 0 "register_operand" "=r")
9747 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9748 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9749 (clobber (reg:CC FLAGS_REG))]
9750 ""
9751 "#"
9752 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9753 [(const_int 0)]
9754 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9755 [(set_attr "type" "multi")])
9756
9757 ;; By default we don't ask for a scratch register, because when DWImode
9758 ;; values are manipulated, registers are already at a premium. But if
9759 ;; we have one handy, we won't turn it away.
9760
9761 (define_peephole2
9762 [(match_scratch:DWIH 3 "r")
9763 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9764 (any_shiftrt:<DWI>
9765 (match_operand:<DWI> 1 "register_operand")
9766 (match_operand:QI 2 "nonmemory_operand")))
9767 (clobber (reg:CC FLAGS_REG))])
9768 (match_dup 3)]
9769 "TARGET_CMOVE"
9770 [(const_int 0)]
9771 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9772
9773 (define_insn "x86_64_shrd"
9774 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9775 (ior:DI (ashiftrt:DI (match_dup 0)
9776 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9777 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9778 (minus:QI (const_int 64) (match_dup 2)))))
9779 (clobber (reg:CC FLAGS_REG))]
9780 "TARGET_64BIT"
9781 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9782 [(set_attr "type" "ishift")
9783 (set_attr "prefix_0f" "1")
9784 (set_attr "mode" "DI")
9785 (set_attr "athlon_decode" "vector")
9786 (set_attr "amdfam10_decode" "vector")
9787 (set_attr "bdver1_decode" "vector")])
9788
9789 (define_insn "x86_shrd"
9790 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9791 (ior:SI (ashiftrt:SI (match_dup 0)
9792 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9793 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9794 (minus:QI (const_int 32) (match_dup 2)))))
9795 (clobber (reg:CC FLAGS_REG))]
9796 ""
9797 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9798 [(set_attr "type" "ishift")
9799 (set_attr "prefix_0f" "1")
9800 (set_attr "mode" "SI")
9801 (set_attr "pent_pair" "np")
9802 (set_attr "athlon_decode" "vector")
9803 (set_attr "amdfam10_decode" "vector")
9804 (set_attr "bdver1_decode" "vector")])
9805
9806 (define_insn "ashrdi3_cvt"
9807 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9808 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9809 (match_operand:QI 2 "const_int_operand")))
9810 (clobber (reg:CC FLAGS_REG))]
9811 "TARGET_64BIT && INTVAL (operands[2]) == 63
9812 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9813 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9814 "@
9815 {cqto|cqo}
9816 sar{q}\t{%2, %0|%0, %2}"
9817 [(set_attr "type" "imovx,ishift")
9818 (set_attr "prefix_0f" "0,*")
9819 (set_attr "length_immediate" "0,*")
9820 (set_attr "modrm" "0,1")
9821 (set_attr "mode" "DI")])
9822
9823 (define_insn "ashrsi3_cvt"
9824 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9825 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9826 (match_operand:QI 2 "const_int_operand")))
9827 (clobber (reg:CC FLAGS_REG))]
9828 "INTVAL (operands[2]) == 31
9829 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9830 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9831 "@
9832 {cltd|cdq}
9833 sar{l}\t{%2, %0|%0, %2}"
9834 [(set_attr "type" "imovx,ishift")
9835 (set_attr "prefix_0f" "0,*")
9836 (set_attr "length_immediate" "0,*")
9837 (set_attr "modrm" "0,1")
9838 (set_attr "mode" "SI")])
9839
9840 (define_insn "*ashrsi3_cvt_zext"
9841 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9842 (zero_extend:DI
9843 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9844 (match_operand:QI 2 "const_int_operand"))))
9845 (clobber (reg:CC FLAGS_REG))]
9846 "TARGET_64BIT && INTVAL (operands[2]) == 31
9847 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9848 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9849 "@
9850 {cltd|cdq}
9851 sar{l}\t{%2, %k0|%k0, %2}"
9852 [(set_attr "type" "imovx,ishift")
9853 (set_attr "prefix_0f" "0,*")
9854 (set_attr "length_immediate" "0,*")
9855 (set_attr "modrm" "0,1")
9856 (set_attr "mode" "SI")])
9857
9858 (define_expand "x86_shift<mode>_adj_3"
9859 [(use (match_operand:SWI48 0 "register_operand"))
9860 (use (match_operand:SWI48 1 "register_operand"))
9861 (use (match_operand:QI 2 "register_operand"))]
9862 ""
9863 {
9864 rtx label = gen_label_rtx ();
9865 rtx tmp;
9866
9867 emit_insn (gen_testqi_ccz_1 (operands[2],
9868 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9869
9870 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9871 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9872 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9873 gen_rtx_LABEL_REF (VOIDmode, label),
9874 pc_rtx);
9875 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9876 JUMP_LABEL (tmp) = label;
9877
9878 emit_move_insn (operands[0], operands[1]);
9879 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9880 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9881 emit_label (label);
9882 LABEL_NUSES (label) = 1;
9883
9884 DONE;
9885 })
9886
9887 (define_insn "*bmi2_<shift_insn><mode>3_1"
9888 [(set (match_operand:SWI48 0 "register_operand" "=r")
9889 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9890 (match_operand:SWI48 2 "register_operand" "r")))]
9891 "TARGET_BMI2"
9892 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9893 [(set_attr "type" "ishiftx")
9894 (set_attr "mode" "<MODE>")])
9895
9896 (define_insn "*<shift_insn><mode>3_1"
9897 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9898 (any_shiftrt:SWI48
9899 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9900 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9901 (clobber (reg:CC FLAGS_REG))]
9902 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9903 {
9904 switch (get_attr_type (insn))
9905 {
9906 case TYPE_ISHIFTX:
9907 return "#";
9908
9909 default:
9910 if (operands[2] == const1_rtx
9911 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9912 return "<shift>{<imodesuffix>}\t%0";
9913 else
9914 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9915 }
9916 }
9917 [(set_attr "isa" "*,bmi2")
9918 (set_attr "type" "ishift,ishiftx")
9919 (set (attr "length_immediate")
9920 (if_then_else
9921 (and (match_operand 2 "const1_operand")
9922 (ior (match_test "TARGET_SHIFT1")
9923 (match_test "optimize_function_for_size_p (cfun)")))
9924 (const_string "0")
9925 (const_string "*")))
9926 (set_attr "mode" "<MODE>")])
9927
9928 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9929 (define_split
9930 [(set (match_operand:SWI48 0 "register_operand")
9931 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9932 (match_operand:QI 2 "register_operand")))
9933 (clobber (reg:CC FLAGS_REG))]
9934 "TARGET_BMI2 && reload_completed"
9935 [(set (match_dup 0)
9936 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9937 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9938
9939 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9940 [(set (match_operand:DI 0 "register_operand" "=r")
9941 (zero_extend:DI
9942 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9943 (match_operand:SI 2 "register_operand" "r"))))]
9944 "TARGET_64BIT && TARGET_BMI2"
9945 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9946 [(set_attr "type" "ishiftx")
9947 (set_attr "mode" "SI")])
9948
9949 (define_insn "*<shift_insn>si3_1_zext"
9950 [(set (match_operand:DI 0 "register_operand" "=r,r")
9951 (zero_extend:DI
9952 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9953 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9954 (clobber (reg:CC FLAGS_REG))]
9955 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9956 {
9957 switch (get_attr_type (insn))
9958 {
9959 case TYPE_ISHIFTX:
9960 return "#";
9961
9962 default:
9963 if (operands[2] == const1_rtx
9964 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9965 return "<shift>{l}\t%k0";
9966 else
9967 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9968 }
9969 }
9970 [(set_attr "isa" "*,bmi2")
9971 (set_attr "type" "ishift,ishiftx")
9972 (set (attr "length_immediate")
9973 (if_then_else
9974 (and (match_operand 2 "const1_operand")
9975 (ior (match_test "TARGET_SHIFT1")
9976 (match_test "optimize_function_for_size_p (cfun)")))
9977 (const_string "0")
9978 (const_string "*")))
9979 (set_attr "mode" "SI")])
9980
9981 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9982 (define_split
9983 [(set (match_operand:DI 0 "register_operand")
9984 (zero_extend:DI
9985 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9986 (match_operand:QI 2 "register_operand"))))
9987 (clobber (reg:CC FLAGS_REG))]
9988 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9989 [(set (match_dup 0)
9990 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9991 "operands[2] = gen_lowpart (SImode, operands[2]);")
9992
9993 (define_insn "*<shift_insn><mode>3_1"
9994 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9995 (any_shiftrt:SWI12
9996 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9997 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9998 (clobber (reg:CC FLAGS_REG))]
9999 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10000 {
10001 if (operands[2] == const1_rtx
10002 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10003 return "<shift>{<imodesuffix>}\t%0";
10004 else
10005 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10006 }
10007 [(set_attr "type" "ishift")
10008 (set (attr "length_immediate")
10009 (if_then_else
10010 (and (match_operand 2 "const1_operand")
10011 (ior (match_test "TARGET_SHIFT1")
10012 (match_test "optimize_function_for_size_p (cfun)")))
10013 (const_string "0")
10014 (const_string "*")))
10015 (set_attr "mode" "<MODE>")])
10016
10017 (define_insn "*<shift_insn>qi3_1_slp"
10018 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10019 (any_shiftrt:QI (match_dup 0)
10020 (match_operand:QI 1 "nonmemory_operand" "cI")))
10021 (clobber (reg:CC FLAGS_REG))]
10022 "(optimize_function_for_size_p (cfun)
10023 || !TARGET_PARTIAL_REG_STALL
10024 || (operands[1] == const1_rtx
10025 && TARGET_SHIFT1))"
10026 {
10027 if (operands[1] == const1_rtx
10028 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10029 return "<shift>{b}\t%0";
10030 else
10031 return "<shift>{b}\t{%1, %0|%0, %1}";
10032 }
10033 [(set_attr "type" "ishift1")
10034 (set (attr "length_immediate")
10035 (if_then_else
10036 (and (match_operand 1 "const1_operand")
10037 (ior (match_test "TARGET_SHIFT1")
10038 (match_test "optimize_function_for_size_p (cfun)")))
10039 (const_string "0")
10040 (const_string "*")))
10041 (set_attr "mode" "QI")])
10042
10043 ;; This pattern can't accept a variable shift count, since shifts by
10044 ;; zero don't affect the flags. We assume that shifts by constant
10045 ;; zero are optimized away.
10046 (define_insn "*<shift_insn><mode>3_cmp"
10047 [(set (reg FLAGS_REG)
10048 (compare
10049 (any_shiftrt:SWI
10050 (match_operand:SWI 1 "nonimmediate_operand" "0")
10051 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10052 (const_int 0)))
10053 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10054 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10055 "(optimize_function_for_size_p (cfun)
10056 || !TARGET_PARTIAL_FLAG_REG_STALL
10057 || (operands[2] == const1_rtx
10058 && TARGET_SHIFT1))
10059 && ix86_match_ccmode (insn, CCGOCmode)
10060 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10061 {
10062 if (operands[2] == const1_rtx
10063 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10064 return "<shift>{<imodesuffix>}\t%0";
10065 else
10066 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10067 }
10068 [(set_attr "type" "ishift")
10069 (set (attr "length_immediate")
10070 (if_then_else
10071 (and (match_operand 2 "const1_operand")
10072 (ior (match_test "TARGET_SHIFT1")
10073 (match_test "optimize_function_for_size_p (cfun)")))
10074 (const_string "0")
10075 (const_string "*")))
10076 (set_attr "mode" "<MODE>")])
10077
10078 (define_insn "*<shift_insn>si3_cmp_zext"
10079 [(set (reg FLAGS_REG)
10080 (compare
10081 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10082 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10083 (const_int 0)))
10084 (set (match_operand:DI 0 "register_operand" "=r")
10085 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10086 "TARGET_64BIT
10087 && (optimize_function_for_size_p (cfun)
10088 || !TARGET_PARTIAL_FLAG_REG_STALL
10089 || (operands[2] == const1_rtx
10090 && TARGET_SHIFT1))
10091 && ix86_match_ccmode (insn, CCGOCmode)
10092 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10093 {
10094 if (operands[2] == const1_rtx
10095 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10096 return "<shift>{l}\t%k0";
10097 else
10098 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10099 }
10100 [(set_attr "type" "ishift")
10101 (set (attr "length_immediate")
10102 (if_then_else
10103 (and (match_operand 2 "const1_operand")
10104 (ior (match_test "TARGET_SHIFT1")
10105 (match_test "optimize_function_for_size_p (cfun)")))
10106 (const_string "0")
10107 (const_string "*")))
10108 (set_attr "mode" "SI")])
10109
10110 (define_insn "*<shift_insn><mode>3_cconly"
10111 [(set (reg FLAGS_REG)
10112 (compare
10113 (any_shiftrt:SWI
10114 (match_operand:SWI 1 "register_operand" "0")
10115 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10116 (const_int 0)))
10117 (clobber (match_scratch:SWI 0 "=<r>"))]
10118 "(optimize_function_for_size_p (cfun)
10119 || !TARGET_PARTIAL_FLAG_REG_STALL
10120 || (operands[2] == const1_rtx
10121 && TARGET_SHIFT1))
10122 && ix86_match_ccmode (insn, CCGOCmode)"
10123 {
10124 if (operands[2] == const1_rtx
10125 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10126 return "<shift>{<imodesuffix>}\t%0";
10127 else
10128 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10129 }
10130 [(set_attr "type" "ishift")
10131 (set (attr "length_immediate")
10132 (if_then_else
10133 (and (match_operand 2 "const1_operand")
10134 (ior (match_test "TARGET_SHIFT1")
10135 (match_test "optimize_function_for_size_p (cfun)")))
10136 (const_string "0")
10137 (const_string "*")))
10138 (set_attr "mode" "<MODE>")])
10139 \f
10140 ;; Rotate instructions
10141
10142 (define_expand "<rotate_insn>ti3"
10143 [(set (match_operand:TI 0 "register_operand")
10144 (any_rotate:TI (match_operand:TI 1 "register_operand")
10145 (match_operand:QI 2 "nonmemory_operand")))]
10146 "TARGET_64BIT"
10147 {
10148 if (const_1_to_63_operand (operands[2], VOIDmode))
10149 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10150 (operands[0], operands[1], operands[2]));
10151 else
10152 FAIL;
10153
10154 DONE;
10155 })
10156
10157 (define_expand "<rotate_insn>di3"
10158 [(set (match_operand:DI 0 "shiftdi_operand")
10159 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10160 (match_operand:QI 2 "nonmemory_operand")))]
10161 ""
10162 {
10163 if (TARGET_64BIT)
10164 ix86_expand_binary_operator (<CODE>, DImode, operands);
10165 else if (const_1_to_31_operand (operands[2], VOIDmode))
10166 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10167 (operands[0], operands[1], operands[2]));
10168 else
10169 FAIL;
10170
10171 DONE;
10172 })
10173
10174 (define_expand "<rotate_insn><mode>3"
10175 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10176 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10177 (match_operand:QI 2 "nonmemory_operand")))]
10178 ""
10179 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10180
10181 ;; Avoid useless masking of count operand.
10182 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10183 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10184 (any_rotate:SWI48
10185 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10186 (subreg:QI
10187 (and:SI
10188 (match_operand:SI 2 "nonimmediate_operand" "c")
10189 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10190 (clobber (reg:CC FLAGS_REG))]
10191 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10192 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10193 == GET_MODE_BITSIZE (<MODE>mode)-1"
10194 "#"
10195 "&& 1"
10196 [(parallel [(set (match_dup 0)
10197 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10198 (clobber (reg:CC FLAGS_REG))])]
10199 {
10200 if (can_create_pseudo_p ())
10201 operands [2] = force_reg (SImode, operands[2]);
10202
10203 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10204 }
10205 [(set_attr "type" "rotate")
10206 (set_attr "mode" "<MODE>")])
10207
10208 ;; Implement rotation using two double-precision
10209 ;; shift instructions and a scratch register.
10210
10211 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10212 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10213 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10214 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10215 (clobber (reg:CC FLAGS_REG))
10216 (clobber (match_scratch:DWIH 3 "=&r"))]
10217 ""
10218 "#"
10219 "reload_completed"
10220 [(set (match_dup 3) (match_dup 4))
10221 (parallel
10222 [(set (match_dup 4)
10223 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10224 (lshiftrt:DWIH (match_dup 5)
10225 (minus:QI (match_dup 6) (match_dup 2)))))
10226 (clobber (reg:CC FLAGS_REG))])
10227 (parallel
10228 [(set (match_dup 5)
10229 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10230 (lshiftrt:DWIH (match_dup 3)
10231 (minus:QI (match_dup 6) (match_dup 2)))))
10232 (clobber (reg:CC FLAGS_REG))])]
10233 {
10234 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10235
10236 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10237 })
10238
10239 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10240 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10241 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10242 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10243 (clobber (reg:CC FLAGS_REG))
10244 (clobber (match_scratch:DWIH 3 "=&r"))]
10245 ""
10246 "#"
10247 "reload_completed"
10248 [(set (match_dup 3) (match_dup 4))
10249 (parallel
10250 [(set (match_dup 4)
10251 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10252 (ashift:DWIH (match_dup 5)
10253 (minus:QI (match_dup 6) (match_dup 2)))))
10254 (clobber (reg:CC FLAGS_REG))])
10255 (parallel
10256 [(set (match_dup 5)
10257 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10258 (ashift:DWIH (match_dup 3)
10259 (minus:QI (match_dup 6) (match_dup 2)))))
10260 (clobber (reg:CC FLAGS_REG))])]
10261 {
10262 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10263
10264 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10265 })
10266
10267 (define_insn "*bmi2_rorx<mode>3_1"
10268 [(set (match_operand:SWI48 0 "register_operand" "=r")
10269 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10270 (match_operand:QI 2 "immediate_operand" "<S>")))]
10271 "TARGET_BMI2"
10272 "rorx\t{%2, %1, %0|%0, %1, %2}"
10273 [(set_attr "type" "rotatex")
10274 (set_attr "mode" "<MODE>")])
10275
10276 (define_insn "*<rotate_insn><mode>3_1"
10277 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10278 (any_rotate:SWI48
10279 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10280 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10281 (clobber (reg:CC FLAGS_REG))]
10282 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10283 {
10284 switch (get_attr_type (insn))
10285 {
10286 case TYPE_ROTATEX:
10287 return "#";
10288
10289 default:
10290 if (operands[2] == const1_rtx
10291 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10292 return "<rotate>{<imodesuffix>}\t%0";
10293 else
10294 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10295 }
10296 }
10297 [(set_attr "isa" "*,bmi2")
10298 (set_attr "type" "rotate,rotatex")
10299 (set (attr "length_immediate")
10300 (if_then_else
10301 (and (eq_attr "type" "rotate")
10302 (and (match_operand 2 "const1_operand")
10303 (ior (match_test "TARGET_SHIFT1")
10304 (match_test "optimize_function_for_size_p (cfun)"))))
10305 (const_string "0")
10306 (const_string "*")))
10307 (set_attr "mode" "<MODE>")])
10308
10309 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10310 (define_split
10311 [(set (match_operand:SWI48 0 "register_operand")
10312 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10313 (match_operand:QI 2 "immediate_operand")))
10314 (clobber (reg:CC FLAGS_REG))]
10315 "TARGET_BMI2 && reload_completed"
10316 [(set (match_dup 0)
10317 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10318 {
10319 operands[2]
10320 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10321 })
10322
10323 (define_split
10324 [(set (match_operand:SWI48 0 "register_operand")
10325 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10326 (match_operand:QI 2 "immediate_operand")))
10327 (clobber (reg:CC FLAGS_REG))]
10328 "TARGET_BMI2 && reload_completed"
10329 [(set (match_dup 0)
10330 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10331
10332 (define_insn "*bmi2_rorxsi3_1_zext"
10333 [(set (match_operand:DI 0 "register_operand" "=r")
10334 (zero_extend:DI
10335 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10336 (match_operand:QI 2 "immediate_operand" "I"))))]
10337 "TARGET_64BIT && TARGET_BMI2"
10338 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10339 [(set_attr "type" "rotatex")
10340 (set_attr "mode" "SI")])
10341
10342 (define_insn "*<rotate_insn>si3_1_zext"
10343 [(set (match_operand:DI 0 "register_operand" "=r,r")
10344 (zero_extend:DI
10345 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10346 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10347 (clobber (reg:CC FLAGS_REG))]
10348 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10349 {
10350 switch (get_attr_type (insn))
10351 {
10352 case TYPE_ROTATEX:
10353 return "#";
10354
10355 default:
10356 if (operands[2] == const1_rtx
10357 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10358 return "<rotate>{l}\t%k0";
10359 else
10360 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10361 }
10362 }
10363 [(set_attr "isa" "*,bmi2")
10364 (set_attr "type" "rotate,rotatex")
10365 (set (attr "length_immediate")
10366 (if_then_else
10367 (and (eq_attr "type" "rotate")
10368 (and (match_operand 2 "const1_operand")
10369 (ior (match_test "TARGET_SHIFT1")
10370 (match_test "optimize_function_for_size_p (cfun)"))))
10371 (const_string "0")
10372 (const_string "*")))
10373 (set_attr "mode" "SI")])
10374
10375 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10376 (define_split
10377 [(set (match_operand:DI 0 "register_operand")
10378 (zero_extend:DI
10379 (rotate: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 operands[2]
10387 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10388 })
10389
10390 (define_split
10391 [(set (match_operand:DI 0 "register_operand")
10392 (zero_extend:DI
10393 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10394 (match_operand:QI 2 "immediate_operand"))))
10395 (clobber (reg:CC FLAGS_REG))]
10396 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10397 [(set (match_dup 0)
10398 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10399
10400 (define_insn "*<rotate_insn><mode>3_1"
10401 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10402 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10403 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10404 (clobber (reg:CC FLAGS_REG))]
10405 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10406 {
10407 if (operands[2] == const1_rtx
10408 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10409 return "<rotate>{<imodesuffix>}\t%0";
10410 else
10411 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10412 }
10413 [(set_attr "type" "rotate")
10414 (set (attr "length_immediate")
10415 (if_then_else
10416 (and (match_operand 2 "const1_operand")
10417 (ior (match_test "TARGET_SHIFT1")
10418 (match_test "optimize_function_for_size_p (cfun)")))
10419 (const_string "0")
10420 (const_string "*")))
10421 (set_attr "mode" "<MODE>")])
10422
10423 (define_insn "*<rotate_insn>qi3_1_slp"
10424 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10425 (any_rotate:QI (match_dup 0)
10426 (match_operand:QI 1 "nonmemory_operand" "cI")))
10427 (clobber (reg:CC FLAGS_REG))]
10428 "(optimize_function_for_size_p (cfun)
10429 || !TARGET_PARTIAL_REG_STALL
10430 || (operands[1] == const1_rtx
10431 && TARGET_SHIFT1))"
10432 {
10433 if (operands[1] == const1_rtx
10434 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10435 return "<rotate>{b}\t%0";
10436 else
10437 return "<rotate>{b}\t{%1, %0|%0, %1}";
10438 }
10439 [(set_attr "type" "rotate1")
10440 (set (attr "length_immediate")
10441 (if_then_else
10442 (and (match_operand 1 "const1_operand")
10443 (ior (match_test "TARGET_SHIFT1")
10444 (match_test "optimize_function_for_size_p (cfun)")))
10445 (const_string "0")
10446 (const_string "*")))
10447 (set_attr "mode" "QI")])
10448
10449 (define_split
10450 [(set (match_operand:HI 0 "register_operand")
10451 (any_rotate:HI (match_dup 0) (const_int 8)))
10452 (clobber (reg:CC FLAGS_REG))]
10453 "reload_completed
10454 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10455 [(parallel [(set (strict_low_part (match_dup 0))
10456 (bswap:HI (match_dup 0)))
10457 (clobber (reg:CC FLAGS_REG))])])
10458 \f
10459 ;; Bit set / bit test instructions
10460
10461 (define_expand "extv"
10462 [(set (match_operand:SI 0 "register_operand")
10463 (sign_extract:SI (match_operand:SI 1 "register_operand")
10464 (match_operand:SI 2 "const8_operand")
10465 (match_operand:SI 3 "const8_operand")))]
10466 ""
10467 {
10468 /* Handle extractions from %ah et al. */
10469 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10470 FAIL;
10471
10472 /* From mips.md: extract_bit_field doesn't verify that our source
10473 matches the predicate, so check it again here. */
10474 if (! ext_register_operand (operands[1], VOIDmode))
10475 FAIL;
10476 })
10477
10478 (define_expand "extzv"
10479 [(set (match_operand:SI 0 "register_operand")
10480 (zero_extract:SI (match_operand 1 "ext_register_operand")
10481 (match_operand:SI 2 "const8_operand")
10482 (match_operand:SI 3 "const8_operand")))]
10483 ""
10484 {
10485 /* Handle extractions from %ah et al. */
10486 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10487 FAIL;
10488
10489 /* From mips.md: extract_bit_field doesn't verify that our source
10490 matches the predicate, so check it again here. */
10491 if (! ext_register_operand (operands[1], VOIDmode))
10492 FAIL;
10493 })
10494
10495 (define_expand "insv"
10496 [(set (zero_extract (match_operand 0 "register_operand")
10497 (match_operand 1 "const_int_operand")
10498 (match_operand 2 "const_int_operand"))
10499 (match_operand 3 "register_operand"))]
10500 ""
10501 {
10502 rtx (*gen_mov_insv_1) (rtx, rtx);
10503
10504 if (ix86_expand_pinsr (operands))
10505 DONE;
10506
10507 /* Handle insertions to %ah et al. */
10508 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10509 FAIL;
10510
10511 /* From mips.md: insert_bit_field doesn't verify that our source
10512 matches the predicate, so check it again here. */
10513 if (! ext_register_operand (operands[0], VOIDmode))
10514 FAIL;
10515
10516 gen_mov_insv_1 = (TARGET_64BIT
10517 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10518
10519 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10520 DONE;
10521 })
10522
10523 ;; %%% bts, btr, btc, bt.
10524 ;; In general these instructions are *slow* when applied to memory,
10525 ;; since they enforce atomic operation. When applied to registers,
10526 ;; it depends on the cpu implementation. They're never faster than
10527 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10528 ;; no point. But in 64-bit, we can't hold the relevant immediates
10529 ;; within the instruction itself, so operating on bits in the high
10530 ;; 32-bits of a register becomes easier.
10531 ;;
10532 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10533 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10534 ;; negdf respectively, so they can never be disabled entirely.
10535
10536 (define_insn "*btsq"
10537 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10538 (const_int 1)
10539 (match_operand:DI 1 "const_0_to_63_operand"))
10540 (const_int 1))
10541 (clobber (reg:CC FLAGS_REG))]
10542 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10543 "bts{q}\t{%1, %0|%0, %1}"
10544 [(set_attr "type" "alu1")
10545 (set_attr "prefix_0f" "1")
10546 (set_attr "mode" "DI")])
10547
10548 (define_insn "*btrq"
10549 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10550 (const_int 1)
10551 (match_operand:DI 1 "const_0_to_63_operand"))
10552 (const_int 0))
10553 (clobber (reg:CC FLAGS_REG))]
10554 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10555 "btr{q}\t{%1, %0|%0, %1}"
10556 [(set_attr "type" "alu1")
10557 (set_attr "prefix_0f" "1")
10558 (set_attr "mode" "DI")])
10559
10560 (define_insn "*btcq"
10561 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10562 (const_int 1)
10563 (match_operand:DI 1 "const_0_to_63_operand"))
10564 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10565 (clobber (reg:CC FLAGS_REG))]
10566 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10567 "btc{q}\t{%1, %0|%0, %1}"
10568 [(set_attr "type" "alu1")
10569 (set_attr "prefix_0f" "1")
10570 (set_attr "mode" "DI")])
10571
10572 ;; Allow Nocona to avoid these instructions if a register is available.
10573
10574 (define_peephole2
10575 [(match_scratch:DI 2 "r")
10576 (parallel [(set (zero_extract:DI
10577 (match_operand:DI 0 "register_operand")
10578 (const_int 1)
10579 (match_operand:DI 1 "const_0_to_63_operand"))
10580 (const_int 1))
10581 (clobber (reg:CC FLAGS_REG))])]
10582 "TARGET_64BIT && !TARGET_USE_BT"
10583 [(const_int 0)]
10584 {
10585 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10586 rtx op1;
10587
10588 if (HOST_BITS_PER_WIDE_INT >= 64)
10589 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10590 else if (i < HOST_BITS_PER_WIDE_INT)
10591 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10592 else
10593 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10594
10595 op1 = immed_double_const (lo, hi, DImode);
10596 if (i >= 31)
10597 {
10598 emit_move_insn (operands[2], op1);
10599 op1 = operands[2];
10600 }
10601
10602 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10603 DONE;
10604 })
10605
10606 (define_peephole2
10607 [(match_scratch:DI 2 "r")
10608 (parallel [(set (zero_extract:DI
10609 (match_operand:DI 0 "register_operand")
10610 (const_int 1)
10611 (match_operand:DI 1 "const_0_to_63_operand"))
10612 (const_int 0))
10613 (clobber (reg:CC FLAGS_REG))])]
10614 "TARGET_64BIT && !TARGET_USE_BT"
10615 [(const_int 0)]
10616 {
10617 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10618 rtx op1;
10619
10620 if (HOST_BITS_PER_WIDE_INT >= 64)
10621 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10622 else if (i < HOST_BITS_PER_WIDE_INT)
10623 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10624 else
10625 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10626
10627 op1 = immed_double_const (~lo, ~hi, DImode);
10628 if (i >= 32)
10629 {
10630 emit_move_insn (operands[2], op1);
10631 op1 = operands[2];
10632 }
10633
10634 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10635 DONE;
10636 })
10637
10638 (define_peephole2
10639 [(match_scratch:DI 2 "r")
10640 (parallel [(set (zero_extract:DI
10641 (match_operand:DI 0 "register_operand")
10642 (const_int 1)
10643 (match_operand:DI 1 "const_0_to_63_operand"))
10644 (not:DI (zero_extract:DI
10645 (match_dup 0) (const_int 1) (match_dup 1))))
10646 (clobber (reg:CC FLAGS_REG))])]
10647 "TARGET_64BIT && !TARGET_USE_BT"
10648 [(const_int 0)]
10649 {
10650 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10651 rtx op1;
10652
10653 if (HOST_BITS_PER_WIDE_INT >= 64)
10654 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10655 else if (i < HOST_BITS_PER_WIDE_INT)
10656 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10657 else
10658 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10659
10660 op1 = immed_double_const (lo, hi, DImode);
10661 if (i >= 31)
10662 {
10663 emit_move_insn (operands[2], op1);
10664 op1 = operands[2];
10665 }
10666
10667 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10668 DONE;
10669 })
10670
10671 (define_insn "*bt<mode>"
10672 [(set (reg:CCC FLAGS_REG)
10673 (compare:CCC
10674 (zero_extract:SWI48
10675 (match_operand:SWI48 0 "register_operand" "r")
10676 (const_int 1)
10677 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10678 (const_int 0)))]
10679 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10680 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10681 [(set_attr "type" "alu1")
10682 (set_attr "prefix_0f" "1")
10683 (set_attr "mode" "<MODE>")])
10684 \f
10685 ;; Store-flag instructions.
10686
10687 ;; For all sCOND expanders, also expand the compare or test insn that
10688 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10689
10690 (define_insn_and_split "*setcc_di_1"
10691 [(set (match_operand:DI 0 "register_operand" "=q")
10692 (match_operator:DI 1 "ix86_comparison_operator"
10693 [(reg FLAGS_REG) (const_int 0)]))]
10694 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10695 "#"
10696 "&& reload_completed"
10697 [(set (match_dup 2) (match_dup 1))
10698 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10699 {
10700 PUT_MODE (operands[1], QImode);
10701 operands[2] = gen_lowpart (QImode, operands[0]);
10702 })
10703
10704 (define_insn_and_split "*setcc_si_1_and"
10705 [(set (match_operand:SI 0 "register_operand" "=q")
10706 (match_operator:SI 1 "ix86_comparison_operator"
10707 [(reg FLAGS_REG) (const_int 0)]))
10708 (clobber (reg:CC FLAGS_REG))]
10709 "!TARGET_PARTIAL_REG_STALL
10710 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10711 "#"
10712 "&& reload_completed"
10713 [(set (match_dup 2) (match_dup 1))
10714 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10715 (clobber (reg:CC FLAGS_REG))])]
10716 {
10717 PUT_MODE (operands[1], QImode);
10718 operands[2] = gen_lowpart (QImode, operands[0]);
10719 })
10720
10721 (define_insn_and_split "*setcc_si_1_movzbl"
10722 [(set (match_operand:SI 0 "register_operand" "=q")
10723 (match_operator:SI 1 "ix86_comparison_operator"
10724 [(reg FLAGS_REG) (const_int 0)]))]
10725 "!TARGET_PARTIAL_REG_STALL
10726 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10727 "#"
10728 "&& reload_completed"
10729 [(set (match_dup 2) (match_dup 1))
10730 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10731 {
10732 PUT_MODE (operands[1], QImode);
10733 operands[2] = gen_lowpart (QImode, operands[0]);
10734 })
10735
10736 (define_insn "*setcc_qi"
10737 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10738 (match_operator:QI 1 "ix86_comparison_operator"
10739 [(reg FLAGS_REG) (const_int 0)]))]
10740 ""
10741 "set%C1\t%0"
10742 [(set_attr "type" "setcc")
10743 (set_attr "mode" "QI")])
10744
10745 (define_insn "*setcc_qi_slp"
10746 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10747 (match_operator:QI 1 "ix86_comparison_operator"
10748 [(reg FLAGS_REG) (const_int 0)]))]
10749 ""
10750 "set%C1\t%0"
10751 [(set_attr "type" "setcc")
10752 (set_attr "mode" "QI")])
10753
10754 ;; In general it is not safe to assume too much about CCmode registers,
10755 ;; so simplify-rtx stops when it sees a second one. Under certain
10756 ;; conditions this is safe on x86, so help combine not create
10757 ;;
10758 ;; seta %al
10759 ;; testb %al, %al
10760 ;; sete %al
10761
10762 (define_split
10763 [(set (match_operand:QI 0 "nonimmediate_operand")
10764 (ne:QI (match_operator 1 "ix86_comparison_operator"
10765 [(reg FLAGS_REG) (const_int 0)])
10766 (const_int 0)))]
10767 ""
10768 [(set (match_dup 0) (match_dup 1))]
10769 "PUT_MODE (operands[1], QImode);")
10770
10771 (define_split
10772 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10773 (ne:QI (match_operator 1 "ix86_comparison_operator"
10774 [(reg FLAGS_REG) (const_int 0)])
10775 (const_int 0)))]
10776 ""
10777 [(set (match_dup 0) (match_dup 1))]
10778 "PUT_MODE (operands[1], QImode);")
10779
10780 (define_split
10781 [(set (match_operand:QI 0 "nonimmediate_operand")
10782 (eq:QI (match_operator 1 "ix86_comparison_operator"
10783 [(reg FLAGS_REG) (const_int 0)])
10784 (const_int 0)))]
10785 ""
10786 [(set (match_dup 0) (match_dup 1))]
10787 {
10788 rtx new_op1 = copy_rtx (operands[1]);
10789 operands[1] = new_op1;
10790 PUT_MODE (new_op1, QImode);
10791 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10792 GET_MODE (XEXP (new_op1, 0))));
10793
10794 /* Make sure that (a) the CCmode we have for the flags is strong
10795 enough for the reversed compare or (b) we have a valid FP compare. */
10796 if (! ix86_comparison_operator (new_op1, VOIDmode))
10797 FAIL;
10798 })
10799
10800 (define_split
10801 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10802 (eq:QI (match_operator 1 "ix86_comparison_operator"
10803 [(reg FLAGS_REG) (const_int 0)])
10804 (const_int 0)))]
10805 ""
10806 [(set (match_dup 0) (match_dup 1))]
10807 {
10808 rtx new_op1 = copy_rtx (operands[1]);
10809 operands[1] = new_op1;
10810 PUT_MODE (new_op1, QImode);
10811 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10812 GET_MODE (XEXP (new_op1, 0))));
10813
10814 /* Make sure that (a) the CCmode we have for the flags is strong
10815 enough for the reversed compare or (b) we have a valid FP compare. */
10816 if (! ix86_comparison_operator (new_op1, VOIDmode))
10817 FAIL;
10818 })
10819
10820 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10821 ;; subsequent logical operations are used to imitate conditional moves.
10822 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10823 ;; it directly.
10824
10825 (define_insn "setcc_<mode>_sse"
10826 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10827 (match_operator:MODEF 3 "sse_comparison_operator"
10828 [(match_operand:MODEF 1 "register_operand" "0,x")
10829 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10830 "SSE_FLOAT_MODE_P (<MODE>mode)"
10831 "@
10832 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10833 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10834 [(set_attr "isa" "noavx,avx")
10835 (set_attr "type" "ssecmp")
10836 (set_attr "length_immediate" "1")
10837 (set_attr "prefix" "orig,vex")
10838 (set_attr "mode" "<MODE>")])
10839 \f
10840 ;; Basic conditional jump instructions.
10841 ;; We ignore the overflow flag for signed branch instructions.
10842
10843 (define_insn "*jcc_1"
10844 [(set (pc)
10845 (if_then_else (match_operator 1 "ix86_comparison_operator"
10846 [(reg FLAGS_REG) (const_int 0)])
10847 (label_ref (match_operand 0))
10848 (pc)))]
10849 ""
10850 "%+j%C1\t%l0"
10851 [(set_attr "type" "ibr")
10852 (set_attr "modrm" "0")
10853 (set (attr "length")
10854 (if_then_else (and (ge (minus (match_dup 0) (pc))
10855 (const_int -126))
10856 (lt (minus (match_dup 0) (pc))
10857 (const_int 128)))
10858 (const_int 2)
10859 (const_int 6)))])
10860
10861 (define_insn "*jcc_2"
10862 [(set (pc)
10863 (if_then_else (match_operator 1 "ix86_comparison_operator"
10864 [(reg FLAGS_REG) (const_int 0)])
10865 (pc)
10866 (label_ref (match_operand 0))))]
10867 ""
10868 "%+j%c1\t%l0"
10869 [(set_attr "type" "ibr")
10870 (set_attr "modrm" "0")
10871 (set (attr "length")
10872 (if_then_else (and (ge (minus (match_dup 0) (pc))
10873 (const_int -126))
10874 (lt (minus (match_dup 0) (pc))
10875 (const_int 128)))
10876 (const_int 2)
10877 (const_int 6)))])
10878
10879 ;; In general it is not safe to assume too much about CCmode registers,
10880 ;; so simplify-rtx stops when it sees a second one. Under certain
10881 ;; conditions this is safe on x86, so help combine not create
10882 ;;
10883 ;; seta %al
10884 ;; testb %al, %al
10885 ;; je Lfoo
10886
10887 (define_split
10888 [(set (pc)
10889 (if_then_else (ne (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 "PUT_MODE (operands[0], VOIDmode);")
10900
10901 (define_split
10902 [(set (pc)
10903 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10904 [(reg FLAGS_REG) (const_int 0)])
10905 (const_int 0))
10906 (label_ref (match_operand 1))
10907 (pc)))]
10908 ""
10909 [(set (pc)
10910 (if_then_else (match_dup 0)
10911 (label_ref (match_dup 1))
10912 (pc)))]
10913 {
10914 rtx new_op0 = copy_rtx (operands[0]);
10915 operands[0] = new_op0;
10916 PUT_MODE (new_op0, VOIDmode);
10917 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10918 GET_MODE (XEXP (new_op0, 0))));
10919
10920 /* Make sure that (a) the CCmode we have for the flags is strong
10921 enough for the reversed compare or (b) we have a valid FP compare. */
10922 if (! ix86_comparison_operator (new_op0, VOIDmode))
10923 FAIL;
10924 })
10925
10926 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10927 ;; pass generates from shift insn with QImode operand. Actually, the mode
10928 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10929 ;; appropriate modulo of the bit offset value.
10930
10931 (define_insn_and_split "*jcc_bt<mode>"
10932 [(set (pc)
10933 (if_then_else (match_operator 0 "bt_comparison_operator"
10934 [(zero_extract:SWI48
10935 (match_operand:SWI48 1 "register_operand" "r")
10936 (const_int 1)
10937 (zero_extend:SI
10938 (match_operand:QI 2 "register_operand" "r")))
10939 (const_int 0)])
10940 (label_ref (match_operand 3))
10941 (pc)))
10942 (clobber (reg:CC FLAGS_REG))]
10943 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10944 "#"
10945 "&& 1"
10946 [(set (reg:CCC FLAGS_REG)
10947 (compare:CCC
10948 (zero_extract:SWI48
10949 (match_dup 1)
10950 (const_int 1)
10951 (match_dup 2))
10952 (const_int 0)))
10953 (set (pc)
10954 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10955 (label_ref (match_dup 3))
10956 (pc)))]
10957 {
10958 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10959
10960 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10961 })
10962
10963 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10964 ;; also for DImode, this is what combine produces.
10965 (define_insn_and_split "*jcc_bt<mode>_mask"
10966 [(set (pc)
10967 (if_then_else (match_operator 0 "bt_comparison_operator"
10968 [(zero_extract:SWI48
10969 (match_operand:SWI48 1 "register_operand" "r")
10970 (const_int 1)
10971 (and:SI
10972 (match_operand:SI 2 "register_operand" "r")
10973 (match_operand:SI 3 "const_int_operand" "n")))])
10974 (label_ref (match_operand 4))
10975 (pc)))
10976 (clobber (reg:CC FLAGS_REG))]
10977 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10978 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10979 == GET_MODE_BITSIZE (<MODE>mode)-1"
10980 "#"
10981 "&& 1"
10982 [(set (reg:CCC FLAGS_REG)
10983 (compare:CCC
10984 (zero_extract:SWI48
10985 (match_dup 1)
10986 (const_int 1)
10987 (match_dup 2))
10988 (const_int 0)))
10989 (set (pc)
10990 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10991 (label_ref (match_dup 4))
10992 (pc)))]
10993 {
10994 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10995
10996 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10997 })
10998
10999 (define_insn_and_split "*jcc_btsi_1"
11000 [(set (pc)
11001 (if_then_else (match_operator 0 "bt_comparison_operator"
11002 [(and:SI
11003 (lshiftrt:SI
11004 (match_operand:SI 1 "register_operand" "r")
11005 (match_operand:QI 2 "register_operand" "r"))
11006 (const_int 1))
11007 (const_int 0)])
11008 (label_ref (match_operand 3))
11009 (pc)))
11010 (clobber (reg:CC FLAGS_REG))]
11011 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11012 "#"
11013 "&& 1"
11014 [(set (reg:CCC FLAGS_REG)
11015 (compare:CCC
11016 (zero_extract:SI
11017 (match_dup 1)
11018 (const_int 1)
11019 (match_dup 2))
11020 (const_int 0)))
11021 (set (pc)
11022 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11023 (label_ref (match_dup 3))
11024 (pc)))]
11025 {
11026 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11027
11028 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11029 })
11030
11031 ;; avoid useless masking of bit offset operand
11032 (define_insn_and_split "*jcc_btsi_mask_1"
11033 [(set (pc)
11034 (if_then_else
11035 (match_operator 0 "bt_comparison_operator"
11036 [(and:SI
11037 (lshiftrt:SI
11038 (match_operand:SI 1 "register_operand" "r")
11039 (subreg:QI
11040 (and:SI
11041 (match_operand:SI 2 "register_operand" "r")
11042 (match_operand:SI 3 "const_int_operand" "n")) 0))
11043 (const_int 1))
11044 (const_int 0)])
11045 (label_ref (match_operand 4))
11046 (pc)))
11047 (clobber (reg:CC FLAGS_REG))]
11048 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11049 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11050 "#"
11051 "&& 1"
11052 [(set (reg:CCC FLAGS_REG)
11053 (compare:CCC
11054 (zero_extract:SI
11055 (match_dup 1)
11056 (const_int 1)
11057 (match_dup 2))
11058 (const_int 0)))
11059 (set (pc)
11060 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11061 (label_ref (match_dup 4))
11062 (pc)))]
11063 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11064
11065 ;; Define combination compare-and-branch fp compare instructions to help
11066 ;; combine.
11067
11068 (define_insn "*fp_jcc_1_387"
11069 [(set (pc)
11070 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11071 [(match_operand 1 "register_operand" "f")
11072 (match_operand 2 "nonimmediate_operand" "fm")])
11073 (label_ref (match_operand 3))
11074 (pc)))
11075 (clobber (reg:CCFP FPSR_REG))
11076 (clobber (reg:CCFP FLAGS_REG))
11077 (clobber (match_scratch:HI 4 "=a"))]
11078 "TARGET_80387
11079 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11080 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11081 && SELECT_CC_MODE (GET_CODE (operands[0]),
11082 operands[1], operands[2]) == CCFPmode
11083 && !TARGET_CMOVE"
11084 "#")
11085
11086 (define_insn "*fp_jcc_1r_387"
11087 [(set (pc)
11088 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11089 [(match_operand 1 "register_operand" "f")
11090 (match_operand 2 "nonimmediate_operand" "fm")])
11091 (pc)
11092 (label_ref (match_operand 3))))
11093 (clobber (reg:CCFP FPSR_REG))
11094 (clobber (reg:CCFP FLAGS_REG))
11095 (clobber (match_scratch:HI 4 "=a"))]
11096 "TARGET_80387
11097 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11098 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11099 && SELECT_CC_MODE (GET_CODE (operands[0]),
11100 operands[1], operands[2]) == CCFPmode
11101 && !TARGET_CMOVE"
11102 "#")
11103
11104 (define_insn "*fp_jcc_2_387"
11105 [(set (pc)
11106 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11107 [(match_operand 1 "register_operand" "f")
11108 (match_operand 2 "register_operand" "f")])
11109 (label_ref (match_operand 3))
11110 (pc)))
11111 (clobber (reg:CCFP FPSR_REG))
11112 (clobber (reg:CCFP FLAGS_REG))
11113 (clobber (match_scratch:HI 4 "=a"))]
11114 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11115 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11116 && !TARGET_CMOVE"
11117 "#")
11118
11119 (define_insn "*fp_jcc_2r_387"
11120 [(set (pc)
11121 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11122 [(match_operand 1 "register_operand" "f")
11123 (match_operand 2 "register_operand" "f")])
11124 (pc)
11125 (label_ref (match_operand 3))))
11126 (clobber (reg:CCFP FPSR_REG))
11127 (clobber (reg:CCFP FLAGS_REG))
11128 (clobber (match_scratch:HI 4 "=a"))]
11129 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11130 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11131 && !TARGET_CMOVE"
11132 "#")
11133
11134 (define_insn "*fp_jcc_3_387"
11135 [(set (pc)
11136 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11137 [(match_operand 1 "register_operand" "f")
11138 (match_operand 2 "const0_operand")])
11139 (label_ref (match_operand 3))
11140 (pc)))
11141 (clobber (reg:CCFP FPSR_REG))
11142 (clobber (reg:CCFP FLAGS_REG))
11143 (clobber (match_scratch:HI 4 "=a"))]
11144 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11145 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11146 && SELECT_CC_MODE (GET_CODE (operands[0]),
11147 operands[1], operands[2]) == CCFPmode
11148 && !TARGET_CMOVE"
11149 "#")
11150
11151 (define_split
11152 [(set (pc)
11153 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11154 [(match_operand 1 "register_operand")
11155 (match_operand 2 "nonimmediate_operand")])
11156 (match_operand 3)
11157 (match_operand 4)))
11158 (clobber (reg:CCFP FPSR_REG))
11159 (clobber (reg:CCFP FLAGS_REG))]
11160 "reload_completed"
11161 [(const_int 0)]
11162 {
11163 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11164 operands[3], operands[4], NULL_RTX, NULL_RTX);
11165 DONE;
11166 })
11167
11168 (define_split
11169 [(set (pc)
11170 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11171 [(match_operand 1 "register_operand")
11172 (match_operand 2 "general_operand")])
11173 (match_operand 3)
11174 (match_operand 4)))
11175 (clobber (reg:CCFP FPSR_REG))
11176 (clobber (reg:CCFP FLAGS_REG))
11177 (clobber (match_scratch:HI 5 "=a"))]
11178 "reload_completed"
11179 [(const_int 0)]
11180 {
11181 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11182 operands[3], operands[4], operands[5], NULL_RTX);
11183 DONE;
11184 })
11185
11186 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11187 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11188 ;; with a precedence over other operators and is always put in the first
11189 ;; place. Swap condition and operands to match ficom instruction.
11190
11191 (define_insn "*fp_jcc_4_<mode>_387"
11192 [(set (pc)
11193 (if_then_else
11194 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11195 [(match_operator 1 "float_operator"
11196 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11197 (match_operand 3 "register_operand" "f,f")])
11198 (label_ref (match_operand 4))
11199 (pc)))
11200 (clobber (reg:CCFP FPSR_REG))
11201 (clobber (reg:CCFP FLAGS_REG))
11202 (clobber (match_scratch:HI 5 "=a,a"))]
11203 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11204 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11205 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11206 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11207 && !TARGET_CMOVE"
11208 "#")
11209
11210 (define_split
11211 [(set (pc)
11212 (if_then_else
11213 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11214 [(match_operator 1 "float_operator"
11215 [(match_operand:SWI24 2 "memory_operand")])
11216 (match_operand 3 "register_operand")])
11217 (match_operand 4)
11218 (match_operand 5)))
11219 (clobber (reg:CCFP FPSR_REG))
11220 (clobber (reg:CCFP FLAGS_REG))
11221 (clobber (match_scratch:HI 6 "=a"))]
11222 "reload_completed"
11223 [(const_int 0)]
11224 {
11225 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11226
11227 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11228 operands[3], operands[7],
11229 operands[4], operands[5], operands[6], NULL_RTX);
11230 DONE;
11231 })
11232
11233 ;; %%% Kill this when reload knows how to do it.
11234 (define_split
11235 [(set (pc)
11236 (if_then_else
11237 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11238 [(match_operator 1 "float_operator"
11239 [(match_operand:SWI24 2 "register_operand")])
11240 (match_operand 3 "register_operand")])
11241 (match_operand 4)
11242 (match_operand 5)))
11243 (clobber (reg:CCFP FPSR_REG))
11244 (clobber (reg:CCFP FLAGS_REG))
11245 (clobber (match_scratch:HI 6 "=a"))]
11246 "reload_completed"
11247 [(const_int 0)]
11248 {
11249 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11250 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11251
11252 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11253 operands[3], operands[7],
11254 operands[4], operands[5], operands[6], operands[2]);
11255 DONE;
11256 })
11257 \f
11258 ;; Unconditional and other jump instructions
11259
11260 (define_insn "jump"
11261 [(set (pc)
11262 (label_ref (match_operand 0)))]
11263 ""
11264 "jmp\t%l0"
11265 [(set_attr "type" "ibr")
11266 (set (attr "length")
11267 (if_then_else (and (ge (minus (match_dup 0) (pc))
11268 (const_int -126))
11269 (lt (minus (match_dup 0) (pc))
11270 (const_int 128)))
11271 (const_int 2)
11272 (const_int 5)))
11273 (set_attr "modrm" "0")])
11274
11275 (define_expand "indirect_jump"
11276 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11277 ""
11278 {
11279 if (TARGET_X32)
11280 operands[0] = convert_memory_address (word_mode, operands[0]);
11281 })
11282
11283 (define_insn "*indirect_jump"
11284 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11285 ""
11286 "jmp\t%A0"
11287 [(set_attr "type" "ibr")
11288 (set_attr "length_immediate" "0")])
11289
11290 (define_expand "tablejump"
11291 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11292 (use (label_ref (match_operand 1)))])]
11293 ""
11294 {
11295 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11296 relative. Convert the relative address to an absolute address. */
11297 if (flag_pic)
11298 {
11299 rtx op0, op1;
11300 enum rtx_code code;
11301
11302 /* We can't use @GOTOFF for text labels on VxWorks;
11303 see gotoff_operand. */
11304 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11305 {
11306 code = PLUS;
11307 op0 = operands[0];
11308 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11309 }
11310 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11311 {
11312 code = PLUS;
11313 op0 = operands[0];
11314 op1 = pic_offset_table_rtx;
11315 }
11316 else
11317 {
11318 code = MINUS;
11319 op0 = pic_offset_table_rtx;
11320 op1 = operands[0];
11321 }
11322
11323 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11324 OPTAB_DIRECT);
11325 }
11326
11327 if (TARGET_X32)
11328 operands[0] = convert_memory_address (word_mode, operands[0]);
11329 })
11330
11331 (define_insn "*tablejump_1"
11332 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11333 (use (label_ref (match_operand 1)))]
11334 ""
11335 "jmp\t%A0"
11336 [(set_attr "type" "ibr")
11337 (set_attr "length_immediate" "0")])
11338 \f
11339 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11340
11341 (define_peephole2
11342 [(set (reg FLAGS_REG) (match_operand 0))
11343 (set (match_operand:QI 1 "register_operand")
11344 (match_operator:QI 2 "ix86_comparison_operator"
11345 [(reg FLAGS_REG) (const_int 0)]))
11346 (set (match_operand 3 "q_regs_operand")
11347 (zero_extend (match_dup 1)))]
11348 "(peep2_reg_dead_p (3, operands[1])
11349 || operands_match_p (operands[1], operands[3]))
11350 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11351 [(set (match_dup 4) (match_dup 0))
11352 (set (strict_low_part (match_dup 5))
11353 (match_dup 2))]
11354 {
11355 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11356 operands[5] = gen_lowpart (QImode, operands[3]);
11357 ix86_expand_clear (operands[3]);
11358 })
11359
11360 (define_peephole2
11361 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11362 (match_operand 4)])
11363 (set (match_operand:QI 1 "register_operand")
11364 (match_operator:QI 2 "ix86_comparison_operator"
11365 [(reg FLAGS_REG) (const_int 0)]))
11366 (set (match_operand 3 "q_regs_operand")
11367 (zero_extend (match_dup 1)))]
11368 "(peep2_reg_dead_p (3, operands[1])
11369 || operands_match_p (operands[1], operands[3]))
11370 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11371 [(parallel [(set (match_dup 5) (match_dup 0))
11372 (match_dup 4)])
11373 (set (strict_low_part (match_dup 6))
11374 (match_dup 2))]
11375 {
11376 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11377 operands[6] = gen_lowpart (QImode, operands[3]);
11378 ix86_expand_clear (operands[3]);
11379 })
11380
11381 ;; Similar, but match zero extend with andsi3.
11382
11383 (define_peephole2
11384 [(set (reg FLAGS_REG) (match_operand 0))
11385 (set (match_operand:QI 1 "register_operand")
11386 (match_operator:QI 2 "ix86_comparison_operator"
11387 [(reg FLAGS_REG) (const_int 0)]))
11388 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11389 (and:SI (match_dup 3) (const_int 255)))
11390 (clobber (reg:CC FLAGS_REG))])]
11391 "REGNO (operands[1]) == REGNO (operands[3])
11392 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11393 [(set (match_dup 4) (match_dup 0))
11394 (set (strict_low_part (match_dup 5))
11395 (match_dup 2))]
11396 {
11397 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11398 operands[5] = gen_lowpart (QImode, operands[3]);
11399 ix86_expand_clear (operands[3]);
11400 })
11401
11402 (define_peephole2
11403 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11404 (match_operand 4)])
11405 (set (match_operand:QI 1 "register_operand")
11406 (match_operator:QI 2 "ix86_comparison_operator"
11407 [(reg FLAGS_REG) (const_int 0)]))
11408 (parallel [(set (match_operand 3 "q_regs_operand")
11409 (zero_extend (match_dup 1)))
11410 (clobber (reg:CC FLAGS_REG))])]
11411 "(peep2_reg_dead_p (3, operands[1])
11412 || operands_match_p (operands[1], operands[3]))
11413 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11414 [(parallel [(set (match_dup 5) (match_dup 0))
11415 (match_dup 4)])
11416 (set (strict_low_part (match_dup 6))
11417 (match_dup 2))]
11418 {
11419 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11420 operands[6] = gen_lowpart (QImode, operands[3]);
11421 ix86_expand_clear (operands[3]);
11422 })
11423 \f
11424 ;; Call instructions.
11425
11426 ;; The predicates normally associated with named expanders are not properly
11427 ;; checked for calls. This is a bug in the generic code, but it isn't that
11428 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11429
11430 ;; P6 processors will jump to the address after the decrement when %esp
11431 ;; is used as a call operand, so they will execute return address as a code.
11432 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11433
11434 ;; Register constraint for call instruction.
11435 (define_mode_attr c [(SI "l") (DI "r")])
11436
11437 ;; Call subroutine returning no value.
11438
11439 (define_expand "call"
11440 [(call (match_operand:QI 0)
11441 (match_operand 1))
11442 (use (match_operand 2))]
11443 ""
11444 {
11445 ix86_expand_call (NULL, operands[0], operands[1],
11446 operands[2], NULL, false);
11447 DONE;
11448 })
11449
11450 (define_expand "sibcall"
11451 [(call (match_operand:QI 0)
11452 (match_operand 1))
11453 (use (match_operand 2))]
11454 ""
11455 {
11456 ix86_expand_call (NULL, operands[0], operands[1],
11457 operands[2], NULL, true);
11458 DONE;
11459 })
11460
11461 (define_insn_and_split "*call_vzeroupper"
11462 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11463 (match_operand 1))
11464 (unspec [(match_operand 2 "const_int_operand")]
11465 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11466 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11467 "#"
11468 "&& reload_completed"
11469 [(const_int 0)]
11470 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11471 [(set_attr "type" "call")])
11472
11473 (define_insn "*call"
11474 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11475 (match_operand 1))]
11476 "!SIBLING_CALL_P (insn)"
11477 "* return ix86_output_call_insn (insn, operands[0]);"
11478 [(set_attr "type" "call")])
11479
11480 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11481 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11482 (match_operand 1))
11483 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11484 (clobber (reg:TI XMM6_REG))
11485 (clobber (reg:TI XMM7_REG))
11486 (clobber (reg:TI XMM8_REG))
11487 (clobber (reg:TI XMM9_REG))
11488 (clobber (reg:TI XMM10_REG))
11489 (clobber (reg:TI XMM11_REG))
11490 (clobber (reg:TI XMM12_REG))
11491 (clobber (reg:TI XMM13_REG))
11492 (clobber (reg:TI XMM14_REG))
11493 (clobber (reg:TI XMM15_REG))
11494 (clobber (reg:DI SI_REG))
11495 (clobber (reg:DI DI_REG))
11496 (unspec [(match_operand 2 "const_int_operand")]
11497 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11498 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11499 "#"
11500 "&& reload_completed"
11501 [(const_int 0)]
11502 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11503 [(set_attr "type" "call")])
11504
11505 (define_insn "*call_rex64_ms_sysv"
11506 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11507 (match_operand 1))
11508 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11509 (clobber (reg:TI XMM6_REG))
11510 (clobber (reg:TI XMM7_REG))
11511 (clobber (reg:TI XMM8_REG))
11512 (clobber (reg:TI XMM9_REG))
11513 (clobber (reg:TI XMM10_REG))
11514 (clobber (reg:TI XMM11_REG))
11515 (clobber (reg:TI XMM12_REG))
11516 (clobber (reg:TI XMM13_REG))
11517 (clobber (reg:TI XMM14_REG))
11518 (clobber (reg:TI XMM15_REG))
11519 (clobber (reg:DI SI_REG))
11520 (clobber (reg:DI DI_REG))]
11521 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11522 "* return ix86_output_call_insn (insn, operands[0]);"
11523 [(set_attr "type" "call")])
11524
11525 (define_insn_and_split "*sibcall_vzeroupper"
11526 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11527 (match_operand 1))
11528 (unspec [(match_operand 2 "const_int_operand")]
11529 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11530 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11531 "#"
11532 "&& reload_completed"
11533 [(const_int 0)]
11534 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11535 [(set_attr "type" "call")])
11536
11537 (define_insn "*sibcall"
11538 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11539 (match_operand 1))]
11540 "SIBLING_CALL_P (insn)"
11541 "* return ix86_output_call_insn (insn, operands[0]);"
11542 [(set_attr "type" "call")])
11543
11544 (define_expand "call_pop"
11545 [(parallel [(call (match_operand:QI 0)
11546 (match_operand:SI 1))
11547 (set (reg:SI SP_REG)
11548 (plus:SI (reg:SI SP_REG)
11549 (match_operand:SI 3)))])]
11550 "!TARGET_64BIT"
11551 {
11552 ix86_expand_call (NULL, operands[0], operands[1],
11553 operands[2], operands[3], false);
11554 DONE;
11555 })
11556
11557 (define_insn_and_split "*call_pop_vzeroupper"
11558 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11559 (match_operand 1))
11560 (set (reg:SI SP_REG)
11561 (plus:SI (reg:SI SP_REG)
11562 (match_operand:SI 2 "immediate_operand" "i")))
11563 (unspec [(match_operand 3 "const_int_operand")]
11564 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11565 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11566 "#"
11567 "&& reload_completed"
11568 [(const_int 0)]
11569 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11570 [(set_attr "type" "call")])
11571
11572 (define_insn "*call_pop"
11573 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11574 (match_operand 1))
11575 (set (reg:SI SP_REG)
11576 (plus:SI (reg:SI SP_REG)
11577 (match_operand:SI 2 "immediate_operand" "i")))]
11578 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11579 "* return ix86_output_call_insn (insn, operands[0]);"
11580 [(set_attr "type" "call")])
11581
11582 (define_insn_and_split "*sibcall_pop_vzeroupper"
11583 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11584 (match_operand 1))
11585 (set (reg:SI SP_REG)
11586 (plus:SI (reg:SI SP_REG)
11587 (match_operand:SI 2 "immediate_operand" "i")))
11588 (unspec [(match_operand 3 "const_int_operand")]
11589 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11590 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11591 "#"
11592 "&& reload_completed"
11593 [(const_int 0)]
11594 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11595 [(set_attr "type" "call")])
11596
11597 (define_insn "*sibcall_pop"
11598 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11599 (match_operand 1))
11600 (set (reg:SI SP_REG)
11601 (plus:SI (reg:SI SP_REG)
11602 (match_operand:SI 2 "immediate_operand" "i")))]
11603 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11604 "* return ix86_output_call_insn (insn, operands[0]);"
11605 [(set_attr "type" "call")])
11606
11607 ;; Call subroutine, returning value in operand 0
11608
11609 (define_expand "call_value"
11610 [(set (match_operand 0)
11611 (call (match_operand:QI 1)
11612 (match_operand 2)))
11613 (use (match_operand 3))]
11614 ""
11615 {
11616 ix86_expand_call (operands[0], operands[1], operands[2],
11617 operands[3], NULL, false);
11618 DONE;
11619 })
11620
11621 (define_expand "sibcall_value"
11622 [(set (match_operand 0)
11623 (call (match_operand:QI 1)
11624 (match_operand 2)))
11625 (use (match_operand 3))]
11626 ""
11627 {
11628 ix86_expand_call (operands[0], operands[1], operands[2],
11629 operands[3], NULL, true);
11630 DONE;
11631 })
11632
11633 (define_insn_and_split "*call_value_vzeroupper"
11634 [(set (match_operand 0)
11635 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11636 (match_operand 2)))
11637 (unspec [(match_operand 3 "const_int_operand")]
11638 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11639 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11640 "#"
11641 "&& reload_completed"
11642 [(const_int 0)]
11643 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11644 [(set_attr "type" "callv")])
11645
11646 (define_insn "*call_value"
11647 [(set (match_operand 0)
11648 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11649 (match_operand 2)))]
11650 "!SIBLING_CALL_P (insn)"
11651 "* return ix86_output_call_insn (insn, operands[1]);"
11652 [(set_attr "type" "callv")])
11653
11654 (define_insn_and_split "*sibcall_value_vzeroupper"
11655 [(set (match_operand 0)
11656 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11657 (match_operand 2)))
11658 (unspec [(match_operand 3 "const_int_operand")]
11659 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11660 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11661 "#"
11662 "&& reload_completed"
11663 [(const_int 0)]
11664 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11665 [(set_attr "type" "callv")])
11666
11667 (define_insn "*sibcall_value"
11668 [(set (match_operand 0)
11669 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11670 (match_operand 2)))]
11671 "SIBLING_CALL_P (insn)"
11672 "* return ix86_output_call_insn (insn, operands[1]);"
11673 [(set_attr "type" "callv")])
11674
11675 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11676 [(set (match_operand 0)
11677 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11678 (match_operand 2)))
11679 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11680 (clobber (reg:TI XMM6_REG))
11681 (clobber (reg:TI XMM7_REG))
11682 (clobber (reg:TI XMM8_REG))
11683 (clobber (reg:TI XMM9_REG))
11684 (clobber (reg:TI XMM10_REG))
11685 (clobber (reg:TI XMM11_REG))
11686 (clobber (reg:TI XMM12_REG))
11687 (clobber (reg:TI XMM13_REG))
11688 (clobber (reg:TI XMM14_REG))
11689 (clobber (reg:TI XMM15_REG))
11690 (clobber (reg:DI SI_REG))
11691 (clobber (reg:DI DI_REG))
11692 (unspec [(match_operand 3 "const_int_operand")]
11693 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11694 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11695 "#"
11696 "&& reload_completed"
11697 [(const_int 0)]
11698 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11699 [(set_attr "type" "callv")])
11700
11701 (define_insn "*call_value_rex64_ms_sysv"
11702 [(set (match_operand 0)
11703 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11704 (match_operand 2)))
11705 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11706 (clobber (reg:TI XMM6_REG))
11707 (clobber (reg:TI XMM7_REG))
11708 (clobber (reg:TI XMM8_REG))
11709 (clobber (reg:TI XMM9_REG))
11710 (clobber (reg:TI XMM10_REG))
11711 (clobber (reg:TI XMM11_REG))
11712 (clobber (reg:TI XMM12_REG))
11713 (clobber (reg:TI XMM13_REG))
11714 (clobber (reg:TI XMM14_REG))
11715 (clobber (reg:TI XMM15_REG))
11716 (clobber (reg:DI SI_REG))
11717 (clobber (reg:DI DI_REG))]
11718 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11719 "* return ix86_output_call_insn (insn, operands[1]);"
11720 [(set_attr "type" "callv")])
11721
11722 (define_expand "call_value_pop"
11723 [(parallel [(set (match_operand 0)
11724 (call (match_operand:QI 1)
11725 (match_operand:SI 2)))
11726 (set (reg:SI SP_REG)
11727 (plus:SI (reg:SI SP_REG)
11728 (match_operand:SI 4)))])]
11729 "!TARGET_64BIT"
11730 {
11731 ix86_expand_call (operands[0], operands[1], operands[2],
11732 operands[3], operands[4], false);
11733 DONE;
11734 })
11735
11736 (define_insn_and_split "*call_value_pop_vzeroupper"
11737 [(set (match_operand 0)
11738 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11739 (match_operand 2)))
11740 (set (reg:SI SP_REG)
11741 (plus:SI (reg:SI SP_REG)
11742 (match_operand:SI 3 "immediate_operand" "i")))
11743 (unspec [(match_operand 4 "const_int_operand")]
11744 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11745 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11746 "#"
11747 "&& reload_completed"
11748 [(const_int 0)]
11749 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11750 [(set_attr "type" "callv")])
11751
11752 (define_insn "*call_value_pop"
11753 [(set (match_operand 0)
11754 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11755 (match_operand 2)))
11756 (set (reg:SI SP_REG)
11757 (plus:SI (reg:SI SP_REG)
11758 (match_operand:SI 3 "immediate_operand" "i")))]
11759 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11760 "* return ix86_output_call_insn (insn, operands[1]);"
11761 [(set_attr "type" "callv")])
11762
11763 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11764 [(set (match_operand 0)
11765 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11766 (match_operand 2)))
11767 (set (reg:SI SP_REG)
11768 (plus:SI (reg:SI SP_REG)
11769 (match_operand:SI 3 "immediate_operand" "i")))
11770 (unspec [(match_operand 4 "const_int_operand")]
11771 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11772 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11773 "#"
11774 "&& reload_completed"
11775 [(const_int 0)]
11776 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11777 [(set_attr "type" "callv")])
11778
11779 (define_insn "*sibcall_value_pop"
11780 [(set (match_operand 0)
11781 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11782 (match_operand 2)))
11783 (set (reg:SI SP_REG)
11784 (plus:SI (reg:SI SP_REG)
11785 (match_operand:SI 3 "immediate_operand" "i")))]
11786 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11787 "* return ix86_output_call_insn (insn, operands[1]);"
11788 [(set_attr "type" "callv")])
11789
11790 ;; Call subroutine returning any type.
11791
11792 (define_expand "untyped_call"
11793 [(parallel [(call (match_operand 0)
11794 (const_int 0))
11795 (match_operand 1)
11796 (match_operand 2)])]
11797 ""
11798 {
11799 int i;
11800
11801 /* In order to give reg-stack an easier job in validating two
11802 coprocessor registers as containing a possible return value,
11803 simply pretend the untyped call returns a complex long double
11804 value.
11805
11806 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11807 and should have the default ABI. */
11808
11809 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11810 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11811 operands[0], const0_rtx,
11812 GEN_INT ((TARGET_64BIT
11813 ? (ix86_abi == SYSV_ABI
11814 ? X86_64_SSE_REGPARM_MAX
11815 : X86_64_MS_SSE_REGPARM_MAX)
11816 : X86_32_SSE_REGPARM_MAX)
11817 - 1),
11818 NULL, false);
11819
11820 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11821 {
11822 rtx set = XVECEXP (operands[2], 0, i);
11823 emit_move_insn (SET_DEST (set), SET_SRC (set));
11824 }
11825
11826 /* The optimizer does not know that the call sets the function value
11827 registers we stored in the result block. We avoid problems by
11828 claiming that all hard registers are used and clobbered at this
11829 point. */
11830 emit_insn (gen_blockage ());
11831
11832 DONE;
11833 })
11834 \f
11835 ;; Prologue and epilogue instructions
11836
11837 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11838 ;; all of memory. This blocks insns from being moved across this point.
11839
11840 (define_insn "blockage"
11841 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11842 ""
11843 ""
11844 [(set_attr "length" "0")])
11845
11846 ;; Do not schedule instructions accessing memory across this point.
11847
11848 (define_expand "memory_blockage"
11849 [(set (match_dup 0)
11850 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11851 ""
11852 {
11853 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11854 MEM_VOLATILE_P (operands[0]) = 1;
11855 })
11856
11857 (define_insn "*memory_blockage"
11858 [(set (match_operand:BLK 0)
11859 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11860 ""
11861 ""
11862 [(set_attr "length" "0")])
11863
11864 ;; As USE insns aren't meaningful after reload, this is used instead
11865 ;; to prevent deleting instructions setting registers for PIC code
11866 (define_insn "prologue_use"
11867 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11868 ""
11869 ""
11870 [(set_attr "length" "0")])
11871
11872 ;; Insn emitted into the body of a function to return from a function.
11873 ;; This is only done if the function's epilogue is known to be simple.
11874 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11875
11876 (define_expand "return"
11877 [(simple_return)]
11878 "ix86_can_use_return_insn_p ()"
11879 {
11880 ix86_maybe_emit_epilogue_vzeroupper ();
11881 if (crtl->args.pops_args)
11882 {
11883 rtx popc = GEN_INT (crtl->args.pops_args);
11884 emit_jump_insn (gen_simple_return_pop_internal (popc));
11885 DONE;
11886 }
11887 })
11888
11889 ;; We need to disable this for TARGET_SEH, as otherwise
11890 ;; shrink-wrapped prologue gets enabled too. This might exceed
11891 ;; the maximum size of prologue in unwind information.
11892
11893 (define_expand "simple_return"
11894 [(simple_return)]
11895 "!TARGET_SEH"
11896 {
11897 ix86_maybe_emit_epilogue_vzeroupper ();
11898 if (crtl->args.pops_args)
11899 {
11900 rtx popc = GEN_INT (crtl->args.pops_args);
11901 emit_jump_insn (gen_simple_return_pop_internal (popc));
11902 DONE;
11903 }
11904 })
11905
11906 (define_insn "simple_return_internal"
11907 [(simple_return)]
11908 "reload_completed"
11909 "ret"
11910 [(set_attr "length" "1")
11911 (set_attr "atom_unit" "jeu")
11912 (set_attr "length_immediate" "0")
11913 (set_attr "modrm" "0")])
11914
11915 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11916 ;; instruction Athlon and K8 have.
11917
11918 (define_insn "simple_return_internal_long"
11919 [(simple_return)
11920 (unspec [(const_int 0)] UNSPEC_REP)]
11921 "reload_completed"
11922 "rep%; ret"
11923 [(set_attr "length" "2")
11924 (set_attr "atom_unit" "jeu")
11925 (set_attr "length_immediate" "0")
11926 (set_attr "prefix_rep" "1")
11927 (set_attr "modrm" "0")])
11928
11929 (define_insn "simple_return_pop_internal"
11930 [(simple_return)
11931 (use (match_operand:SI 0 "const_int_operand"))]
11932 "reload_completed"
11933 "ret\t%0"
11934 [(set_attr "length" "3")
11935 (set_attr "atom_unit" "jeu")
11936 (set_attr "length_immediate" "2")
11937 (set_attr "modrm" "0")])
11938
11939 (define_insn "simple_return_indirect_internal"
11940 [(simple_return)
11941 (use (match_operand:SI 0 "register_operand" "r"))]
11942 "reload_completed"
11943 "jmp\t%A0"
11944 [(set_attr "type" "ibr")
11945 (set_attr "length_immediate" "0")])
11946
11947 (define_insn "nop"
11948 [(const_int 0)]
11949 ""
11950 "nop"
11951 [(set_attr "length" "1")
11952 (set_attr "length_immediate" "0")
11953 (set_attr "modrm" "0")])
11954
11955 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11956 (define_insn "nops"
11957 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11958 UNSPECV_NOPS)]
11959 "reload_completed"
11960 {
11961 int num = INTVAL (operands[0]);
11962
11963 gcc_assert (IN_RANGE (num, 1, 8));
11964
11965 while (num--)
11966 fputs ("\tnop\n", asm_out_file);
11967
11968 return "";
11969 }
11970 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11971 (set_attr "length_immediate" "0")
11972 (set_attr "modrm" "0")])
11973
11974 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11975 ;; branch prediction penalty for the third jump in a 16-byte
11976 ;; block on K8.
11977
11978 (define_insn "pad"
11979 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11980 ""
11981 {
11982 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11983 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11984 #else
11985 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11986 The align insn is used to avoid 3 jump instructions in the row to improve
11987 branch prediction and the benefits hardly outweigh the cost of extra 8
11988 nops on the average inserted by full alignment pseudo operation. */
11989 #endif
11990 return "";
11991 }
11992 [(set_attr "length" "16")])
11993
11994 (define_expand "prologue"
11995 [(const_int 0)]
11996 ""
11997 "ix86_expand_prologue (); DONE;")
11998
11999 (define_insn "set_got"
12000 [(set (match_operand:SI 0 "register_operand" "=r")
12001 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12002 (clobber (reg:CC FLAGS_REG))]
12003 "!TARGET_64BIT"
12004 "* return output_set_got (operands[0], NULL_RTX);"
12005 [(set_attr "type" "multi")
12006 (set_attr "length" "12")])
12007
12008 (define_insn "set_got_labelled"
12009 [(set (match_operand:SI 0 "register_operand" "=r")
12010 (unspec:SI [(label_ref (match_operand 1))]
12011 UNSPEC_SET_GOT))
12012 (clobber (reg:CC FLAGS_REG))]
12013 "!TARGET_64BIT"
12014 "* return output_set_got (operands[0], operands[1]);"
12015 [(set_attr "type" "multi")
12016 (set_attr "length" "12")])
12017
12018 (define_insn "set_got_rex64"
12019 [(set (match_operand:DI 0 "register_operand" "=r")
12020 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12021 "TARGET_64BIT"
12022 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12023 [(set_attr "type" "lea")
12024 (set_attr "length_address" "4")
12025 (set_attr "mode" "DI")])
12026
12027 (define_insn "set_rip_rex64"
12028 [(set (match_operand:DI 0 "register_operand" "=r")
12029 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12030 "TARGET_64BIT"
12031 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12032 [(set_attr "type" "lea")
12033 (set_attr "length_address" "4")
12034 (set_attr "mode" "DI")])
12035
12036 (define_insn "set_got_offset_rex64"
12037 [(set (match_operand:DI 0 "register_operand" "=r")
12038 (unspec:DI
12039 [(label_ref (match_operand 1))]
12040 UNSPEC_SET_GOT_OFFSET))]
12041 "TARGET_LP64"
12042 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12043 [(set_attr "type" "imov")
12044 (set_attr "length_immediate" "0")
12045 (set_attr "length_address" "8")
12046 (set_attr "mode" "DI")])
12047
12048 (define_expand "epilogue"
12049 [(const_int 0)]
12050 ""
12051 "ix86_expand_epilogue (1); DONE;")
12052
12053 (define_expand "sibcall_epilogue"
12054 [(const_int 0)]
12055 ""
12056 "ix86_expand_epilogue (0); DONE;")
12057
12058 (define_expand "eh_return"
12059 [(use (match_operand 0 "register_operand"))]
12060 ""
12061 {
12062 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12063
12064 /* Tricky bit: we write the address of the handler to which we will
12065 be returning into someone else's stack frame, one word below the
12066 stack address we wish to restore. */
12067 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12068 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12069 tmp = gen_rtx_MEM (Pmode, tmp);
12070 emit_move_insn (tmp, ra);
12071
12072 emit_jump_insn (gen_eh_return_internal ());
12073 emit_barrier ();
12074 DONE;
12075 })
12076
12077 (define_insn_and_split "eh_return_internal"
12078 [(eh_return)]
12079 ""
12080 "#"
12081 "epilogue_completed"
12082 [(const_int 0)]
12083 "ix86_expand_epilogue (2); DONE;")
12084
12085 (define_insn "leave"
12086 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12087 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12088 (clobber (mem:BLK (scratch)))]
12089 "!TARGET_64BIT"
12090 "leave"
12091 [(set_attr "type" "leave")])
12092
12093 (define_insn "leave_rex64"
12094 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12095 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12096 (clobber (mem:BLK (scratch)))]
12097 "TARGET_64BIT"
12098 "leave"
12099 [(set_attr "type" "leave")])
12100 \f
12101 ;; Handle -fsplit-stack.
12102
12103 (define_expand "split_stack_prologue"
12104 [(const_int 0)]
12105 ""
12106 {
12107 ix86_expand_split_stack_prologue ();
12108 DONE;
12109 })
12110
12111 ;; In order to support the call/return predictor, we use a return
12112 ;; instruction which the middle-end doesn't see.
12113 (define_insn "split_stack_return"
12114 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12115 UNSPECV_SPLIT_STACK_RETURN)]
12116 ""
12117 {
12118 if (operands[0] == const0_rtx)
12119 return "ret";
12120 else
12121 return "ret\t%0";
12122 }
12123 [(set_attr "atom_unit" "jeu")
12124 (set_attr "modrm" "0")
12125 (set (attr "length")
12126 (if_then_else (match_operand:SI 0 "const0_operand")
12127 (const_int 1)
12128 (const_int 3)))
12129 (set (attr "length_immediate")
12130 (if_then_else (match_operand:SI 0 "const0_operand")
12131 (const_int 0)
12132 (const_int 2)))])
12133
12134 ;; If there are operand 0 bytes available on the stack, jump to
12135 ;; operand 1.
12136
12137 (define_expand "split_stack_space_check"
12138 [(set (pc) (if_then_else
12139 (ltu (minus (reg SP_REG)
12140 (match_operand 0 "register_operand"))
12141 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12142 (label_ref (match_operand 1))
12143 (pc)))]
12144 ""
12145 {
12146 rtx reg, size, limit;
12147
12148 reg = gen_reg_rtx (Pmode);
12149 size = force_reg (Pmode, operands[0]);
12150 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12151 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12152 UNSPEC_STACK_CHECK);
12153 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12154 ix86_expand_branch (GEU, reg, limit, operands[1]);
12155
12156 DONE;
12157 })
12158 \f
12159 ;; Bit manipulation instructions.
12160
12161 (define_expand "ffs<mode>2"
12162 [(set (match_dup 2) (const_int -1))
12163 (parallel [(set (match_dup 3) (match_dup 4))
12164 (set (match_operand:SWI48 0 "register_operand")
12165 (ctz:SWI48
12166 (match_operand:SWI48 1 "nonimmediate_operand")))])
12167 (set (match_dup 0) (if_then_else:SWI48
12168 (eq (match_dup 3) (const_int 0))
12169 (match_dup 2)
12170 (match_dup 0)))
12171 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12172 (clobber (reg:CC FLAGS_REG))])]
12173 ""
12174 {
12175 enum machine_mode flags_mode;
12176
12177 if (<MODE>mode == SImode && !TARGET_CMOVE)
12178 {
12179 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12180 DONE;
12181 }
12182
12183 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12184
12185 operands[2] = gen_reg_rtx (<MODE>mode);
12186 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12187 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12188 })
12189
12190 (define_insn_and_split "ffssi2_no_cmove"
12191 [(set (match_operand:SI 0 "register_operand" "=r")
12192 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12193 (clobber (match_scratch:SI 2 "=&q"))
12194 (clobber (reg:CC FLAGS_REG))]
12195 "!TARGET_CMOVE"
12196 "#"
12197 "&& reload_completed"
12198 [(parallel [(set (match_dup 4) (match_dup 5))
12199 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12200 (set (strict_low_part (match_dup 3))
12201 (eq:QI (match_dup 4) (const_int 0)))
12202 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12203 (clobber (reg:CC FLAGS_REG))])
12204 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12205 (clobber (reg:CC FLAGS_REG))])
12206 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12207 (clobber (reg:CC FLAGS_REG))])]
12208 {
12209 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12210
12211 operands[3] = gen_lowpart (QImode, operands[2]);
12212 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12213 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12214
12215 ix86_expand_clear (operands[2]);
12216 })
12217
12218 (define_insn "*tzcnt<mode>_1"
12219 [(set (reg:CCC FLAGS_REG)
12220 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12221 (const_int 0)))
12222 (set (match_operand:SWI48 0 "register_operand" "=r")
12223 (ctz:SWI48 (match_dup 1)))]
12224 "TARGET_BMI"
12225 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12226 [(set_attr "type" "alu1")
12227 (set_attr "prefix_0f" "1")
12228 (set_attr "prefix_rep" "1")
12229 (set_attr "mode" "<MODE>")])
12230
12231 (define_insn "*bsf<mode>_1"
12232 [(set (reg:CCZ FLAGS_REG)
12233 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12234 (const_int 0)))
12235 (set (match_operand:SWI48 0 "register_operand" "=r")
12236 (ctz:SWI48 (match_dup 1)))]
12237 ""
12238 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12239 [(set_attr "type" "alu1")
12240 (set_attr "prefix_0f" "1")
12241 (set_attr "mode" "<MODE>")])
12242
12243 (define_insn "ctz<mode>2"
12244 [(set (match_operand:SWI248 0 "register_operand" "=r")
12245 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12246 (clobber (reg:CC FLAGS_REG))]
12247 ""
12248 {
12249 if (TARGET_BMI)
12250 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12251 else if (optimize_function_for_size_p (cfun))
12252 ;
12253 else if (TARGET_GENERIC)
12254 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12255 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12256
12257 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12258 }
12259 [(set_attr "type" "alu1")
12260 (set_attr "prefix_0f" "1")
12261 (set (attr "prefix_rep")
12262 (if_then_else
12263 (ior (match_test "TARGET_BMI")
12264 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12265 (match_test "TARGET_GENERIC")))
12266 (const_string "1")
12267 (const_string "0")))
12268 (set_attr "mode" "<MODE>")])
12269
12270 (define_expand "clz<mode>2"
12271 [(parallel
12272 [(set (match_operand:SWI248 0 "register_operand")
12273 (minus:SWI248
12274 (match_dup 2)
12275 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12276 (clobber (reg:CC FLAGS_REG))])
12277 (parallel
12278 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12279 (clobber (reg:CC FLAGS_REG))])]
12280 ""
12281 {
12282 if (TARGET_LZCNT)
12283 {
12284 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12285 DONE;
12286 }
12287 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12288 })
12289
12290 (define_insn "clz<mode>2_lzcnt"
12291 [(set (match_operand:SWI248 0 "register_operand" "=r")
12292 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12293 (clobber (reg:CC FLAGS_REG))]
12294 "TARGET_LZCNT"
12295 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12296 [(set_attr "prefix_rep" "1")
12297 (set_attr "type" "bitmanip")
12298 (set_attr "mode" "<MODE>")])
12299
12300 ;; BMI instructions.
12301 (define_insn "*bmi_andn_<mode>"
12302 [(set (match_operand:SWI48 0 "register_operand" "=r")
12303 (and:SWI48
12304 (not:SWI48
12305 (match_operand:SWI48 1 "register_operand" "r"))
12306 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12307 (clobber (reg:CC FLAGS_REG))]
12308 "TARGET_BMI"
12309 "andn\t{%2, %1, %0|%0, %1, %2}"
12310 [(set_attr "type" "bitmanip")
12311 (set_attr "mode" "<MODE>")])
12312
12313 (define_insn "bmi_bextr_<mode>"
12314 [(set (match_operand:SWI48 0 "register_operand" "=r")
12315 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12316 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12317 UNSPEC_BEXTR))
12318 (clobber (reg:CC FLAGS_REG))]
12319 "TARGET_BMI"
12320 "bextr\t{%2, %1, %0|%0, %1, %2}"
12321 [(set_attr "type" "bitmanip")
12322 (set_attr "mode" "<MODE>")])
12323
12324 (define_insn "*bmi_blsi_<mode>"
12325 [(set (match_operand:SWI48 0 "register_operand" "=r")
12326 (and:SWI48
12327 (neg:SWI48
12328 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12329 (match_dup 1)))
12330 (clobber (reg:CC FLAGS_REG))]
12331 "TARGET_BMI"
12332 "blsi\t{%1, %0|%0, %1}"
12333 [(set_attr "type" "bitmanip")
12334 (set_attr "mode" "<MODE>")])
12335
12336 (define_insn "*bmi_blsmsk_<mode>"
12337 [(set (match_operand:SWI48 0 "register_operand" "=r")
12338 (xor:SWI48
12339 (plus:SWI48
12340 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12341 (const_int -1))
12342 (match_dup 1)))
12343 (clobber (reg:CC FLAGS_REG))]
12344 "TARGET_BMI"
12345 "blsmsk\t{%1, %0|%0, %1}"
12346 [(set_attr "type" "bitmanip")
12347 (set_attr "mode" "<MODE>")])
12348
12349 (define_insn "*bmi_blsr_<mode>"
12350 [(set (match_operand:SWI48 0 "register_operand" "=r")
12351 (and:SWI48
12352 (plus:SWI48
12353 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12354 (const_int -1))
12355 (match_dup 1)))
12356 (clobber (reg:CC FLAGS_REG))]
12357 "TARGET_BMI"
12358 "blsr\t{%1, %0|%0, %1}"
12359 [(set_attr "type" "bitmanip")
12360 (set_attr "mode" "<MODE>")])
12361
12362 ;; BMI2 instructions.
12363 (define_insn "bmi2_bzhi_<mode>3"
12364 [(set (match_operand:SWI48 0 "register_operand" "=r")
12365 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12366 (lshiftrt:SWI48 (const_int -1)
12367 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12368 (clobber (reg:CC FLAGS_REG))]
12369 "TARGET_BMI2"
12370 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12371 [(set_attr "type" "bitmanip")
12372 (set_attr "prefix" "vex")
12373 (set_attr "mode" "<MODE>")])
12374
12375 (define_insn "bmi2_pdep_<mode>3"
12376 [(set (match_operand:SWI48 0 "register_operand" "=r")
12377 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12378 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12379 UNSPEC_PDEP))]
12380 "TARGET_BMI2"
12381 "pdep\t{%2, %1, %0|%0, %1, %2}"
12382 [(set_attr "type" "bitmanip")
12383 (set_attr "prefix" "vex")
12384 (set_attr "mode" "<MODE>")])
12385
12386 (define_insn "bmi2_pext_<mode>3"
12387 [(set (match_operand:SWI48 0 "register_operand" "=r")
12388 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12389 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12390 UNSPEC_PEXT))]
12391 "TARGET_BMI2"
12392 "pext\t{%2, %1, %0|%0, %1, %2}"
12393 [(set_attr "type" "bitmanip")
12394 (set_attr "prefix" "vex")
12395 (set_attr "mode" "<MODE>")])
12396
12397 ;; TBM instructions.
12398 (define_insn "tbm_bextri_<mode>"
12399 [(set (match_operand:SWI48 0 "register_operand" "=r")
12400 (zero_extract:SWI48
12401 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12402 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12403 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12404 (clobber (reg:CC FLAGS_REG))]
12405 "TARGET_TBM"
12406 {
12407 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12408 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12409 }
12410 [(set_attr "type" "bitmanip")
12411 (set_attr "mode" "<MODE>")])
12412
12413 (define_insn "*tbm_blcfill_<mode>"
12414 [(set (match_operand:SWI48 0 "register_operand" "=r")
12415 (and: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 "blcfill\t{%1, %0|%0, %1}"
12423 [(set_attr "type" "bitmanip")
12424 (set_attr "mode" "<MODE>")])
12425
12426 (define_insn "*tbm_blci_<mode>"
12427 [(set (match_operand:SWI48 0 "register_operand" "=r")
12428 (ior:SWI48
12429 (not:SWI48
12430 (plus:SWI48
12431 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12432 (const_int 1)))
12433 (match_dup 1)))
12434 (clobber (reg:CC FLAGS_REG))]
12435 "TARGET_TBM"
12436 "blci\t{%1, %0|%0, %1}"
12437 [(set_attr "type" "bitmanip")
12438 (set_attr "mode" "<MODE>")])
12439
12440 (define_insn "*tbm_blcic_<mode>"
12441 [(set (match_operand:SWI48 0 "register_operand" "=r")
12442 (and:SWI48
12443 (plus:SWI48
12444 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12445 (const_int 1))
12446 (not:SWI48
12447 (match_dup 1))))
12448 (clobber (reg:CC FLAGS_REG))]
12449 "TARGET_TBM"
12450 "blcic\t{%1, %0|%0, %1}"
12451 [(set_attr "type" "bitmanip")
12452 (set_attr "mode" "<MODE>")])
12453
12454 (define_insn "*tbm_blcmsk_<mode>"
12455 [(set (match_operand:SWI48 0 "register_operand" "=r")
12456 (xor:SWI48
12457 (plus:SWI48
12458 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12459 (const_int 1))
12460 (match_dup 1)))
12461 (clobber (reg:CC FLAGS_REG))]
12462 "TARGET_TBM"
12463 "blcmsk\t{%1, %0|%0, %1}"
12464 [(set_attr "type" "bitmanip")
12465 (set_attr "mode" "<MODE>")])
12466
12467 (define_insn "*tbm_blcs_<mode>"
12468 [(set (match_operand:SWI48 0 "register_operand" "=r")
12469 (ior:SWI48
12470 (plus:SWI48
12471 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12472 (const_int 1))
12473 (match_dup 1)))
12474 (clobber (reg:CC FLAGS_REG))]
12475 "TARGET_TBM"
12476 "blcs\t{%1, %0|%0, %1}"
12477 [(set_attr "type" "bitmanip")
12478 (set_attr "mode" "<MODE>")])
12479
12480 (define_insn "*tbm_blsfill_<mode>"
12481 [(set (match_operand:SWI48 0 "register_operand" "=r")
12482 (ior:SWI48
12483 (plus:SWI48
12484 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12485 (const_int -1))
12486 (match_dup 1)))
12487 (clobber (reg:CC FLAGS_REG))]
12488 "TARGET_TBM"
12489 "blsfill\t{%1, %0|%0, %1}"
12490 [(set_attr "type" "bitmanip")
12491 (set_attr "mode" "<MODE>")])
12492
12493 (define_insn "*tbm_blsic_<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 "blsic\t{%1, %0|%0, %1}"
12504 [(set_attr "type" "bitmanip")
12505 (set_attr "mode" "<MODE>")])
12506
12507 (define_insn "*tbm_t1mskc_<mode>"
12508 [(set (match_operand:SWI48 0 "register_operand" "=r")
12509 (ior: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 "t1mskc\t{%1, %0|%0, %1}"
12518 [(set_attr "type" "bitmanip")
12519 (set_attr "mode" "<MODE>")])
12520
12521 (define_insn "*tbm_tzmsk_<mode>"
12522 [(set (match_operand:SWI48 0 "register_operand" "=r")
12523 (and:SWI48
12524 (plus:SWI48
12525 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12526 (const_int -1))
12527 (not:SWI48
12528 (match_dup 1))))
12529 (clobber (reg:CC FLAGS_REG))]
12530 "TARGET_TBM"
12531 "tzmsk\t{%1, %0|%0, %1}"
12532 [(set_attr "type" "bitmanip")
12533 (set_attr "mode" "<MODE>")])
12534
12535 (define_insn "bsr_rex64"
12536 [(set (match_operand:DI 0 "register_operand" "=r")
12537 (minus:DI (const_int 63)
12538 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12539 (clobber (reg:CC FLAGS_REG))]
12540 "TARGET_64BIT"
12541 "bsr{q}\t{%1, %0|%0, %1}"
12542 [(set_attr "type" "alu1")
12543 (set_attr "prefix_0f" "1")
12544 (set_attr "mode" "DI")])
12545
12546 (define_insn "bsr"
12547 [(set (match_operand:SI 0 "register_operand" "=r")
12548 (minus:SI (const_int 31)
12549 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12550 (clobber (reg:CC FLAGS_REG))]
12551 ""
12552 "bsr{l}\t{%1, %0|%0, %1}"
12553 [(set_attr "type" "alu1")
12554 (set_attr "prefix_0f" "1")
12555 (set_attr "mode" "SI")])
12556
12557 (define_insn "*bsrhi"
12558 [(set (match_operand:HI 0 "register_operand" "=r")
12559 (minus:HI (const_int 15)
12560 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12561 (clobber (reg:CC FLAGS_REG))]
12562 ""
12563 "bsr{w}\t{%1, %0|%0, %1}"
12564 [(set_attr "type" "alu1")
12565 (set_attr "prefix_0f" "1")
12566 (set_attr "mode" "HI")])
12567
12568 (define_insn "popcount<mode>2"
12569 [(set (match_operand:SWI248 0 "register_operand" "=r")
12570 (popcount:SWI248
12571 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12572 (clobber (reg:CC FLAGS_REG))]
12573 "TARGET_POPCNT"
12574 {
12575 #if TARGET_MACHO
12576 return "popcnt\t{%1, %0|%0, %1}";
12577 #else
12578 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12579 #endif
12580 }
12581 [(set_attr "prefix_rep" "1")
12582 (set_attr "type" "bitmanip")
12583 (set_attr "mode" "<MODE>")])
12584
12585 (define_insn "*popcount<mode>2_cmp"
12586 [(set (reg FLAGS_REG)
12587 (compare
12588 (popcount:SWI248
12589 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12590 (const_int 0)))
12591 (set (match_operand:SWI248 0 "register_operand" "=r")
12592 (popcount:SWI248 (match_dup 1)))]
12593 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12594 {
12595 #if TARGET_MACHO
12596 return "popcnt\t{%1, %0|%0, %1}";
12597 #else
12598 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12599 #endif
12600 }
12601 [(set_attr "prefix_rep" "1")
12602 (set_attr "type" "bitmanip")
12603 (set_attr "mode" "<MODE>")])
12604
12605 (define_insn "*popcountsi2_cmp_zext"
12606 [(set (reg FLAGS_REG)
12607 (compare
12608 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12609 (const_int 0)))
12610 (set (match_operand:DI 0 "register_operand" "=r")
12611 (zero_extend:DI(popcount:SI (match_dup 1))))]
12612 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12613 {
12614 #if TARGET_MACHO
12615 return "popcnt\t{%1, %0|%0, %1}";
12616 #else
12617 return "popcnt{l}\t{%1, %0|%0, %1}";
12618 #endif
12619 }
12620 [(set_attr "prefix_rep" "1")
12621 (set_attr "type" "bitmanip")
12622 (set_attr "mode" "SI")])
12623
12624 (define_expand "bswapdi2"
12625 [(set (match_operand:DI 0 "register_operand")
12626 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12627 ""
12628 {
12629 if (TARGET_64BIT && !TARGET_MOVBE)
12630 operands[1] = force_reg (DImode, operands[1]);
12631 })
12632
12633 (define_insn_and_split "*bswapdi2_doubleword"
12634 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12635 (bswap:DI
12636 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12637 "!TARGET_64BIT
12638 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12639 "#"
12640 "&& reload_completed"
12641 [(set (match_dup 2)
12642 (bswap:SI (match_dup 1)))
12643 (set (match_dup 0)
12644 (bswap:SI (match_dup 3)))]
12645 {
12646 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12647
12648 if (REG_P (operands[0]) && REG_P (operands[1]))
12649 {
12650 emit_insn (gen_swapsi (operands[0], operands[2]));
12651 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12652 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12653 DONE;
12654 }
12655
12656 if (!TARGET_MOVBE)
12657 {
12658 if (MEM_P (operands[0]))
12659 {
12660 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12661 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12662
12663 emit_move_insn (operands[0], operands[3]);
12664 emit_move_insn (operands[2], operands[1]);
12665 }
12666 if (MEM_P (operands[1]))
12667 {
12668 emit_move_insn (operands[2], operands[1]);
12669 emit_move_insn (operands[0], operands[3]);
12670
12671 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12672 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12673 }
12674 DONE;
12675 }
12676 })
12677
12678 (define_expand "bswapsi2"
12679 [(set (match_operand:SI 0 "register_operand")
12680 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12681 ""
12682 {
12683 if (TARGET_MOVBE)
12684 ;
12685 else if (TARGET_BSWAP)
12686 operands[1] = force_reg (SImode, operands[1]);
12687 else
12688 {
12689 rtx x = operands[0];
12690
12691 emit_move_insn (x, operands[1]);
12692 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12693 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12694 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12695 DONE;
12696 }
12697 })
12698
12699 (define_insn "*bswap<mode>2_movbe"
12700 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12701 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12702 "TARGET_MOVBE
12703 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12704 "@
12705 bswap\t%0
12706 movbe\t{%1, %0|%0, %1}
12707 movbe\t{%1, %0|%0, %1}"
12708 [(set_attr "type" "bitmanip,imov,imov")
12709 (set_attr "modrm" "0,1,1")
12710 (set_attr "prefix_0f" "*,1,1")
12711 (set_attr "prefix_extra" "*,1,1")
12712 (set_attr "mode" "<MODE>")])
12713
12714 (define_insn "*bswap<mode>2"
12715 [(set (match_operand:SWI48 0 "register_operand" "=r")
12716 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12717 "TARGET_BSWAP"
12718 "bswap\t%0"
12719 [(set_attr "type" "bitmanip")
12720 (set_attr "modrm" "0")
12721 (set_attr "mode" "<MODE>")])
12722
12723 (define_insn "*bswaphi_lowpart_1"
12724 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12725 (bswap:HI (match_dup 0)))
12726 (clobber (reg:CC FLAGS_REG))]
12727 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12728 "@
12729 xchg{b}\t{%h0, %b0|%b0, %h0}
12730 rol{w}\t{$8, %0|%0, 8}"
12731 [(set_attr "length" "2,4")
12732 (set_attr "mode" "QI,HI")])
12733
12734 (define_insn "bswaphi_lowpart"
12735 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12736 (bswap:HI (match_dup 0)))
12737 (clobber (reg:CC FLAGS_REG))]
12738 ""
12739 "rol{w}\t{$8, %0|%0, 8}"
12740 [(set_attr "length" "4")
12741 (set_attr "mode" "HI")])
12742
12743 (define_expand "paritydi2"
12744 [(set (match_operand:DI 0 "register_operand")
12745 (parity:DI (match_operand:DI 1 "register_operand")))]
12746 "! TARGET_POPCNT"
12747 {
12748 rtx scratch = gen_reg_rtx (QImode);
12749 rtx cond;
12750
12751 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12752 NULL_RTX, operands[1]));
12753
12754 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12755 gen_rtx_REG (CCmode, FLAGS_REG),
12756 const0_rtx);
12757 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12758
12759 if (TARGET_64BIT)
12760 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12761 else
12762 {
12763 rtx tmp = gen_reg_rtx (SImode);
12764
12765 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12766 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12767 }
12768 DONE;
12769 })
12770
12771 (define_expand "paritysi2"
12772 [(set (match_operand:SI 0 "register_operand")
12773 (parity:SI (match_operand:SI 1 "register_operand")))]
12774 "! TARGET_POPCNT"
12775 {
12776 rtx scratch = gen_reg_rtx (QImode);
12777 rtx cond;
12778
12779 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12780
12781 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12782 gen_rtx_REG (CCmode, FLAGS_REG),
12783 const0_rtx);
12784 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12785
12786 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12787 DONE;
12788 })
12789
12790 (define_insn_and_split "paritydi2_cmp"
12791 [(set (reg:CC FLAGS_REG)
12792 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12793 UNSPEC_PARITY))
12794 (clobber (match_scratch:DI 0 "=r"))
12795 (clobber (match_scratch:SI 1 "=&r"))
12796 (clobber (match_scratch:HI 2 "=Q"))]
12797 "! TARGET_POPCNT"
12798 "#"
12799 "&& reload_completed"
12800 [(parallel
12801 [(set (match_dup 1)
12802 (xor:SI (match_dup 1) (match_dup 4)))
12803 (clobber (reg:CC FLAGS_REG))])
12804 (parallel
12805 [(set (reg:CC FLAGS_REG)
12806 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12807 (clobber (match_dup 1))
12808 (clobber (match_dup 2))])]
12809 {
12810 operands[4] = gen_lowpart (SImode, operands[3]);
12811
12812 if (TARGET_64BIT)
12813 {
12814 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12815 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12816 }
12817 else
12818 operands[1] = gen_highpart (SImode, operands[3]);
12819 })
12820
12821 (define_insn_and_split "paritysi2_cmp"
12822 [(set (reg:CC FLAGS_REG)
12823 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12824 UNSPEC_PARITY))
12825 (clobber (match_scratch:SI 0 "=r"))
12826 (clobber (match_scratch:HI 1 "=&Q"))]
12827 "! TARGET_POPCNT"
12828 "#"
12829 "&& reload_completed"
12830 [(parallel
12831 [(set (match_dup 1)
12832 (xor:HI (match_dup 1) (match_dup 3)))
12833 (clobber (reg:CC FLAGS_REG))])
12834 (parallel
12835 [(set (reg:CC FLAGS_REG)
12836 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12837 (clobber (match_dup 1))])]
12838 {
12839 operands[3] = gen_lowpart (HImode, operands[2]);
12840
12841 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12842 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12843 })
12844
12845 (define_insn "*parityhi2_cmp"
12846 [(set (reg:CC FLAGS_REG)
12847 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12848 UNSPEC_PARITY))
12849 (clobber (match_scratch:HI 0 "=Q"))]
12850 "! TARGET_POPCNT"
12851 "xor{b}\t{%h0, %b0|%b0, %h0}"
12852 [(set_attr "length" "2")
12853 (set_attr "mode" "HI")])
12854
12855 \f
12856 ;; Thread-local storage patterns for ELF.
12857 ;;
12858 ;; Note that these code sequences must appear exactly as shown
12859 ;; in order to allow linker relaxation.
12860
12861 (define_insn "*tls_global_dynamic_32_gnu"
12862 [(set (match_operand:SI 0 "register_operand" "=a")
12863 (unspec:SI
12864 [(match_operand:SI 1 "register_operand" "b")
12865 (match_operand 2 "tls_symbolic_operand")
12866 (match_operand 3 "constant_call_address_operand" "z")]
12867 UNSPEC_TLS_GD))
12868 (clobber (match_scratch:SI 4 "=d"))
12869 (clobber (match_scratch:SI 5 "=c"))
12870 (clobber (reg:CC FLAGS_REG))]
12871 "!TARGET_64BIT && TARGET_GNU_TLS"
12872 {
12873 output_asm_insn
12874 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12875 if (TARGET_SUN_TLS)
12876 #ifdef HAVE_AS_IX86_TLSGDPLT
12877 return "call\t%a2@tlsgdplt";
12878 #else
12879 return "call\t%p3@plt";
12880 #endif
12881 return "call\t%P3";
12882 }
12883 [(set_attr "type" "multi")
12884 (set_attr "length" "12")])
12885
12886 (define_expand "tls_global_dynamic_32"
12887 [(parallel
12888 [(set (match_operand:SI 0 "register_operand")
12889 (unspec:SI [(match_operand:SI 2 "register_operand")
12890 (match_operand 1 "tls_symbolic_operand")
12891 (match_operand 3 "constant_call_address_operand")]
12892 UNSPEC_TLS_GD))
12893 (clobber (match_scratch:SI 4))
12894 (clobber (match_scratch:SI 5))
12895 (clobber (reg:CC FLAGS_REG))])])
12896
12897 (define_insn "*tls_global_dynamic_64_<mode>"
12898 [(set (match_operand:P 0 "register_operand" "=a")
12899 (call:P
12900 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12901 (match_operand 3)))
12902 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12903 UNSPEC_TLS_GD)]
12904 "TARGET_64BIT"
12905 {
12906 if (!TARGET_X32)
12907 fputs (ASM_BYTE "0x66\n", asm_out_file);
12908 output_asm_insn
12909 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12910 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12911 fputs ("\trex64\n", asm_out_file);
12912 if (TARGET_SUN_TLS)
12913 return "call\t%p2@plt";
12914 return "call\t%P2";
12915 }
12916 [(set_attr "type" "multi")
12917 (set (attr "length")
12918 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12919
12920 (define_expand "tls_global_dynamic_64_<mode>"
12921 [(parallel
12922 [(set (match_operand:P 0 "register_operand")
12923 (call:P
12924 (mem:QI (match_operand 2 "constant_call_address_operand"))
12925 (const_int 0)))
12926 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12927 UNSPEC_TLS_GD)])]
12928 "TARGET_64BIT")
12929
12930 (define_insn "*tls_local_dynamic_base_32_gnu"
12931 [(set (match_operand:SI 0 "register_operand" "=a")
12932 (unspec:SI
12933 [(match_operand:SI 1 "register_operand" "b")
12934 (match_operand 2 "constant_call_address_operand" "z")]
12935 UNSPEC_TLS_LD_BASE))
12936 (clobber (match_scratch:SI 3 "=d"))
12937 (clobber (match_scratch:SI 4 "=c"))
12938 (clobber (reg:CC FLAGS_REG))]
12939 "!TARGET_64BIT && TARGET_GNU_TLS"
12940 {
12941 output_asm_insn
12942 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12943 if (TARGET_SUN_TLS)
12944 #ifdef HAVE_AS_IX86_TLSLDMPLT
12945 return "call\t%&@tlsldmplt";
12946 #else
12947 return "call\t%p2@plt";
12948 #endif
12949 return "call\t%P2";
12950 }
12951 [(set_attr "type" "multi")
12952 (set_attr "length" "11")])
12953
12954 (define_expand "tls_local_dynamic_base_32"
12955 [(parallel
12956 [(set (match_operand:SI 0 "register_operand")
12957 (unspec:SI
12958 [(match_operand:SI 1 "register_operand")
12959 (match_operand 2 "constant_call_address_operand")]
12960 UNSPEC_TLS_LD_BASE))
12961 (clobber (match_scratch:SI 3))
12962 (clobber (match_scratch:SI 4))
12963 (clobber (reg:CC FLAGS_REG))])])
12964
12965 (define_insn "*tls_local_dynamic_base_64_<mode>"
12966 [(set (match_operand:P 0 "register_operand" "=a")
12967 (call:P
12968 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12969 (match_operand 2)))
12970 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12971 "TARGET_64BIT"
12972 {
12973 output_asm_insn
12974 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12975 if (TARGET_SUN_TLS)
12976 return "call\t%p1@plt";
12977 return "call\t%P1";
12978 }
12979 [(set_attr "type" "multi")
12980 (set_attr "length" "12")])
12981
12982 (define_expand "tls_local_dynamic_base_64_<mode>"
12983 [(parallel
12984 [(set (match_operand:P 0 "register_operand")
12985 (call:P
12986 (mem:QI (match_operand 1 "constant_call_address_operand"))
12987 (const_int 0)))
12988 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12989 "TARGET_64BIT")
12990
12991 ;; Local dynamic of a single variable is a lose. Show combine how
12992 ;; to convert that back to global dynamic.
12993
12994 (define_insn_and_split "*tls_local_dynamic_32_once"
12995 [(set (match_operand:SI 0 "register_operand" "=a")
12996 (plus:SI
12997 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12998 (match_operand 2 "constant_call_address_operand" "z")]
12999 UNSPEC_TLS_LD_BASE)
13000 (const:SI (unspec:SI
13001 [(match_operand 3 "tls_symbolic_operand")]
13002 UNSPEC_DTPOFF))))
13003 (clobber (match_scratch:SI 4 "=d"))
13004 (clobber (match_scratch:SI 5 "=c"))
13005 (clobber (reg:CC FLAGS_REG))]
13006 ""
13007 "#"
13008 ""
13009 [(parallel
13010 [(set (match_dup 0)
13011 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13012 UNSPEC_TLS_GD))
13013 (clobber (match_dup 4))
13014 (clobber (match_dup 5))
13015 (clobber (reg:CC FLAGS_REG))])])
13016
13017 ;; Segment register for the thread base ptr load
13018 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13019
13020 ;; Load and add the thread base pointer from %<tp_seg>:0.
13021 (define_insn "*load_tp_x32"
13022 [(set (match_operand:SI 0 "register_operand" "=r")
13023 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13024 "TARGET_X32"
13025 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13026 [(set_attr "type" "imov")
13027 (set_attr "modrm" "0")
13028 (set_attr "length" "7")
13029 (set_attr "memory" "load")
13030 (set_attr "imm_disp" "false")])
13031
13032 (define_insn "*load_tp_x32_zext"
13033 [(set (match_operand:DI 0 "register_operand" "=r")
13034 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13035 "TARGET_X32"
13036 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13037 [(set_attr "type" "imov")
13038 (set_attr "modrm" "0")
13039 (set_attr "length" "7")
13040 (set_attr "memory" "load")
13041 (set_attr "imm_disp" "false")])
13042
13043 (define_insn "*load_tp_<mode>"
13044 [(set (match_operand:P 0 "register_operand" "=r")
13045 (unspec:P [(const_int 0)] UNSPEC_TP))]
13046 "!TARGET_X32"
13047 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13048 [(set_attr "type" "imov")
13049 (set_attr "modrm" "0")
13050 (set_attr "length" "7")
13051 (set_attr "memory" "load")
13052 (set_attr "imm_disp" "false")])
13053
13054 (define_insn "*add_tp_x32"
13055 [(set (match_operand:SI 0 "register_operand" "=r")
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, %0|%0, 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_x32_zext"
13068 [(set (match_operand:DI 0 "register_operand" "=r")
13069 (zero_extend:DI
13070 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13071 (match_operand:SI 1 "register_operand" "0"))))
13072 (clobber (reg:CC FLAGS_REG))]
13073 "TARGET_X32"
13074 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13075 [(set_attr "type" "alu")
13076 (set_attr "modrm" "0")
13077 (set_attr "length" "7")
13078 (set_attr "memory" "load")
13079 (set_attr "imm_disp" "false")])
13080
13081 (define_insn "*add_tp_<mode>"
13082 [(set (match_operand:P 0 "register_operand" "=r")
13083 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13084 (match_operand:P 1 "register_operand" "0")))
13085 (clobber (reg:CC FLAGS_REG))]
13086 "!TARGET_X32"
13087 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13088 [(set_attr "type" "alu")
13089 (set_attr "modrm" "0")
13090 (set_attr "length" "7")
13091 (set_attr "memory" "load")
13092 (set_attr "imm_disp" "false")])
13093
13094 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13095 ;; %rax as destination of the initial executable code sequence.
13096 (define_insn "tls_initial_exec_64_sun"
13097 [(set (match_operand:DI 0 "register_operand" "=a")
13098 (unspec:DI
13099 [(match_operand 1 "tls_symbolic_operand")]
13100 UNSPEC_TLS_IE_SUN))
13101 (clobber (reg:CC FLAGS_REG))]
13102 "TARGET_64BIT && TARGET_SUN_TLS"
13103 {
13104 output_asm_insn
13105 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13106 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13107 }
13108 [(set_attr "type" "multi")])
13109
13110 ;; GNU2 TLS patterns can be split.
13111
13112 (define_expand "tls_dynamic_gnu2_32"
13113 [(set (match_dup 3)
13114 (plus:SI (match_operand:SI 2 "register_operand")
13115 (const:SI
13116 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13117 UNSPEC_TLSDESC))))
13118 (parallel
13119 [(set (match_operand:SI 0 "register_operand")
13120 (unspec:SI [(match_dup 1) (match_dup 3)
13121 (match_dup 2) (reg:SI SP_REG)]
13122 UNSPEC_TLSDESC))
13123 (clobber (reg:CC FLAGS_REG))])]
13124 "!TARGET_64BIT && TARGET_GNU2_TLS"
13125 {
13126 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13127 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13128 })
13129
13130 (define_insn "*tls_dynamic_gnu2_lea_32"
13131 [(set (match_operand:SI 0 "register_operand" "=r")
13132 (plus:SI (match_operand:SI 1 "register_operand" "b")
13133 (const:SI
13134 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13135 UNSPEC_TLSDESC))))]
13136 "!TARGET_64BIT && TARGET_GNU2_TLS"
13137 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13138 [(set_attr "type" "lea")
13139 (set_attr "mode" "SI")
13140 (set_attr "length" "6")
13141 (set_attr "length_address" "4")])
13142
13143 (define_insn "*tls_dynamic_gnu2_call_32"
13144 [(set (match_operand:SI 0 "register_operand" "=a")
13145 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13146 (match_operand:SI 2 "register_operand" "0")
13147 ;; we have to make sure %ebx still points to the GOT
13148 (match_operand:SI 3 "register_operand" "b")
13149 (reg:SI SP_REG)]
13150 UNSPEC_TLSDESC))
13151 (clobber (reg:CC FLAGS_REG))]
13152 "!TARGET_64BIT && TARGET_GNU2_TLS"
13153 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13154 [(set_attr "type" "call")
13155 (set_attr "length" "2")
13156 (set_attr "length_address" "0")])
13157
13158 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13159 [(set (match_operand:SI 0 "register_operand" "=&a")
13160 (plus:SI
13161 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13162 (match_operand:SI 4)
13163 (match_operand:SI 2 "register_operand" "b")
13164 (reg:SI SP_REG)]
13165 UNSPEC_TLSDESC)
13166 (const:SI (unspec:SI
13167 [(match_operand 1 "tls_symbolic_operand")]
13168 UNSPEC_DTPOFF))))
13169 (clobber (reg:CC FLAGS_REG))]
13170 "!TARGET_64BIT && TARGET_GNU2_TLS"
13171 "#"
13172 ""
13173 [(set (match_dup 0) (match_dup 5))]
13174 {
13175 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13176 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13177 })
13178
13179 (define_expand "tls_dynamic_gnu2_64"
13180 [(set (match_dup 2)
13181 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13182 UNSPEC_TLSDESC))
13183 (parallel
13184 [(set (match_operand:DI 0 "register_operand")
13185 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13186 UNSPEC_TLSDESC))
13187 (clobber (reg:CC FLAGS_REG))])]
13188 "TARGET_64BIT && TARGET_GNU2_TLS"
13189 {
13190 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13191 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13192 })
13193
13194 (define_insn "*tls_dynamic_gnu2_lea_64"
13195 [(set (match_operand:DI 0 "register_operand" "=r")
13196 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13197 UNSPEC_TLSDESC))]
13198 "TARGET_64BIT && TARGET_GNU2_TLS"
13199 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13200 [(set_attr "type" "lea")
13201 (set_attr "mode" "DI")
13202 (set_attr "length" "7")
13203 (set_attr "length_address" "4")])
13204
13205 (define_insn "*tls_dynamic_gnu2_call_64"
13206 [(set (match_operand:DI 0 "register_operand" "=a")
13207 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13208 (match_operand:DI 2 "register_operand" "0")
13209 (reg:DI SP_REG)]
13210 UNSPEC_TLSDESC))
13211 (clobber (reg:CC FLAGS_REG))]
13212 "TARGET_64BIT && TARGET_GNU2_TLS"
13213 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13214 [(set_attr "type" "call")
13215 (set_attr "length" "2")
13216 (set_attr "length_address" "0")])
13217
13218 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13219 [(set (match_operand:DI 0 "register_operand" "=&a")
13220 (plus:DI
13221 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13222 (match_operand:DI 3)
13223 (reg:DI SP_REG)]
13224 UNSPEC_TLSDESC)
13225 (const:DI (unspec:DI
13226 [(match_operand 1 "tls_symbolic_operand")]
13227 UNSPEC_DTPOFF))))
13228 (clobber (reg:CC FLAGS_REG))]
13229 "TARGET_64BIT && TARGET_GNU2_TLS"
13230 "#"
13231 ""
13232 [(set (match_dup 0) (match_dup 4))]
13233 {
13234 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13235 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13236 })
13237 \f
13238 ;; These patterns match the binary 387 instructions for addM3, subM3,
13239 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13240 ;; SFmode. The first is the normal insn, the second the same insn but
13241 ;; with one operand a conversion, and the third the same insn but with
13242 ;; the other operand a conversion. The conversion may be SFmode or
13243 ;; SImode if the target mode DFmode, but only SImode if the target mode
13244 ;; is SFmode.
13245
13246 ;; Gcc is slightly more smart about handling normal two address instructions
13247 ;; so use special patterns for add and mull.
13248
13249 (define_insn "*fop_<mode>_comm_mixed"
13250 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13251 (match_operator:MODEF 3 "binary_fp_operator"
13252 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13253 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13254 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13255 && COMMUTATIVE_ARITH_P (operands[3])
13256 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13257 "* return output_387_binary_op (insn, operands);"
13258 [(set (attr "type")
13259 (if_then_else (eq_attr "alternative" "1,2")
13260 (if_then_else (match_operand:MODEF 3 "mult_operator")
13261 (const_string "ssemul")
13262 (const_string "sseadd"))
13263 (if_then_else (match_operand:MODEF 3 "mult_operator")
13264 (const_string "fmul")
13265 (const_string "fop"))))
13266 (set_attr "isa" "*,noavx,avx")
13267 (set_attr "prefix" "orig,orig,vex")
13268 (set_attr "mode" "<MODE>")])
13269
13270 (define_insn "*fop_<mode>_comm_sse"
13271 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13272 (match_operator:MODEF 3 "binary_fp_operator"
13273 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13274 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13275 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13276 && COMMUTATIVE_ARITH_P (operands[3])
13277 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13278 "* return output_387_binary_op (insn, operands);"
13279 [(set (attr "type")
13280 (if_then_else (match_operand:MODEF 3 "mult_operator")
13281 (const_string "ssemul")
13282 (const_string "sseadd")))
13283 (set_attr "isa" "noavx,avx")
13284 (set_attr "prefix" "orig,vex")
13285 (set_attr "mode" "<MODE>")])
13286
13287 (define_insn "*fop_<mode>_comm_i387"
13288 [(set (match_operand:MODEF 0 "register_operand" "=f")
13289 (match_operator:MODEF 3 "binary_fp_operator"
13290 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13291 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13292 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13293 && COMMUTATIVE_ARITH_P (operands[3])
13294 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13295 "* return output_387_binary_op (insn, operands);"
13296 [(set (attr "type")
13297 (if_then_else (match_operand:MODEF 3 "mult_operator")
13298 (const_string "fmul")
13299 (const_string "fop")))
13300 (set_attr "mode" "<MODE>")])
13301
13302 (define_insn "*fop_<mode>_1_mixed"
13303 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13304 (match_operator:MODEF 3 "binary_fp_operator"
13305 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13306 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13307 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13308 && !COMMUTATIVE_ARITH_P (operands[3])
13309 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13310 "* return output_387_binary_op (insn, operands);"
13311 [(set (attr "type")
13312 (cond [(and (eq_attr "alternative" "2,3")
13313 (match_operand:MODEF 3 "mult_operator"))
13314 (const_string "ssemul")
13315 (and (eq_attr "alternative" "2,3")
13316 (match_operand:MODEF 3 "div_operator"))
13317 (const_string "ssediv")
13318 (eq_attr "alternative" "2,3")
13319 (const_string "sseadd")
13320 (match_operand:MODEF 3 "mult_operator")
13321 (const_string "fmul")
13322 (match_operand:MODEF 3 "div_operator")
13323 (const_string "fdiv")
13324 ]
13325 (const_string "fop")))
13326 (set_attr "isa" "*,*,noavx,avx")
13327 (set_attr "prefix" "orig,orig,orig,vex")
13328 (set_attr "mode" "<MODE>")])
13329
13330 (define_insn "*rcpsf2_sse"
13331 [(set (match_operand:SF 0 "register_operand" "=x")
13332 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13333 UNSPEC_RCP))]
13334 "TARGET_SSE_MATH"
13335 "%vrcpss\t{%1, %d0|%d0, %1}"
13336 [(set_attr "type" "sse")
13337 (set_attr "atom_sse_attr" "rcp")
13338 (set_attr "prefix" "maybe_vex")
13339 (set_attr "mode" "SF")])
13340
13341 (define_insn "*fop_<mode>_1_sse"
13342 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13343 (match_operator:MODEF 3 "binary_fp_operator"
13344 [(match_operand:MODEF 1 "register_operand" "0,x")
13345 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13346 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13347 && !COMMUTATIVE_ARITH_P (operands[3])"
13348 "* return output_387_binary_op (insn, operands);"
13349 [(set (attr "type")
13350 (cond [(match_operand:MODEF 3 "mult_operator")
13351 (const_string "ssemul")
13352 (match_operand:MODEF 3 "div_operator")
13353 (const_string "ssediv")
13354 ]
13355 (const_string "sseadd")))
13356 (set_attr "isa" "noavx,avx")
13357 (set_attr "prefix" "orig,vex")
13358 (set_attr "mode" "<MODE>")])
13359
13360 ;; This pattern is not fully shadowed by the pattern above.
13361 (define_insn "*fop_<mode>_1_i387"
13362 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13363 (match_operator:MODEF 3 "binary_fp_operator"
13364 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13365 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13366 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13367 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13368 && !COMMUTATIVE_ARITH_P (operands[3])
13369 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13370 "* return output_387_binary_op (insn, operands);"
13371 [(set (attr "type")
13372 (cond [(match_operand:MODEF 3 "mult_operator")
13373 (const_string "fmul")
13374 (match_operand:MODEF 3 "div_operator")
13375 (const_string "fdiv")
13376 ]
13377 (const_string "fop")))
13378 (set_attr "mode" "<MODE>")])
13379
13380 ;; ??? Add SSE splitters for these!
13381 (define_insn "*fop_<MODEF:mode>_2_i387"
13382 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13383 (match_operator:MODEF 3 "binary_fp_operator"
13384 [(float:MODEF
13385 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13386 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13387 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13388 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13389 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13390 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13391 [(set (attr "type")
13392 (cond [(match_operand:MODEF 3 "mult_operator")
13393 (const_string "fmul")
13394 (match_operand:MODEF 3 "div_operator")
13395 (const_string "fdiv")
13396 ]
13397 (const_string "fop")))
13398 (set_attr "fp_int_src" "true")
13399 (set_attr "mode" "<SWI24:MODE>")])
13400
13401 (define_insn "*fop_<MODEF:mode>_3_i387"
13402 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13403 (match_operator:MODEF 3 "binary_fp_operator"
13404 [(match_operand:MODEF 1 "register_operand" "0,0")
13405 (float:MODEF
13406 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13407 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13408 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13409 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13410 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13411 [(set (attr "type")
13412 (cond [(match_operand:MODEF 3 "mult_operator")
13413 (const_string "fmul")
13414 (match_operand:MODEF 3 "div_operator")
13415 (const_string "fdiv")
13416 ]
13417 (const_string "fop")))
13418 (set_attr "fp_int_src" "true")
13419 (set_attr "mode" "<MODE>")])
13420
13421 (define_insn "*fop_df_4_i387"
13422 [(set (match_operand:DF 0 "register_operand" "=f,f")
13423 (match_operator:DF 3 "binary_fp_operator"
13424 [(float_extend:DF
13425 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13426 (match_operand:DF 2 "register_operand" "0,f")]))]
13427 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13428 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13429 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13430 "* return output_387_binary_op (insn, operands);"
13431 [(set (attr "type")
13432 (cond [(match_operand:DF 3 "mult_operator")
13433 (const_string "fmul")
13434 (match_operand:DF 3 "div_operator")
13435 (const_string "fdiv")
13436 ]
13437 (const_string "fop")))
13438 (set_attr "mode" "SF")])
13439
13440 (define_insn "*fop_df_5_i387"
13441 [(set (match_operand:DF 0 "register_operand" "=f,f")
13442 (match_operator:DF 3 "binary_fp_operator"
13443 [(match_operand:DF 1 "register_operand" "0,f")
13444 (float_extend:DF
13445 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13446 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13447 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13448 "* return output_387_binary_op (insn, operands);"
13449 [(set (attr "type")
13450 (cond [(match_operand:DF 3 "mult_operator")
13451 (const_string "fmul")
13452 (match_operand:DF 3 "div_operator")
13453 (const_string "fdiv")
13454 ]
13455 (const_string "fop")))
13456 (set_attr "mode" "SF")])
13457
13458 (define_insn "*fop_df_6_i387"
13459 [(set (match_operand:DF 0 "register_operand" "=f,f")
13460 (match_operator:DF 3 "binary_fp_operator"
13461 [(float_extend:DF
13462 (match_operand:SF 1 "register_operand" "0,f"))
13463 (float_extend:DF
13464 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13465 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13466 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13467 "* return output_387_binary_op (insn, operands);"
13468 [(set (attr "type")
13469 (cond [(match_operand:DF 3 "mult_operator")
13470 (const_string "fmul")
13471 (match_operand:DF 3 "div_operator")
13472 (const_string "fdiv")
13473 ]
13474 (const_string "fop")))
13475 (set_attr "mode" "SF")])
13476
13477 (define_insn "*fop_xf_comm_i387"
13478 [(set (match_operand:XF 0 "register_operand" "=f")
13479 (match_operator:XF 3 "binary_fp_operator"
13480 [(match_operand:XF 1 "register_operand" "%0")
13481 (match_operand:XF 2 "register_operand" "f")]))]
13482 "TARGET_80387
13483 && COMMUTATIVE_ARITH_P (operands[3])"
13484 "* return output_387_binary_op (insn, operands);"
13485 [(set (attr "type")
13486 (if_then_else (match_operand:XF 3 "mult_operator")
13487 (const_string "fmul")
13488 (const_string "fop")))
13489 (set_attr "mode" "XF")])
13490
13491 (define_insn "*fop_xf_1_i387"
13492 [(set (match_operand:XF 0 "register_operand" "=f,f")
13493 (match_operator:XF 3 "binary_fp_operator"
13494 [(match_operand:XF 1 "register_operand" "0,f")
13495 (match_operand:XF 2 "register_operand" "f,0")]))]
13496 "TARGET_80387
13497 && !COMMUTATIVE_ARITH_P (operands[3])"
13498 "* return output_387_binary_op (insn, operands);"
13499 [(set (attr "type")
13500 (cond [(match_operand:XF 3 "mult_operator")
13501 (const_string "fmul")
13502 (match_operand:XF 3 "div_operator")
13503 (const_string "fdiv")
13504 ]
13505 (const_string "fop")))
13506 (set_attr "mode" "XF")])
13507
13508 (define_insn "*fop_xf_2_i387"
13509 [(set (match_operand:XF 0 "register_operand" "=f,f")
13510 (match_operator:XF 3 "binary_fp_operator"
13511 [(float:XF
13512 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13513 (match_operand:XF 2 "register_operand" "0,0")]))]
13514 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13515 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13516 [(set (attr "type")
13517 (cond [(match_operand:XF 3 "mult_operator")
13518 (const_string "fmul")
13519 (match_operand:XF 3 "div_operator")
13520 (const_string "fdiv")
13521 ]
13522 (const_string "fop")))
13523 (set_attr "fp_int_src" "true")
13524 (set_attr "mode" "<MODE>")])
13525
13526 (define_insn "*fop_xf_3_i387"
13527 [(set (match_operand:XF 0 "register_operand" "=f,f")
13528 (match_operator:XF 3 "binary_fp_operator"
13529 [(match_operand:XF 1 "register_operand" "0,0")
13530 (float:XF
13531 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13532 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13533 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13534 [(set (attr "type")
13535 (cond [(match_operand:XF 3 "mult_operator")
13536 (const_string "fmul")
13537 (match_operand:XF 3 "div_operator")
13538 (const_string "fdiv")
13539 ]
13540 (const_string "fop")))
13541 (set_attr "fp_int_src" "true")
13542 (set_attr "mode" "<MODE>")])
13543
13544 (define_insn "*fop_xf_4_i387"
13545 [(set (match_operand:XF 0 "register_operand" "=f,f")
13546 (match_operator:XF 3 "binary_fp_operator"
13547 [(float_extend:XF
13548 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13549 (match_operand:XF 2 "register_operand" "0,f")]))]
13550 "TARGET_80387"
13551 "* return output_387_binary_op (insn, operands);"
13552 [(set (attr "type")
13553 (cond [(match_operand:XF 3 "mult_operator")
13554 (const_string "fmul")
13555 (match_operand:XF 3 "div_operator")
13556 (const_string "fdiv")
13557 ]
13558 (const_string "fop")))
13559 (set_attr "mode" "<MODE>")])
13560
13561 (define_insn "*fop_xf_5_i387"
13562 [(set (match_operand:XF 0 "register_operand" "=f,f")
13563 (match_operator:XF 3 "binary_fp_operator"
13564 [(match_operand:XF 1 "register_operand" "0,f")
13565 (float_extend:XF
13566 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13567 "TARGET_80387"
13568 "* return output_387_binary_op (insn, operands);"
13569 [(set (attr "type")
13570 (cond [(match_operand:XF 3 "mult_operator")
13571 (const_string "fmul")
13572 (match_operand:XF 3 "div_operator")
13573 (const_string "fdiv")
13574 ]
13575 (const_string "fop")))
13576 (set_attr "mode" "<MODE>")])
13577
13578 (define_insn "*fop_xf_6_i387"
13579 [(set (match_operand:XF 0 "register_operand" "=f,f")
13580 (match_operator:XF 3 "binary_fp_operator"
13581 [(float_extend:XF
13582 (match_operand:MODEF 1 "register_operand" "0,f"))
13583 (float_extend:XF
13584 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13585 "TARGET_80387"
13586 "* return output_387_binary_op (insn, operands);"
13587 [(set (attr "type")
13588 (cond [(match_operand:XF 3 "mult_operator")
13589 (const_string "fmul")
13590 (match_operand:XF 3 "div_operator")
13591 (const_string "fdiv")
13592 ]
13593 (const_string "fop")))
13594 (set_attr "mode" "<MODE>")])
13595
13596 (define_split
13597 [(set (match_operand 0 "register_operand")
13598 (match_operator 3 "binary_fp_operator"
13599 [(float (match_operand:SWI24 1 "register_operand"))
13600 (match_operand 2 "register_operand")]))]
13601 "reload_completed
13602 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13603 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13604 [(const_int 0)]
13605 {
13606 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13607 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13608 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13609 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13610 GET_MODE (operands[3]),
13611 operands[4],
13612 operands[2])));
13613 ix86_free_from_memory (GET_MODE (operands[1]));
13614 DONE;
13615 })
13616
13617 (define_split
13618 [(set (match_operand 0 "register_operand")
13619 (match_operator 3 "binary_fp_operator"
13620 [(match_operand 1 "register_operand")
13621 (float (match_operand:SWI24 2 "register_operand"))]))]
13622 "reload_completed
13623 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13624 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13625 [(const_int 0)]
13626 {
13627 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13628 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13629 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13630 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13631 GET_MODE (operands[3]),
13632 operands[1],
13633 operands[4])));
13634 ix86_free_from_memory (GET_MODE (operands[2]));
13635 DONE;
13636 })
13637 \f
13638 ;; FPU special functions.
13639
13640 ;; This pattern implements a no-op XFmode truncation for
13641 ;; all fancy i386 XFmode math functions.
13642
13643 (define_insn "truncxf<mode>2_i387_noop_unspec"
13644 [(set (match_operand:MODEF 0 "register_operand" "=f")
13645 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13646 UNSPEC_TRUNC_NOOP))]
13647 "TARGET_USE_FANCY_MATH_387"
13648 "* return output_387_reg_move (insn, operands);"
13649 [(set_attr "type" "fmov")
13650 (set_attr "mode" "<MODE>")])
13651
13652 (define_insn "sqrtxf2"
13653 [(set (match_operand:XF 0 "register_operand" "=f")
13654 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13655 "TARGET_USE_FANCY_MATH_387"
13656 "fsqrt"
13657 [(set_attr "type" "fpspc")
13658 (set_attr "mode" "XF")
13659 (set_attr "athlon_decode" "direct")
13660 (set_attr "amdfam10_decode" "direct")
13661 (set_attr "bdver1_decode" "direct")])
13662
13663 (define_insn "sqrt_extend<mode>xf2_i387"
13664 [(set (match_operand:XF 0 "register_operand" "=f")
13665 (sqrt:XF
13666 (float_extend:XF
13667 (match_operand:MODEF 1 "register_operand" "0"))))]
13668 "TARGET_USE_FANCY_MATH_387"
13669 "fsqrt"
13670 [(set_attr "type" "fpspc")
13671 (set_attr "mode" "XF")
13672 (set_attr "athlon_decode" "direct")
13673 (set_attr "amdfam10_decode" "direct")
13674 (set_attr "bdver1_decode" "direct")])
13675
13676 (define_insn "*rsqrtsf2_sse"
13677 [(set (match_operand:SF 0 "register_operand" "=x")
13678 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13679 UNSPEC_RSQRT))]
13680 "TARGET_SSE_MATH"
13681 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13682 [(set_attr "type" "sse")
13683 (set_attr "atom_sse_attr" "rcp")
13684 (set_attr "prefix" "maybe_vex")
13685 (set_attr "mode" "SF")])
13686
13687 (define_expand "rsqrtsf2"
13688 [(set (match_operand:SF 0 "register_operand")
13689 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13690 UNSPEC_RSQRT))]
13691 "TARGET_SSE_MATH"
13692 {
13693 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13694 DONE;
13695 })
13696
13697 (define_insn "*sqrt<mode>2_sse"
13698 [(set (match_operand:MODEF 0 "register_operand" "=x")
13699 (sqrt:MODEF
13700 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13701 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13702 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13703 [(set_attr "type" "sse")
13704 (set_attr "atom_sse_attr" "sqrt")
13705 (set_attr "prefix" "maybe_vex")
13706 (set_attr "mode" "<MODE>")
13707 (set_attr "athlon_decode" "*")
13708 (set_attr "amdfam10_decode" "*")
13709 (set_attr "bdver1_decode" "*")])
13710
13711 (define_expand "sqrt<mode>2"
13712 [(set (match_operand:MODEF 0 "register_operand")
13713 (sqrt:MODEF
13714 (match_operand:MODEF 1 "nonimmediate_operand")))]
13715 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13716 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13717 {
13718 if (<MODE>mode == SFmode
13719 && TARGET_SSE_MATH
13720 && TARGET_RECIP_SQRT
13721 && !optimize_function_for_size_p (cfun)
13722 && flag_finite_math_only && !flag_trapping_math
13723 && flag_unsafe_math_optimizations)
13724 {
13725 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13726 DONE;
13727 }
13728
13729 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13730 {
13731 rtx op0 = gen_reg_rtx (XFmode);
13732 rtx op1 = force_reg (<MODE>mode, operands[1]);
13733
13734 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13735 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13736 DONE;
13737 }
13738 })
13739
13740 (define_insn "fpremxf4_i387"
13741 [(set (match_operand:XF 0 "register_operand" "=f")
13742 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13743 (match_operand:XF 3 "register_operand" "1")]
13744 UNSPEC_FPREM_F))
13745 (set (match_operand:XF 1 "register_operand" "=u")
13746 (unspec:XF [(match_dup 2) (match_dup 3)]
13747 UNSPEC_FPREM_U))
13748 (set (reg:CCFP FPSR_REG)
13749 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13750 UNSPEC_C2_FLAG))]
13751 "TARGET_USE_FANCY_MATH_387"
13752 "fprem"
13753 [(set_attr "type" "fpspc")
13754 (set_attr "mode" "XF")])
13755
13756 (define_expand "fmodxf3"
13757 [(use (match_operand:XF 0 "register_operand"))
13758 (use (match_operand:XF 1 "general_operand"))
13759 (use (match_operand:XF 2 "general_operand"))]
13760 "TARGET_USE_FANCY_MATH_387"
13761 {
13762 rtx label = gen_label_rtx ();
13763
13764 rtx op1 = gen_reg_rtx (XFmode);
13765 rtx op2 = gen_reg_rtx (XFmode);
13766
13767 emit_move_insn (op2, operands[2]);
13768 emit_move_insn (op1, operands[1]);
13769
13770 emit_label (label);
13771 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13772 ix86_emit_fp_unordered_jump (label);
13773 LABEL_NUSES (label) = 1;
13774
13775 emit_move_insn (operands[0], op1);
13776 DONE;
13777 })
13778
13779 (define_expand "fmod<mode>3"
13780 [(use (match_operand:MODEF 0 "register_operand"))
13781 (use (match_operand:MODEF 1 "general_operand"))
13782 (use (match_operand:MODEF 2 "general_operand"))]
13783 "TARGET_USE_FANCY_MATH_387"
13784 {
13785 rtx (*gen_truncxf) (rtx, rtx);
13786
13787 rtx label = gen_label_rtx ();
13788
13789 rtx op1 = gen_reg_rtx (XFmode);
13790 rtx op2 = gen_reg_rtx (XFmode);
13791
13792 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13793 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13794
13795 emit_label (label);
13796 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13797 ix86_emit_fp_unordered_jump (label);
13798 LABEL_NUSES (label) = 1;
13799
13800 /* Truncate the result properly for strict SSE math. */
13801 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13802 && !TARGET_MIX_SSE_I387)
13803 gen_truncxf = gen_truncxf<mode>2;
13804 else
13805 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13806
13807 emit_insn (gen_truncxf (operands[0], op1));
13808 DONE;
13809 })
13810
13811 (define_insn "fprem1xf4_i387"
13812 [(set (match_operand:XF 0 "register_operand" "=f")
13813 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13814 (match_operand:XF 3 "register_operand" "1")]
13815 UNSPEC_FPREM1_F))
13816 (set (match_operand:XF 1 "register_operand" "=u")
13817 (unspec:XF [(match_dup 2) (match_dup 3)]
13818 UNSPEC_FPREM1_U))
13819 (set (reg:CCFP FPSR_REG)
13820 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13821 UNSPEC_C2_FLAG))]
13822 "TARGET_USE_FANCY_MATH_387"
13823 "fprem1"
13824 [(set_attr "type" "fpspc")
13825 (set_attr "mode" "XF")])
13826
13827 (define_expand "remainderxf3"
13828 [(use (match_operand:XF 0 "register_operand"))
13829 (use (match_operand:XF 1 "general_operand"))
13830 (use (match_operand:XF 2 "general_operand"))]
13831 "TARGET_USE_FANCY_MATH_387"
13832 {
13833 rtx label = gen_label_rtx ();
13834
13835 rtx op1 = gen_reg_rtx (XFmode);
13836 rtx op2 = gen_reg_rtx (XFmode);
13837
13838 emit_move_insn (op2, operands[2]);
13839 emit_move_insn (op1, operands[1]);
13840
13841 emit_label (label);
13842 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13843 ix86_emit_fp_unordered_jump (label);
13844 LABEL_NUSES (label) = 1;
13845
13846 emit_move_insn (operands[0], op1);
13847 DONE;
13848 })
13849
13850 (define_expand "remainder<mode>3"
13851 [(use (match_operand:MODEF 0 "register_operand"))
13852 (use (match_operand:MODEF 1 "general_operand"))
13853 (use (match_operand:MODEF 2 "general_operand"))]
13854 "TARGET_USE_FANCY_MATH_387"
13855 {
13856 rtx (*gen_truncxf) (rtx, rtx);
13857
13858 rtx label = gen_label_rtx ();
13859
13860 rtx op1 = gen_reg_rtx (XFmode);
13861 rtx op2 = gen_reg_rtx (XFmode);
13862
13863 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13864 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13865
13866 emit_label (label);
13867
13868 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13869 ix86_emit_fp_unordered_jump (label);
13870 LABEL_NUSES (label) = 1;
13871
13872 /* Truncate the result properly for strict SSE math. */
13873 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13874 && !TARGET_MIX_SSE_I387)
13875 gen_truncxf = gen_truncxf<mode>2;
13876 else
13877 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13878
13879 emit_insn (gen_truncxf (operands[0], op1));
13880 DONE;
13881 })
13882
13883 (define_int_iterator SINCOS
13884 [UNSPEC_SIN
13885 UNSPEC_COS])
13886
13887 (define_int_attr sincos
13888 [(UNSPEC_SIN "sin")
13889 (UNSPEC_COS "cos")])
13890
13891 (define_insn "*<sincos>xf2_i387"
13892 [(set (match_operand:XF 0 "register_operand" "=f")
13893 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13894 SINCOS))]
13895 "TARGET_USE_FANCY_MATH_387
13896 && flag_unsafe_math_optimizations"
13897 "f<sincos>"
13898 [(set_attr "type" "fpspc")
13899 (set_attr "mode" "XF")])
13900
13901 (define_insn "*<sincos>_extend<mode>xf2_i387"
13902 [(set (match_operand:XF 0 "register_operand" "=f")
13903 (unspec:XF [(float_extend:XF
13904 (match_operand:MODEF 1 "register_operand" "0"))]
13905 SINCOS))]
13906 "TARGET_USE_FANCY_MATH_387
13907 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13908 || TARGET_MIX_SSE_I387)
13909 && flag_unsafe_math_optimizations"
13910 "f<sincos>"
13911 [(set_attr "type" "fpspc")
13912 (set_attr "mode" "XF")])
13913
13914 ;; When sincos pattern is defined, sin and cos builtin functions will be
13915 ;; expanded to sincos pattern with one of its outputs left unused.
13916 ;; CSE pass will figure out if two sincos patterns can be combined,
13917 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13918 ;; depending on the unused output.
13919
13920 (define_insn "sincosxf3"
13921 [(set (match_operand:XF 0 "register_operand" "=f")
13922 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13923 UNSPEC_SINCOS_COS))
13924 (set (match_operand:XF 1 "register_operand" "=u")
13925 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13926 "TARGET_USE_FANCY_MATH_387
13927 && flag_unsafe_math_optimizations"
13928 "fsincos"
13929 [(set_attr "type" "fpspc")
13930 (set_attr "mode" "XF")])
13931
13932 (define_split
13933 [(set (match_operand:XF 0 "register_operand")
13934 (unspec:XF [(match_operand:XF 2 "register_operand")]
13935 UNSPEC_SINCOS_COS))
13936 (set (match_operand:XF 1 "register_operand")
13937 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13938 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13939 && can_create_pseudo_p ()"
13940 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13941
13942 (define_split
13943 [(set (match_operand:XF 0 "register_operand")
13944 (unspec:XF [(match_operand:XF 2 "register_operand")]
13945 UNSPEC_SINCOS_COS))
13946 (set (match_operand:XF 1 "register_operand")
13947 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13948 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13949 && can_create_pseudo_p ()"
13950 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13951
13952 (define_insn "sincos_extend<mode>xf3_i387"
13953 [(set (match_operand:XF 0 "register_operand" "=f")
13954 (unspec:XF [(float_extend:XF
13955 (match_operand:MODEF 2 "register_operand" "0"))]
13956 UNSPEC_SINCOS_COS))
13957 (set (match_operand:XF 1 "register_operand" "=u")
13958 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13959 "TARGET_USE_FANCY_MATH_387
13960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13961 || TARGET_MIX_SSE_I387)
13962 && flag_unsafe_math_optimizations"
13963 "fsincos"
13964 [(set_attr "type" "fpspc")
13965 (set_attr "mode" "XF")])
13966
13967 (define_split
13968 [(set (match_operand:XF 0 "register_operand")
13969 (unspec:XF [(float_extend:XF
13970 (match_operand:MODEF 2 "register_operand"))]
13971 UNSPEC_SINCOS_COS))
13972 (set (match_operand:XF 1 "register_operand")
13973 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13974 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13975 && can_create_pseudo_p ()"
13976 [(set (match_dup 1)
13977 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13978
13979 (define_split
13980 [(set (match_operand:XF 0 "register_operand")
13981 (unspec:XF [(float_extend:XF
13982 (match_operand:MODEF 2 "register_operand"))]
13983 UNSPEC_SINCOS_COS))
13984 (set (match_operand:XF 1 "register_operand")
13985 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13986 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13987 && can_create_pseudo_p ()"
13988 [(set (match_dup 0)
13989 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13990
13991 (define_expand "sincos<mode>3"
13992 [(use (match_operand:MODEF 0 "register_operand"))
13993 (use (match_operand:MODEF 1 "register_operand"))
13994 (use (match_operand:MODEF 2 "register_operand"))]
13995 "TARGET_USE_FANCY_MATH_387
13996 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13997 || TARGET_MIX_SSE_I387)
13998 && flag_unsafe_math_optimizations"
13999 {
14000 rtx op0 = gen_reg_rtx (XFmode);
14001 rtx op1 = gen_reg_rtx (XFmode);
14002
14003 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14004 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14005 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14006 DONE;
14007 })
14008
14009 (define_insn "fptanxf4_i387"
14010 [(set (match_operand:XF 0 "register_operand" "=f")
14011 (match_operand:XF 3 "const_double_operand" "F"))
14012 (set (match_operand:XF 1 "register_operand" "=u")
14013 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14014 UNSPEC_TAN))]
14015 "TARGET_USE_FANCY_MATH_387
14016 && flag_unsafe_math_optimizations
14017 && standard_80387_constant_p (operands[3]) == 2"
14018 "fptan"
14019 [(set_attr "type" "fpspc")
14020 (set_attr "mode" "XF")])
14021
14022 (define_insn "fptan_extend<mode>xf4_i387"
14023 [(set (match_operand:MODEF 0 "register_operand" "=f")
14024 (match_operand:MODEF 3 "const_double_operand" "F"))
14025 (set (match_operand:XF 1 "register_operand" "=u")
14026 (unspec:XF [(float_extend:XF
14027 (match_operand:MODEF 2 "register_operand" "0"))]
14028 UNSPEC_TAN))]
14029 "TARGET_USE_FANCY_MATH_387
14030 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14031 || TARGET_MIX_SSE_I387)
14032 && flag_unsafe_math_optimizations
14033 && standard_80387_constant_p (operands[3]) == 2"
14034 "fptan"
14035 [(set_attr "type" "fpspc")
14036 (set_attr "mode" "XF")])
14037
14038 (define_expand "tanxf2"
14039 [(use (match_operand:XF 0 "register_operand"))
14040 (use (match_operand:XF 1 "register_operand"))]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14043 {
14044 rtx one = gen_reg_rtx (XFmode);
14045 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14046
14047 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14048 DONE;
14049 })
14050
14051 (define_expand "tan<mode>2"
14052 [(use (match_operand:MODEF 0 "register_operand"))
14053 (use (match_operand:MODEF 1 "register_operand"))]
14054 "TARGET_USE_FANCY_MATH_387
14055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056 || TARGET_MIX_SSE_I387)
14057 && flag_unsafe_math_optimizations"
14058 {
14059 rtx op0 = gen_reg_rtx (XFmode);
14060
14061 rtx one = gen_reg_rtx (<MODE>mode);
14062 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14063
14064 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14065 operands[1], op2));
14066 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14067 DONE;
14068 })
14069
14070 (define_insn "*fpatanxf3_i387"
14071 [(set (match_operand:XF 0 "register_operand" "=f")
14072 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14073 (match_operand:XF 2 "register_operand" "u")]
14074 UNSPEC_FPATAN))
14075 (clobber (match_scratch:XF 3 "=2"))]
14076 "TARGET_USE_FANCY_MATH_387
14077 && flag_unsafe_math_optimizations"
14078 "fpatan"
14079 [(set_attr "type" "fpspc")
14080 (set_attr "mode" "XF")])
14081
14082 (define_insn "fpatan_extend<mode>xf3_i387"
14083 [(set (match_operand:XF 0 "register_operand" "=f")
14084 (unspec:XF [(float_extend:XF
14085 (match_operand:MODEF 1 "register_operand" "0"))
14086 (float_extend:XF
14087 (match_operand:MODEF 2 "register_operand" "u"))]
14088 UNSPEC_FPATAN))
14089 (clobber (match_scratch:XF 3 "=2"))]
14090 "TARGET_USE_FANCY_MATH_387
14091 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14092 || TARGET_MIX_SSE_I387)
14093 && flag_unsafe_math_optimizations"
14094 "fpatan"
14095 [(set_attr "type" "fpspc")
14096 (set_attr "mode" "XF")])
14097
14098 (define_expand "atan2xf3"
14099 [(parallel [(set (match_operand:XF 0 "register_operand")
14100 (unspec:XF [(match_operand:XF 2 "register_operand")
14101 (match_operand:XF 1 "register_operand")]
14102 UNSPEC_FPATAN))
14103 (clobber (match_scratch:XF 3))])]
14104 "TARGET_USE_FANCY_MATH_387
14105 && flag_unsafe_math_optimizations")
14106
14107 (define_expand "atan2<mode>3"
14108 [(use (match_operand:MODEF 0 "register_operand"))
14109 (use (match_operand:MODEF 1 "register_operand"))
14110 (use (match_operand:MODEF 2 "register_operand"))]
14111 "TARGET_USE_FANCY_MATH_387
14112 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14113 || TARGET_MIX_SSE_I387)
14114 && flag_unsafe_math_optimizations"
14115 {
14116 rtx op0 = gen_reg_rtx (XFmode);
14117
14118 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14119 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14120 DONE;
14121 })
14122
14123 (define_expand "atanxf2"
14124 [(parallel [(set (match_operand:XF 0 "register_operand")
14125 (unspec:XF [(match_dup 2)
14126 (match_operand:XF 1 "register_operand")]
14127 UNSPEC_FPATAN))
14128 (clobber (match_scratch:XF 3))])]
14129 "TARGET_USE_FANCY_MATH_387
14130 && flag_unsafe_math_optimizations"
14131 {
14132 operands[2] = gen_reg_rtx (XFmode);
14133 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14134 })
14135
14136 (define_expand "atan<mode>2"
14137 [(use (match_operand:MODEF 0 "register_operand"))
14138 (use (match_operand:MODEF 1 "register_operand"))]
14139 "TARGET_USE_FANCY_MATH_387
14140 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14141 || TARGET_MIX_SSE_I387)
14142 && flag_unsafe_math_optimizations"
14143 {
14144 rtx op0 = gen_reg_rtx (XFmode);
14145
14146 rtx op2 = gen_reg_rtx (<MODE>mode);
14147 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14148
14149 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14150 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14151 DONE;
14152 })
14153
14154 (define_expand "asinxf2"
14155 [(set (match_dup 2)
14156 (mult:XF (match_operand:XF 1 "register_operand")
14157 (match_dup 1)))
14158 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14159 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14160 (parallel [(set (match_operand:XF 0 "register_operand")
14161 (unspec:XF [(match_dup 5) (match_dup 1)]
14162 UNSPEC_FPATAN))
14163 (clobber (match_scratch:XF 6))])]
14164 "TARGET_USE_FANCY_MATH_387
14165 && flag_unsafe_math_optimizations"
14166 {
14167 int i;
14168
14169 if (optimize_insn_for_size_p ())
14170 FAIL;
14171
14172 for (i = 2; i < 6; i++)
14173 operands[i] = gen_reg_rtx (XFmode);
14174
14175 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14176 })
14177
14178 (define_expand "asin<mode>2"
14179 [(use (match_operand:MODEF 0 "register_operand"))
14180 (use (match_operand:MODEF 1 "general_operand"))]
14181 "TARGET_USE_FANCY_MATH_387
14182 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14183 || TARGET_MIX_SSE_I387)
14184 && flag_unsafe_math_optimizations"
14185 {
14186 rtx op0 = gen_reg_rtx (XFmode);
14187 rtx op1 = gen_reg_rtx (XFmode);
14188
14189 if (optimize_insn_for_size_p ())
14190 FAIL;
14191
14192 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14193 emit_insn (gen_asinxf2 (op0, op1));
14194 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14195 DONE;
14196 })
14197
14198 (define_expand "acosxf2"
14199 [(set (match_dup 2)
14200 (mult:XF (match_operand:XF 1 "register_operand")
14201 (match_dup 1)))
14202 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14203 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14204 (parallel [(set (match_operand:XF 0 "register_operand")
14205 (unspec:XF [(match_dup 1) (match_dup 5)]
14206 UNSPEC_FPATAN))
14207 (clobber (match_scratch:XF 6))])]
14208 "TARGET_USE_FANCY_MATH_387
14209 && flag_unsafe_math_optimizations"
14210 {
14211 int i;
14212
14213 if (optimize_insn_for_size_p ())
14214 FAIL;
14215
14216 for (i = 2; i < 6; i++)
14217 operands[i] = gen_reg_rtx (XFmode);
14218
14219 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14220 })
14221
14222 (define_expand "acos<mode>2"
14223 [(use (match_operand:MODEF 0 "register_operand"))
14224 (use (match_operand:MODEF 1 "general_operand"))]
14225 "TARGET_USE_FANCY_MATH_387
14226 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14227 || TARGET_MIX_SSE_I387)
14228 && flag_unsafe_math_optimizations"
14229 {
14230 rtx op0 = gen_reg_rtx (XFmode);
14231 rtx op1 = gen_reg_rtx (XFmode);
14232
14233 if (optimize_insn_for_size_p ())
14234 FAIL;
14235
14236 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14237 emit_insn (gen_acosxf2 (op0, op1));
14238 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14239 DONE;
14240 })
14241
14242 (define_insn "fyl2xxf3_i387"
14243 [(set (match_operand:XF 0 "register_operand" "=f")
14244 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14245 (match_operand:XF 2 "register_operand" "u")]
14246 UNSPEC_FYL2X))
14247 (clobber (match_scratch:XF 3 "=2"))]
14248 "TARGET_USE_FANCY_MATH_387
14249 && flag_unsafe_math_optimizations"
14250 "fyl2x"
14251 [(set_attr "type" "fpspc")
14252 (set_attr "mode" "XF")])
14253
14254 (define_insn "fyl2x_extend<mode>xf3_i387"
14255 [(set (match_operand:XF 0 "register_operand" "=f")
14256 (unspec:XF [(float_extend:XF
14257 (match_operand:MODEF 1 "register_operand" "0"))
14258 (match_operand:XF 2 "register_operand" "u")]
14259 UNSPEC_FYL2X))
14260 (clobber (match_scratch:XF 3 "=2"))]
14261 "TARGET_USE_FANCY_MATH_387
14262 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14263 || TARGET_MIX_SSE_I387)
14264 && flag_unsafe_math_optimizations"
14265 "fyl2x"
14266 [(set_attr "type" "fpspc")
14267 (set_attr "mode" "XF")])
14268
14269 (define_expand "logxf2"
14270 [(parallel [(set (match_operand:XF 0 "register_operand")
14271 (unspec:XF [(match_operand:XF 1 "register_operand")
14272 (match_dup 2)] UNSPEC_FYL2X))
14273 (clobber (match_scratch:XF 3))])]
14274 "TARGET_USE_FANCY_MATH_387
14275 && flag_unsafe_math_optimizations"
14276 {
14277 operands[2] = gen_reg_rtx (XFmode);
14278 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14279 })
14280
14281 (define_expand "log<mode>2"
14282 [(use (match_operand:MODEF 0 "register_operand"))
14283 (use (match_operand:MODEF 1 "register_operand"))]
14284 "TARGET_USE_FANCY_MATH_387
14285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14286 || TARGET_MIX_SSE_I387)
14287 && flag_unsafe_math_optimizations"
14288 {
14289 rtx op0 = gen_reg_rtx (XFmode);
14290
14291 rtx op2 = gen_reg_rtx (XFmode);
14292 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14293
14294 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14295 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14296 DONE;
14297 })
14298
14299 (define_expand "log10xf2"
14300 [(parallel [(set (match_operand:XF 0 "register_operand")
14301 (unspec:XF [(match_operand:XF 1 "register_operand")
14302 (match_dup 2)] UNSPEC_FYL2X))
14303 (clobber (match_scratch:XF 3))])]
14304 "TARGET_USE_FANCY_MATH_387
14305 && flag_unsafe_math_optimizations"
14306 {
14307 operands[2] = gen_reg_rtx (XFmode);
14308 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14309 })
14310
14311 (define_expand "log10<mode>2"
14312 [(use (match_operand:MODEF 0 "register_operand"))
14313 (use (match_operand:MODEF 1 "register_operand"))]
14314 "TARGET_USE_FANCY_MATH_387
14315 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14316 || TARGET_MIX_SSE_I387)
14317 && flag_unsafe_math_optimizations"
14318 {
14319 rtx op0 = gen_reg_rtx (XFmode);
14320
14321 rtx op2 = gen_reg_rtx (XFmode);
14322 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14323
14324 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14325 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14326 DONE;
14327 })
14328
14329 (define_expand "log2xf2"
14330 [(parallel [(set (match_operand:XF 0 "register_operand")
14331 (unspec:XF [(match_operand:XF 1 "register_operand")
14332 (match_dup 2)] UNSPEC_FYL2X))
14333 (clobber (match_scratch:XF 3))])]
14334 "TARGET_USE_FANCY_MATH_387
14335 && flag_unsafe_math_optimizations"
14336 {
14337 operands[2] = gen_reg_rtx (XFmode);
14338 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14339 })
14340
14341 (define_expand "log2<mode>2"
14342 [(use (match_operand:MODEF 0 "register_operand"))
14343 (use (match_operand:MODEF 1 "register_operand"))]
14344 "TARGET_USE_FANCY_MATH_387
14345 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14346 || TARGET_MIX_SSE_I387)
14347 && flag_unsafe_math_optimizations"
14348 {
14349 rtx op0 = gen_reg_rtx (XFmode);
14350
14351 rtx op2 = gen_reg_rtx (XFmode);
14352 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14353
14354 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14355 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14356 DONE;
14357 })
14358
14359 (define_insn "fyl2xp1xf3_i387"
14360 [(set (match_operand:XF 0 "register_operand" "=f")
14361 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14362 (match_operand:XF 2 "register_operand" "u")]
14363 UNSPEC_FYL2XP1))
14364 (clobber (match_scratch:XF 3 "=2"))]
14365 "TARGET_USE_FANCY_MATH_387
14366 && flag_unsafe_math_optimizations"
14367 "fyl2xp1"
14368 [(set_attr "type" "fpspc")
14369 (set_attr "mode" "XF")])
14370
14371 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14372 [(set (match_operand:XF 0 "register_operand" "=f")
14373 (unspec:XF [(float_extend:XF
14374 (match_operand:MODEF 1 "register_operand" "0"))
14375 (match_operand:XF 2 "register_operand" "u")]
14376 UNSPEC_FYL2XP1))
14377 (clobber (match_scratch:XF 3 "=2"))]
14378 "TARGET_USE_FANCY_MATH_387
14379 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14380 || TARGET_MIX_SSE_I387)
14381 && flag_unsafe_math_optimizations"
14382 "fyl2xp1"
14383 [(set_attr "type" "fpspc")
14384 (set_attr "mode" "XF")])
14385
14386 (define_expand "log1pxf2"
14387 [(use (match_operand:XF 0 "register_operand"))
14388 (use (match_operand:XF 1 "register_operand"))]
14389 "TARGET_USE_FANCY_MATH_387
14390 && flag_unsafe_math_optimizations"
14391 {
14392 if (optimize_insn_for_size_p ())
14393 FAIL;
14394
14395 ix86_emit_i387_log1p (operands[0], operands[1]);
14396 DONE;
14397 })
14398
14399 (define_expand "log1p<mode>2"
14400 [(use (match_operand:MODEF 0 "register_operand"))
14401 (use (match_operand:MODEF 1 "register_operand"))]
14402 "TARGET_USE_FANCY_MATH_387
14403 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14404 || TARGET_MIX_SSE_I387)
14405 && flag_unsafe_math_optimizations"
14406 {
14407 rtx op0;
14408
14409 if (optimize_insn_for_size_p ())
14410 FAIL;
14411
14412 op0 = gen_reg_rtx (XFmode);
14413
14414 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14415
14416 ix86_emit_i387_log1p (op0, operands[1]);
14417 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14418 DONE;
14419 })
14420
14421 (define_insn "fxtractxf3_i387"
14422 [(set (match_operand:XF 0 "register_operand" "=f")
14423 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14424 UNSPEC_XTRACT_FRACT))
14425 (set (match_operand:XF 1 "register_operand" "=u")
14426 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14427 "TARGET_USE_FANCY_MATH_387
14428 && flag_unsafe_math_optimizations"
14429 "fxtract"
14430 [(set_attr "type" "fpspc")
14431 (set_attr "mode" "XF")])
14432
14433 (define_insn "fxtract_extend<mode>xf3_i387"
14434 [(set (match_operand:XF 0 "register_operand" "=f")
14435 (unspec:XF [(float_extend:XF
14436 (match_operand:MODEF 2 "register_operand" "0"))]
14437 UNSPEC_XTRACT_FRACT))
14438 (set (match_operand:XF 1 "register_operand" "=u")
14439 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14440 "TARGET_USE_FANCY_MATH_387
14441 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14442 || TARGET_MIX_SSE_I387)
14443 && flag_unsafe_math_optimizations"
14444 "fxtract"
14445 [(set_attr "type" "fpspc")
14446 (set_attr "mode" "XF")])
14447
14448 (define_expand "logbxf2"
14449 [(parallel [(set (match_dup 2)
14450 (unspec:XF [(match_operand:XF 1 "register_operand")]
14451 UNSPEC_XTRACT_FRACT))
14452 (set (match_operand:XF 0 "register_operand")
14453 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14454 "TARGET_USE_FANCY_MATH_387
14455 && flag_unsafe_math_optimizations"
14456 "operands[2] = gen_reg_rtx (XFmode);")
14457
14458 (define_expand "logb<mode>2"
14459 [(use (match_operand:MODEF 0 "register_operand"))
14460 (use (match_operand:MODEF 1 "register_operand"))]
14461 "TARGET_USE_FANCY_MATH_387
14462 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14463 || TARGET_MIX_SSE_I387)
14464 && flag_unsafe_math_optimizations"
14465 {
14466 rtx op0 = gen_reg_rtx (XFmode);
14467 rtx op1 = gen_reg_rtx (XFmode);
14468
14469 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14470 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14471 DONE;
14472 })
14473
14474 (define_expand "ilogbxf2"
14475 [(use (match_operand:SI 0 "register_operand"))
14476 (use (match_operand:XF 1 "register_operand"))]
14477 "TARGET_USE_FANCY_MATH_387
14478 && flag_unsafe_math_optimizations"
14479 {
14480 rtx op0, op1;
14481
14482 if (optimize_insn_for_size_p ())
14483 FAIL;
14484
14485 op0 = gen_reg_rtx (XFmode);
14486 op1 = gen_reg_rtx (XFmode);
14487
14488 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14489 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14490 DONE;
14491 })
14492
14493 (define_expand "ilogb<mode>2"
14494 [(use (match_operand:SI 0 "register_operand"))
14495 (use (match_operand:MODEF 1 "register_operand"))]
14496 "TARGET_USE_FANCY_MATH_387
14497 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14498 || TARGET_MIX_SSE_I387)
14499 && flag_unsafe_math_optimizations"
14500 {
14501 rtx op0, op1;
14502
14503 if (optimize_insn_for_size_p ())
14504 FAIL;
14505
14506 op0 = gen_reg_rtx (XFmode);
14507 op1 = gen_reg_rtx (XFmode);
14508
14509 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14510 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14511 DONE;
14512 })
14513
14514 (define_insn "*f2xm1xf2_i387"
14515 [(set (match_operand:XF 0 "register_operand" "=f")
14516 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14517 UNSPEC_F2XM1))]
14518 "TARGET_USE_FANCY_MATH_387
14519 && flag_unsafe_math_optimizations"
14520 "f2xm1"
14521 [(set_attr "type" "fpspc")
14522 (set_attr "mode" "XF")])
14523
14524 (define_insn "*fscalexf4_i387"
14525 [(set (match_operand:XF 0 "register_operand" "=f")
14526 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14527 (match_operand:XF 3 "register_operand" "1")]
14528 UNSPEC_FSCALE_FRACT))
14529 (set (match_operand:XF 1 "register_operand" "=u")
14530 (unspec:XF [(match_dup 2) (match_dup 3)]
14531 UNSPEC_FSCALE_EXP))]
14532 "TARGET_USE_FANCY_MATH_387
14533 && flag_unsafe_math_optimizations"
14534 "fscale"
14535 [(set_attr "type" "fpspc")
14536 (set_attr "mode" "XF")])
14537
14538 (define_expand "expNcorexf3"
14539 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14540 (match_operand:XF 2 "register_operand")))
14541 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14542 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14543 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14544 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14545 (parallel [(set (match_operand:XF 0 "register_operand")
14546 (unspec:XF [(match_dup 8) (match_dup 4)]
14547 UNSPEC_FSCALE_FRACT))
14548 (set (match_dup 9)
14549 (unspec:XF [(match_dup 8) (match_dup 4)]
14550 UNSPEC_FSCALE_EXP))])]
14551 "TARGET_USE_FANCY_MATH_387
14552 && flag_unsafe_math_optimizations"
14553 {
14554 int i;
14555
14556 if (optimize_insn_for_size_p ())
14557 FAIL;
14558
14559 for (i = 3; i < 10; i++)
14560 operands[i] = gen_reg_rtx (XFmode);
14561
14562 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14563 })
14564
14565 (define_expand "expxf2"
14566 [(use (match_operand:XF 0 "register_operand"))
14567 (use (match_operand:XF 1 "register_operand"))]
14568 "TARGET_USE_FANCY_MATH_387
14569 && flag_unsafe_math_optimizations"
14570 {
14571 rtx op2;
14572
14573 if (optimize_insn_for_size_p ())
14574 FAIL;
14575
14576 op2 = gen_reg_rtx (XFmode);
14577 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14578
14579 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14580 DONE;
14581 })
14582
14583 (define_expand "exp<mode>2"
14584 [(use (match_operand:MODEF 0 "register_operand"))
14585 (use (match_operand:MODEF 1 "general_operand"))]
14586 "TARGET_USE_FANCY_MATH_387
14587 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14588 || TARGET_MIX_SSE_I387)
14589 && flag_unsafe_math_optimizations"
14590 {
14591 rtx op0, op1;
14592
14593 if (optimize_insn_for_size_p ())
14594 FAIL;
14595
14596 op0 = gen_reg_rtx (XFmode);
14597 op1 = gen_reg_rtx (XFmode);
14598
14599 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14600 emit_insn (gen_expxf2 (op0, op1));
14601 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14602 DONE;
14603 })
14604
14605 (define_expand "exp10xf2"
14606 [(use (match_operand:XF 0 "register_operand"))
14607 (use (match_operand:XF 1 "register_operand"))]
14608 "TARGET_USE_FANCY_MATH_387
14609 && flag_unsafe_math_optimizations"
14610 {
14611 rtx op2;
14612
14613 if (optimize_insn_for_size_p ())
14614 FAIL;
14615
14616 op2 = gen_reg_rtx (XFmode);
14617 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14618
14619 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14620 DONE;
14621 })
14622
14623 (define_expand "exp10<mode>2"
14624 [(use (match_operand:MODEF 0 "register_operand"))
14625 (use (match_operand:MODEF 1 "general_operand"))]
14626 "TARGET_USE_FANCY_MATH_387
14627 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14628 || TARGET_MIX_SSE_I387)
14629 && flag_unsafe_math_optimizations"
14630 {
14631 rtx op0, op1;
14632
14633 if (optimize_insn_for_size_p ())
14634 FAIL;
14635
14636 op0 = gen_reg_rtx (XFmode);
14637 op1 = gen_reg_rtx (XFmode);
14638
14639 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14640 emit_insn (gen_exp10xf2 (op0, op1));
14641 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14642 DONE;
14643 })
14644
14645 (define_expand "exp2xf2"
14646 [(use (match_operand:XF 0 "register_operand"))
14647 (use (match_operand:XF 1 "register_operand"))]
14648 "TARGET_USE_FANCY_MATH_387
14649 && flag_unsafe_math_optimizations"
14650 {
14651 rtx op2;
14652
14653 if (optimize_insn_for_size_p ())
14654 FAIL;
14655
14656 op2 = gen_reg_rtx (XFmode);
14657 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14658
14659 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14660 DONE;
14661 })
14662
14663 (define_expand "exp2<mode>2"
14664 [(use (match_operand:MODEF 0 "register_operand"))
14665 (use (match_operand:MODEF 1 "general_operand"))]
14666 "TARGET_USE_FANCY_MATH_387
14667 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14668 || TARGET_MIX_SSE_I387)
14669 && flag_unsafe_math_optimizations"
14670 {
14671 rtx op0, op1;
14672
14673 if (optimize_insn_for_size_p ())
14674 FAIL;
14675
14676 op0 = gen_reg_rtx (XFmode);
14677 op1 = gen_reg_rtx (XFmode);
14678
14679 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14680 emit_insn (gen_exp2xf2 (op0, op1));
14681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14682 DONE;
14683 })
14684
14685 (define_expand "expm1xf2"
14686 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14687 (match_dup 2)))
14688 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14689 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14690 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14691 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14692 (parallel [(set (match_dup 7)
14693 (unspec:XF [(match_dup 6) (match_dup 4)]
14694 UNSPEC_FSCALE_FRACT))
14695 (set (match_dup 8)
14696 (unspec:XF [(match_dup 6) (match_dup 4)]
14697 UNSPEC_FSCALE_EXP))])
14698 (parallel [(set (match_dup 10)
14699 (unspec:XF [(match_dup 9) (match_dup 8)]
14700 UNSPEC_FSCALE_FRACT))
14701 (set (match_dup 11)
14702 (unspec:XF [(match_dup 9) (match_dup 8)]
14703 UNSPEC_FSCALE_EXP))])
14704 (set (match_dup 12) (minus:XF (match_dup 10)
14705 (float_extend:XF (match_dup 13))))
14706 (set (match_operand:XF 0 "register_operand")
14707 (plus:XF (match_dup 12) (match_dup 7)))]
14708 "TARGET_USE_FANCY_MATH_387
14709 && flag_unsafe_math_optimizations"
14710 {
14711 int i;
14712
14713 if (optimize_insn_for_size_p ())
14714 FAIL;
14715
14716 for (i = 2; i < 13; i++)
14717 operands[i] = gen_reg_rtx (XFmode);
14718
14719 operands[13]
14720 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14721
14722 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14723 })
14724
14725 (define_expand "expm1<mode>2"
14726 [(use (match_operand:MODEF 0 "register_operand"))
14727 (use (match_operand:MODEF 1 "general_operand"))]
14728 "TARGET_USE_FANCY_MATH_387
14729 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14730 || TARGET_MIX_SSE_I387)
14731 && flag_unsafe_math_optimizations"
14732 {
14733 rtx op0, op1;
14734
14735 if (optimize_insn_for_size_p ())
14736 FAIL;
14737
14738 op0 = gen_reg_rtx (XFmode);
14739 op1 = gen_reg_rtx (XFmode);
14740
14741 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14742 emit_insn (gen_expm1xf2 (op0, op1));
14743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14744 DONE;
14745 })
14746
14747 (define_expand "ldexpxf3"
14748 [(set (match_dup 3)
14749 (float:XF (match_operand:SI 2 "register_operand")))
14750 (parallel [(set (match_operand:XF 0 " register_operand")
14751 (unspec:XF [(match_operand:XF 1 "register_operand")
14752 (match_dup 3)]
14753 UNSPEC_FSCALE_FRACT))
14754 (set (match_dup 4)
14755 (unspec:XF [(match_dup 1) (match_dup 3)]
14756 UNSPEC_FSCALE_EXP))])]
14757 "TARGET_USE_FANCY_MATH_387
14758 && flag_unsafe_math_optimizations"
14759 {
14760 if (optimize_insn_for_size_p ())
14761 FAIL;
14762
14763 operands[3] = gen_reg_rtx (XFmode);
14764 operands[4] = gen_reg_rtx (XFmode);
14765 })
14766
14767 (define_expand "ldexp<mode>3"
14768 [(use (match_operand:MODEF 0 "register_operand"))
14769 (use (match_operand:MODEF 1 "general_operand"))
14770 (use (match_operand:SI 2 "register_operand"))]
14771 "TARGET_USE_FANCY_MATH_387
14772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14773 || TARGET_MIX_SSE_I387)
14774 && flag_unsafe_math_optimizations"
14775 {
14776 rtx op0, op1;
14777
14778 if (optimize_insn_for_size_p ())
14779 FAIL;
14780
14781 op0 = gen_reg_rtx (XFmode);
14782 op1 = gen_reg_rtx (XFmode);
14783
14784 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14785 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14786 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14787 DONE;
14788 })
14789
14790 (define_expand "scalbxf3"
14791 [(parallel [(set (match_operand:XF 0 " register_operand")
14792 (unspec:XF [(match_operand:XF 1 "register_operand")
14793 (match_operand:XF 2 "register_operand")]
14794 UNSPEC_FSCALE_FRACT))
14795 (set (match_dup 3)
14796 (unspec:XF [(match_dup 1) (match_dup 2)]
14797 UNSPEC_FSCALE_EXP))])]
14798 "TARGET_USE_FANCY_MATH_387
14799 && flag_unsafe_math_optimizations"
14800 {
14801 if (optimize_insn_for_size_p ())
14802 FAIL;
14803
14804 operands[3] = gen_reg_rtx (XFmode);
14805 })
14806
14807 (define_expand "scalb<mode>3"
14808 [(use (match_operand:MODEF 0 "register_operand"))
14809 (use (match_operand:MODEF 1 "general_operand"))
14810 (use (match_operand:MODEF 2 "general_operand"))]
14811 "TARGET_USE_FANCY_MATH_387
14812 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14813 || TARGET_MIX_SSE_I387)
14814 && flag_unsafe_math_optimizations"
14815 {
14816 rtx op0, op1, op2;
14817
14818 if (optimize_insn_for_size_p ())
14819 FAIL;
14820
14821 op0 = gen_reg_rtx (XFmode);
14822 op1 = gen_reg_rtx (XFmode);
14823 op2 = gen_reg_rtx (XFmode);
14824
14825 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14826 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14827 emit_insn (gen_scalbxf3 (op0, op1, op2));
14828 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14829 DONE;
14830 })
14831
14832 (define_expand "significandxf2"
14833 [(parallel [(set (match_operand:XF 0 "register_operand")
14834 (unspec:XF [(match_operand:XF 1 "register_operand")]
14835 UNSPEC_XTRACT_FRACT))
14836 (set (match_dup 2)
14837 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14838 "TARGET_USE_FANCY_MATH_387
14839 && flag_unsafe_math_optimizations"
14840 "operands[2] = gen_reg_rtx (XFmode);")
14841
14842 (define_expand "significand<mode>2"
14843 [(use (match_operand:MODEF 0 "register_operand"))
14844 (use (match_operand:MODEF 1 "register_operand"))]
14845 "TARGET_USE_FANCY_MATH_387
14846 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14847 || TARGET_MIX_SSE_I387)
14848 && flag_unsafe_math_optimizations"
14849 {
14850 rtx op0 = gen_reg_rtx (XFmode);
14851 rtx op1 = gen_reg_rtx (XFmode);
14852
14853 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14854 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14855 DONE;
14856 })
14857 \f
14858
14859 (define_insn "sse4_1_round<mode>2"
14860 [(set (match_operand:MODEF 0 "register_operand" "=x")
14861 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14862 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14863 UNSPEC_ROUND))]
14864 "TARGET_ROUND"
14865 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14866 [(set_attr "type" "ssecvt")
14867 (set_attr "prefix_extra" "1")
14868 (set_attr "prefix" "maybe_vex")
14869 (set_attr "mode" "<MODE>")])
14870
14871 (define_insn "rintxf2"
14872 [(set (match_operand:XF 0 "register_operand" "=f")
14873 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14874 UNSPEC_FRNDINT))]
14875 "TARGET_USE_FANCY_MATH_387
14876 && flag_unsafe_math_optimizations"
14877 "frndint"
14878 [(set_attr "type" "fpspc")
14879 (set_attr "mode" "XF")])
14880
14881 (define_expand "rint<mode>2"
14882 [(use (match_operand:MODEF 0 "register_operand"))
14883 (use (match_operand:MODEF 1 "register_operand"))]
14884 "(TARGET_USE_FANCY_MATH_387
14885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14886 || TARGET_MIX_SSE_I387)
14887 && flag_unsafe_math_optimizations)
14888 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14889 && !flag_trapping_math)"
14890 {
14891 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14892 && !flag_trapping_math)
14893 {
14894 if (TARGET_ROUND)
14895 emit_insn (gen_sse4_1_round<mode>2
14896 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14897 else if (optimize_insn_for_size_p ())
14898 FAIL;
14899 else
14900 ix86_expand_rint (operands[0], operands[1]);
14901 }
14902 else
14903 {
14904 rtx op0 = gen_reg_rtx (XFmode);
14905 rtx op1 = gen_reg_rtx (XFmode);
14906
14907 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14908 emit_insn (gen_rintxf2 (op0, op1));
14909
14910 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14911 }
14912 DONE;
14913 })
14914
14915 (define_expand "round<mode>2"
14916 [(match_operand:X87MODEF 0 "register_operand")
14917 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14918 "(TARGET_USE_FANCY_MATH_387
14919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14920 || TARGET_MIX_SSE_I387)
14921 && flag_unsafe_math_optimizations)
14922 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14923 && !flag_trapping_math && !flag_rounding_math)"
14924 {
14925 if (optimize_insn_for_size_p ())
14926 FAIL;
14927
14928 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14929 && !flag_trapping_math && !flag_rounding_math)
14930 {
14931 if (TARGET_ROUND)
14932 {
14933 operands[1] = force_reg (<MODE>mode, operands[1]);
14934 ix86_expand_round_sse4 (operands[0], operands[1]);
14935 }
14936 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14937 ix86_expand_round (operands[0], operands[1]);
14938 else
14939 ix86_expand_rounddf_32 (operands[0], operands[1]);
14940 }
14941 else
14942 {
14943 operands[1] = force_reg (<MODE>mode, operands[1]);
14944 ix86_emit_i387_round (operands[0], operands[1]);
14945 }
14946 DONE;
14947 })
14948
14949 (define_insn_and_split "*fistdi2_1"
14950 [(set (match_operand:DI 0 "nonimmediate_operand")
14951 (unspec:DI [(match_operand:XF 1 "register_operand")]
14952 UNSPEC_FIST))]
14953 "TARGET_USE_FANCY_MATH_387
14954 && can_create_pseudo_p ()"
14955 "#"
14956 "&& 1"
14957 [(const_int 0)]
14958 {
14959 if (memory_operand (operands[0], VOIDmode))
14960 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14961 else
14962 {
14963 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14964 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14965 operands[2]));
14966 }
14967 DONE;
14968 }
14969 [(set_attr "type" "fpspc")
14970 (set_attr "mode" "DI")])
14971
14972 (define_insn "fistdi2"
14973 [(set (match_operand:DI 0 "memory_operand" "=m")
14974 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14975 UNSPEC_FIST))
14976 (clobber (match_scratch:XF 2 "=&1f"))]
14977 "TARGET_USE_FANCY_MATH_387"
14978 "* return output_fix_trunc (insn, operands, false);"
14979 [(set_attr "type" "fpspc")
14980 (set_attr "mode" "DI")])
14981
14982 (define_insn "fistdi2_with_temp"
14983 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14984 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14985 UNSPEC_FIST))
14986 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14987 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14988 "TARGET_USE_FANCY_MATH_387"
14989 "#"
14990 [(set_attr "type" "fpspc")
14991 (set_attr "mode" "DI")])
14992
14993 (define_split
14994 [(set (match_operand:DI 0 "register_operand")
14995 (unspec:DI [(match_operand:XF 1 "register_operand")]
14996 UNSPEC_FIST))
14997 (clobber (match_operand:DI 2 "memory_operand"))
14998 (clobber (match_scratch 3))]
14999 "reload_completed"
15000 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15001 (clobber (match_dup 3))])
15002 (set (match_dup 0) (match_dup 2))])
15003
15004 (define_split
15005 [(set (match_operand:DI 0 "memory_operand")
15006 (unspec:DI [(match_operand:XF 1 "register_operand")]
15007 UNSPEC_FIST))
15008 (clobber (match_operand:DI 2 "memory_operand"))
15009 (clobber (match_scratch 3))]
15010 "reload_completed"
15011 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15012 (clobber (match_dup 3))])])
15013
15014 (define_insn_and_split "*fist<mode>2_1"
15015 [(set (match_operand:SWI24 0 "register_operand")
15016 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15017 UNSPEC_FIST))]
15018 "TARGET_USE_FANCY_MATH_387
15019 && can_create_pseudo_p ()"
15020 "#"
15021 "&& 1"
15022 [(const_int 0)]
15023 {
15024 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15025 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15026 operands[2]));
15027 DONE;
15028 }
15029 [(set_attr "type" "fpspc")
15030 (set_attr "mode" "<MODE>")])
15031
15032 (define_insn "fist<mode>2"
15033 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15034 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15035 UNSPEC_FIST))]
15036 "TARGET_USE_FANCY_MATH_387"
15037 "* return output_fix_trunc (insn, operands, false);"
15038 [(set_attr "type" "fpspc")
15039 (set_attr "mode" "<MODE>")])
15040
15041 (define_insn "fist<mode>2_with_temp"
15042 [(set (match_operand:SWI24 0 "register_operand" "=r")
15043 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15044 UNSPEC_FIST))
15045 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15046 "TARGET_USE_FANCY_MATH_387"
15047 "#"
15048 [(set_attr "type" "fpspc")
15049 (set_attr "mode" "<MODE>")])
15050
15051 (define_split
15052 [(set (match_operand:SWI24 0 "register_operand")
15053 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15054 UNSPEC_FIST))
15055 (clobber (match_operand:SWI24 2 "memory_operand"))]
15056 "reload_completed"
15057 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15058 (set (match_dup 0) (match_dup 2))])
15059
15060 (define_split
15061 [(set (match_operand:SWI24 0 "memory_operand")
15062 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15063 UNSPEC_FIST))
15064 (clobber (match_operand:SWI24 2 "memory_operand"))]
15065 "reload_completed"
15066 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15067
15068 (define_expand "lrintxf<mode>2"
15069 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15070 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15071 UNSPEC_FIST))]
15072 "TARGET_USE_FANCY_MATH_387")
15073
15074 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15075 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15076 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15077 UNSPEC_FIX_NOTRUNC))]
15078 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15079 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15080
15081 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15082 [(match_operand:SWI248x 0 "nonimmediate_operand")
15083 (match_operand:X87MODEF 1 "register_operand")]
15084 "(TARGET_USE_FANCY_MATH_387
15085 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15086 || TARGET_MIX_SSE_I387)
15087 && flag_unsafe_math_optimizations)
15088 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15089 && <SWI248x:MODE>mode != HImode
15090 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15091 && !flag_trapping_math && !flag_rounding_math)"
15092 {
15093 if (optimize_insn_for_size_p ())
15094 FAIL;
15095
15096 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15097 && <SWI248x:MODE>mode != HImode
15098 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15099 && !flag_trapping_math && !flag_rounding_math)
15100 ix86_expand_lround (operands[0], operands[1]);
15101 else
15102 ix86_emit_i387_round (operands[0], operands[1]);
15103 DONE;
15104 })
15105
15106 (define_int_iterator FRNDINT_ROUNDING
15107 [UNSPEC_FRNDINT_FLOOR
15108 UNSPEC_FRNDINT_CEIL
15109 UNSPEC_FRNDINT_TRUNC])
15110
15111 (define_int_iterator FIST_ROUNDING
15112 [UNSPEC_FIST_FLOOR
15113 UNSPEC_FIST_CEIL])
15114
15115 ;; Base name for define_insn
15116 (define_int_attr rounding_insn
15117 [(UNSPEC_FRNDINT_FLOOR "floor")
15118 (UNSPEC_FRNDINT_CEIL "ceil")
15119 (UNSPEC_FRNDINT_TRUNC "btrunc")
15120 (UNSPEC_FIST_FLOOR "floor")
15121 (UNSPEC_FIST_CEIL "ceil")])
15122
15123 (define_int_attr rounding
15124 [(UNSPEC_FRNDINT_FLOOR "floor")
15125 (UNSPEC_FRNDINT_CEIL "ceil")
15126 (UNSPEC_FRNDINT_TRUNC "trunc")
15127 (UNSPEC_FIST_FLOOR "floor")
15128 (UNSPEC_FIST_CEIL "ceil")])
15129
15130 (define_int_attr ROUNDING
15131 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15132 (UNSPEC_FRNDINT_CEIL "CEIL")
15133 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15134 (UNSPEC_FIST_FLOOR "FLOOR")
15135 (UNSPEC_FIST_CEIL "CEIL")])
15136
15137 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15138 (define_insn_and_split "frndintxf2_<rounding>"
15139 [(set (match_operand:XF 0 "register_operand")
15140 (unspec:XF [(match_operand:XF 1 "register_operand")]
15141 FRNDINT_ROUNDING))
15142 (clobber (reg:CC FLAGS_REG))]
15143 "TARGET_USE_FANCY_MATH_387
15144 && flag_unsafe_math_optimizations
15145 && can_create_pseudo_p ()"
15146 "#"
15147 "&& 1"
15148 [(const_int 0)]
15149 {
15150 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15151
15152 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15153 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15154
15155 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15156 operands[2], operands[3]));
15157 DONE;
15158 }
15159 [(set_attr "type" "frndint")
15160 (set_attr "i387_cw" "<rounding>")
15161 (set_attr "mode" "XF")])
15162
15163 (define_insn "frndintxf2_<rounding>_i387"
15164 [(set (match_operand:XF 0 "register_operand" "=f")
15165 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15166 FRNDINT_ROUNDING))
15167 (use (match_operand:HI 2 "memory_operand" "m"))
15168 (use (match_operand:HI 3 "memory_operand" "m"))]
15169 "TARGET_USE_FANCY_MATH_387
15170 && flag_unsafe_math_optimizations"
15171 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15172 [(set_attr "type" "frndint")
15173 (set_attr "i387_cw" "<rounding>")
15174 (set_attr "mode" "XF")])
15175
15176 (define_expand "<rounding_insn>xf2"
15177 [(parallel [(set (match_operand:XF 0 "register_operand")
15178 (unspec:XF [(match_operand:XF 1 "register_operand")]
15179 FRNDINT_ROUNDING))
15180 (clobber (reg:CC FLAGS_REG))])]
15181 "TARGET_USE_FANCY_MATH_387
15182 && flag_unsafe_math_optimizations
15183 && !optimize_insn_for_size_p ()")
15184
15185 (define_expand "<rounding_insn><mode>2"
15186 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15187 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15188 FRNDINT_ROUNDING))
15189 (clobber (reg:CC FLAGS_REG))])]
15190 "(TARGET_USE_FANCY_MATH_387
15191 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15192 || TARGET_MIX_SSE_I387)
15193 && flag_unsafe_math_optimizations)
15194 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15195 && !flag_trapping_math)"
15196 {
15197 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15198 && !flag_trapping_math)
15199 {
15200 if (TARGET_ROUND)
15201 emit_insn (gen_sse4_1_round<mode>2
15202 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15203 else if (optimize_insn_for_size_p ())
15204 FAIL;
15205 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15206 {
15207 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15208 ix86_expand_floorceil (operands[0], operands[1], true);
15209 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15210 ix86_expand_floorceil (operands[0], operands[1], false);
15211 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15212 ix86_expand_trunc (operands[0], operands[1]);
15213 else
15214 gcc_unreachable ();
15215 }
15216 else
15217 {
15218 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15219 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15220 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15221 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15222 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15223 ix86_expand_truncdf_32 (operands[0], operands[1]);
15224 else
15225 gcc_unreachable ();
15226 }
15227 }
15228 else
15229 {
15230 rtx op0, op1;
15231
15232 if (optimize_insn_for_size_p ())
15233 FAIL;
15234
15235 op0 = gen_reg_rtx (XFmode);
15236 op1 = gen_reg_rtx (XFmode);
15237 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15238 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15239
15240 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15241 }
15242 DONE;
15243 })
15244
15245 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15246 (define_insn_and_split "frndintxf2_mask_pm"
15247 [(set (match_operand:XF 0 "register_operand")
15248 (unspec:XF [(match_operand:XF 1 "register_operand")]
15249 UNSPEC_FRNDINT_MASK_PM))
15250 (clobber (reg:CC FLAGS_REG))]
15251 "TARGET_USE_FANCY_MATH_387
15252 && flag_unsafe_math_optimizations
15253 && can_create_pseudo_p ()"
15254 "#"
15255 "&& 1"
15256 [(const_int 0)]
15257 {
15258 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15259
15260 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15261 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15262
15263 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15264 operands[2], operands[3]));
15265 DONE;
15266 }
15267 [(set_attr "type" "frndint")
15268 (set_attr "i387_cw" "mask_pm")
15269 (set_attr "mode" "XF")])
15270
15271 (define_insn "frndintxf2_mask_pm_i387"
15272 [(set (match_operand:XF 0 "register_operand" "=f")
15273 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15274 UNSPEC_FRNDINT_MASK_PM))
15275 (use (match_operand:HI 2 "memory_operand" "m"))
15276 (use (match_operand:HI 3 "memory_operand" "m"))]
15277 "TARGET_USE_FANCY_MATH_387
15278 && flag_unsafe_math_optimizations"
15279 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15280 [(set_attr "type" "frndint")
15281 (set_attr "i387_cw" "mask_pm")
15282 (set_attr "mode" "XF")])
15283
15284 (define_expand "nearbyintxf2"
15285 [(parallel [(set (match_operand:XF 0 "register_operand")
15286 (unspec:XF [(match_operand:XF 1 "register_operand")]
15287 UNSPEC_FRNDINT_MASK_PM))
15288 (clobber (reg:CC FLAGS_REG))])]
15289 "TARGET_USE_FANCY_MATH_387
15290 && flag_unsafe_math_optimizations")
15291
15292 (define_expand "nearbyint<mode>2"
15293 [(use (match_operand:MODEF 0 "register_operand"))
15294 (use (match_operand:MODEF 1 "register_operand"))]
15295 "TARGET_USE_FANCY_MATH_387
15296 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15297 || TARGET_MIX_SSE_I387)
15298 && flag_unsafe_math_optimizations"
15299 {
15300 rtx op0 = gen_reg_rtx (XFmode);
15301 rtx op1 = gen_reg_rtx (XFmode);
15302
15303 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15304 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15305
15306 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15307 DONE;
15308 })
15309
15310 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15311 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15312 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15313 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15314 FIST_ROUNDING))
15315 (clobber (reg:CC FLAGS_REG))]
15316 "TARGET_USE_FANCY_MATH_387
15317 && flag_unsafe_math_optimizations
15318 && can_create_pseudo_p ()"
15319 "#"
15320 "&& 1"
15321 [(const_int 0)]
15322 {
15323 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15324
15325 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15326 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15327 if (memory_operand (operands[0], VOIDmode))
15328 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15329 operands[2], operands[3]));
15330 else
15331 {
15332 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15333 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15334 (operands[0], operands[1], operands[2],
15335 operands[3], operands[4]));
15336 }
15337 DONE;
15338 }
15339 [(set_attr "type" "fistp")
15340 (set_attr "i387_cw" "<rounding>")
15341 (set_attr "mode" "<MODE>")])
15342
15343 (define_insn "fistdi2_<rounding>"
15344 [(set (match_operand:DI 0 "memory_operand" "=m")
15345 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15346 FIST_ROUNDING))
15347 (use (match_operand:HI 2 "memory_operand" "m"))
15348 (use (match_operand:HI 3 "memory_operand" "m"))
15349 (clobber (match_scratch:XF 4 "=&1f"))]
15350 "TARGET_USE_FANCY_MATH_387
15351 && flag_unsafe_math_optimizations"
15352 "* return output_fix_trunc (insn, operands, false);"
15353 [(set_attr "type" "fistp")
15354 (set_attr "i387_cw" "<rounding>")
15355 (set_attr "mode" "DI")])
15356
15357 (define_insn "fistdi2_<rounding>_with_temp"
15358 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15359 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15360 FIST_ROUNDING))
15361 (use (match_operand:HI 2 "memory_operand" "m,m"))
15362 (use (match_operand:HI 3 "memory_operand" "m,m"))
15363 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15364 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15365 "TARGET_USE_FANCY_MATH_387
15366 && flag_unsafe_math_optimizations"
15367 "#"
15368 [(set_attr "type" "fistp")
15369 (set_attr "i387_cw" "<rounding>")
15370 (set_attr "mode" "DI")])
15371
15372 (define_split
15373 [(set (match_operand:DI 0 "register_operand")
15374 (unspec:DI [(match_operand:XF 1 "register_operand")]
15375 FIST_ROUNDING))
15376 (use (match_operand:HI 2 "memory_operand"))
15377 (use (match_operand:HI 3 "memory_operand"))
15378 (clobber (match_operand:DI 4 "memory_operand"))
15379 (clobber (match_scratch 5))]
15380 "reload_completed"
15381 [(parallel [(set (match_dup 4)
15382 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15383 (use (match_dup 2))
15384 (use (match_dup 3))
15385 (clobber (match_dup 5))])
15386 (set (match_dup 0) (match_dup 4))])
15387
15388 (define_split
15389 [(set (match_operand:DI 0 "memory_operand")
15390 (unspec:DI [(match_operand:XF 1 "register_operand")]
15391 FIST_ROUNDING))
15392 (use (match_operand:HI 2 "memory_operand"))
15393 (use (match_operand:HI 3 "memory_operand"))
15394 (clobber (match_operand:DI 4 "memory_operand"))
15395 (clobber (match_scratch 5))]
15396 "reload_completed"
15397 [(parallel [(set (match_dup 0)
15398 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15399 (use (match_dup 2))
15400 (use (match_dup 3))
15401 (clobber (match_dup 5))])])
15402
15403 (define_insn "fist<mode>2_<rounding>"
15404 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15405 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15406 FIST_ROUNDING))
15407 (use (match_operand:HI 2 "memory_operand" "m"))
15408 (use (match_operand:HI 3 "memory_operand" "m"))]
15409 "TARGET_USE_FANCY_MATH_387
15410 && flag_unsafe_math_optimizations"
15411 "* return output_fix_trunc (insn, operands, false);"
15412 [(set_attr "type" "fistp")
15413 (set_attr "i387_cw" "<rounding>")
15414 (set_attr "mode" "<MODE>")])
15415
15416 (define_insn "fist<mode>2_<rounding>_with_temp"
15417 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15418 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15419 FIST_ROUNDING))
15420 (use (match_operand:HI 2 "memory_operand" "m,m"))
15421 (use (match_operand:HI 3 "memory_operand" "m,m"))
15422 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15423 "TARGET_USE_FANCY_MATH_387
15424 && flag_unsafe_math_optimizations"
15425 "#"
15426 [(set_attr "type" "fistp")
15427 (set_attr "i387_cw" "<rounding>")
15428 (set_attr "mode" "<MODE>")])
15429
15430 (define_split
15431 [(set (match_operand:SWI24 0 "register_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 4)
15439 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15440 (use (match_dup 2))
15441 (use (match_dup 3))])
15442 (set (match_dup 0) (match_dup 4))])
15443
15444 (define_split
15445 [(set (match_operand:SWI24 0 "memory_operand")
15446 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15447 FIST_ROUNDING))
15448 (use (match_operand:HI 2 "memory_operand"))
15449 (use (match_operand:HI 3 "memory_operand"))
15450 (clobber (match_operand:SWI24 4 "memory_operand"))]
15451 "reload_completed"
15452 [(parallel [(set (match_dup 0)
15453 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15454 (use (match_dup 2))
15455 (use (match_dup 3))])])
15456
15457 (define_expand "l<rounding_insn>xf<mode>2"
15458 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15459 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15460 FIST_ROUNDING))
15461 (clobber (reg:CC FLAGS_REG))])]
15462 "TARGET_USE_FANCY_MATH_387
15463 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15464 && flag_unsafe_math_optimizations")
15465
15466 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15467 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15468 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15469 FIST_ROUNDING))
15470 (clobber (reg:CC FLAGS_REG))])]
15471 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15472 && !flag_trapping_math"
15473 {
15474 if (TARGET_64BIT && optimize_insn_for_size_p ())
15475 FAIL;
15476
15477 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15478 ix86_expand_lfloorceil (operands[0], operands[1], true);
15479 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15480 ix86_expand_lfloorceil (operands[0], operands[1], false);
15481 else
15482 gcc_unreachable ();
15483
15484 DONE;
15485 })
15486
15487 (define_insn "fxam<mode>2_i387"
15488 [(set (match_operand:HI 0 "register_operand" "=a")
15489 (unspec:HI
15490 [(match_operand:X87MODEF 1 "register_operand" "f")]
15491 UNSPEC_FXAM))]
15492 "TARGET_USE_FANCY_MATH_387"
15493 "fxam\n\tfnstsw\t%0"
15494 [(set_attr "type" "multi")
15495 (set_attr "length" "4")
15496 (set_attr "unit" "i387")
15497 (set_attr "mode" "<MODE>")])
15498
15499 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15500 [(set (match_operand:HI 0 "register_operand")
15501 (unspec:HI
15502 [(match_operand:MODEF 1 "memory_operand")]
15503 UNSPEC_FXAM_MEM))]
15504 "TARGET_USE_FANCY_MATH_387
15505 && can_create_pseudo_p ()"
15506 "#"
15507 "&& 1"
15508 [(set (match_dup 2)(match_dup 1))
15509 (set (match_dup 0)
15510 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15511 {
15512 operands[2] = gen_reg_rtx (<MODE>mode);
15513
15514 MEM_VOLATILE_P (operands[1]) = 1;
15515 }
15516 [(set_attr "type" "multi")
15517 (set_attr "unit" "i387")
15518 (set_attr "mode" "<MODE>")])
15519
15520 (define_expand "isinfxf2"
15521 [(use (match_operand:SI 0 "register_operand"))
15522 (use (match_operand:XF 1 "register_operand"))]
15523 "TARGET_USE_FANCY_MATH_387
15524 && TARGET_C99_FUNCTIONS"
15525 {
15526 rtx mask = GEN_INT (0x45);
15527 rtx val = GEN_INT (0x05);
15528
15529 rtx cond;
15530
15531 rtx scratch = gen_reg_rtx (HImode);
15532 rtx res = gen_reg_rtx (QImode);
15533
15534 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15535
15536 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15537 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15538 cond = gen_rtx_fmt_ee (EQ, QImode,
15539 gen_rtx_REG (CCmode, FLAGS_REG),
15540 const0_rtx);
15541 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15542 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15543 DONE;
15544 })
15545
15546 (define_expand "isinf<mode>2"
15547 [(use (match_operand:SI 0 "register_operand"))
15548 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15549 "TARGET_USE_FANCY_MATH_387
15550 && TARGET_C99_FUNCTIONS
15551 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15552 {
15553 rtx mask = GEN_INT (0x45);
15554 rtx val = GEN_INT (0x05);
15555
15556 rtx cond;
15557
15558 rtx scratch = gen_reg_rtx (HImode);
15559 rtx res = gen_reg_rtx (QImode);
15560
15561 /* Remove excess precision by forcing value through memory. */
15562 if (memory_operand (operands[1], VOIDmode))
15563 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15564 else
15565 {
15566 enum ix86_stack_slot slot = (virtuals_instantiated
15567 ? SLOT_TEMP
15568 : SLOT_VIRTUAL);
15569 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15570
15571 emit_move_insn (temp, operands[1]);
15572 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15573 }
15574
15575 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15576 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15577 cond = gen_rtx_fmt_ee (EQ, QImode,
15578 gen_rtx_REG (CCmode, FLAGS_REG),
15579 const0_rtx);
15580 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15581 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15582 DONE;
15583 })
15584
15585 (define_expand "signbitxf2"
15586 [(use (match_operand:SI 0 "register_operand"))
15587 (use (match_operand:XF 1 "register_operand"))]
15588 "TARGET_USE_FANCY_MATH_387"
15589 {
15590 rtx scratch = gen_reg_rtx (HImode);
15591
15592 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15593 emit_insn (gen_andsi3 (operands[0],
15594 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15595 DONE;
15596 })
15597
15598 (define_insn "movmsk_df"
15599 [(set (match_operand:SI 0 "register_operand" "=r")
15600 (unspec:SI
15601 [(match_operand:DF 1 "register_operand" "x")]
15602 UNSPEC_MOVMSK))]
15603 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15604 "%vmovmskpd\t{%1, %0|%0, %1}"
15605 [(set_attr "type" "ssemov")
15606 (set_attr "prefix" "maybe_vex")
15607 (set_attr "mode" "DF")])
15608
15609 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15610 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15611 (define_expand "signbitdf2"
15612 [(use (match_operand:SI 0 "register_operand"))
15613 (use (match_operand:DF 1 "register_operand"))]
15614 "TARGET_USE_FANCY_MATH_387
15615 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15616 {
15617 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15618 {
15619 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15620 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15621 }
15622 else
15623 {
15624 rtx scratch = gen_reg_rtx (HImode);
15625
15626 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15627 emit_insn (gen_andsi3 (operands[0],
15628 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15629 }
15630 DONE;
15631 })
15632
15633 (define_expand "signbitsf2"
15634 [(use (match_operand:SI 0 "register_operand"))
15635 (use (match_operand:SF 1 "register_operand"))]
15636 "TARGET_USE_FANCY_MATH_387
15637 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15638 {
15639 rtx scratch = gen_reg_rtx (HImode);
15640
15641 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15642 emit_insn (gen_andsi3 (operands[0],
15643 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15644 DONE;
15645 })
15646 \f
15647 ;; Block operation instructions
15648
15649 (define_insn "cld"
15650 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15651 ""
15652 "cld"
15653 [(set_attr "length" "1")
15654 (set_attr "length_immediate" "0")
15655 (set_attr "modrm" "0")])
15656
15657 (define_expand "movmem<mode>"
15658 [(use (match_operand:BLK 0 "memory_operand"))
15659 (use (match_operand:BLK 1 "memory_operand"))
15660 (use (match_operand:SWI48 2 "nonmemory_operand"))
15661 (use (match_operand:SWI48 3 "const_int_operand"))
15662 (use (match_operand:SI 4 "const_int_operand"))
15663 (use (match_operand:SI 5 "const_int_operand"))]
15664 ""
15665 {
15666 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15667 operands[4], operands[5]))
15668 DONE;
15669 else
15670 FAIL;
15671 })
15672
15673 ;; Most CPUs don't like single string operations
15674 ;; Handle this case here to simplify previous expander.
15675
15676 (define_expand "strmov"
15677 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15678 (set (match_operand 1 "memory_operand") (match_dup 4))
15679 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15680 (clobber (reg:CC FLAGS_REG))])
15681 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15682 (clobber (reg:CC FLAGS_REG))])]
15683 ""
15684 {
15685 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15686
15687 /* If .md ever supports :P for Pmode, these can be directly
15688 in the pattern above. */
15689 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15690 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15691
15692 /* Can't use this if the user has appropriated esi or edi. */
15693 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15694 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15695 {
15696 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15697 operands[2], operands[3],
15698 operands[5], operands[6]));
15699 DONE;
15700 }
15701
15702 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15703 })
15704
15705 (define_expand "strmov_singleop"
15706 [(parallel [(set (match_operand 1 "memory_operand")
15707 (match_operand 3 "memory_operand"))
15708 (set (match_operand 0 "register_operand")
15709 (match_operand 4))
15710 (set (match_operand 2 "register_operand")
15711 (match_operand 5))])]
15712 ""
15713 "ix86_current_function_needs_cld = 1;")
15714
15715 (define_insn "*strmovdi_rex_1"
15716 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15717 (mem:DI (match_operand:P 3 "register_operand" "1")))
15718 (set (match_operand:P 0 "register_operand" "=D")
15719 (plus:P (match_dup 2)
15720 (const_int 8)))
15721 (set (match_operand:P 1 "register_operand" "=S")
15722 (plus:P (match_dup 3)
15723 (const_int 8)))]
15724 "TARGET_64BIT
15725 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15726 "%^movsq"
15727 [(set_attr "type" "str")
15728 (set_attr "memory" "both")
15729 (set_attr "mode" "DI")])
15730
15731 (define_insn "*strmovsi_1"
15732 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15733 (mem:SI (match_operand:P 3 "register_operand" "1")))
15734 (set (match_operand:P 0 "register_operand" "=D")
15735 (plus:P (match_dup 2)
15736 (const_int 4)))
15737 (set (match_operand:P 1 "register_operand" "=S")
15738 (plus:P (match_dup 3)
15739 (const_int 4)))]
15740 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15741 "%^movs{l|d}"
15742 [(set_attr "type" "str")
15743 (set_attr "memory" "both")
15744 (set_attr "mode" "SI")])
15745
15746 (define_insn "*strmovhi_1"
15747 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15748 (mem:HI (match_operand:P 3 "register_operand" "1")))
15749 (set (match_operand:P 0 "register_operand" "=D")
15750 (plus:P (match_dup 2)
15751 (const_int 2)))
15752 (set (match_operand:P 1 "register_operand" "=S")
15753 (plus:P (match_dup 3)
15754 (const_int 2)))]
15755 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15756 "%^movsw"
15757 [(set_attr "type" "str")
15758 (set_attr "memory" "both")
15759 (set_attr "mode" "HI")])
15760
15761 (define_insn "*strmovqi_1"
15762 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15763 (mem:QI (match_operand:P 3 "register_operand" "1")))
15764 (set (match_operand:P 0 "register_operand" "=D")
15765 (plus:P (match_dup 2)
15766 (const_int 1)))
15767 (set (match_operand:P 1 "register_operand" "=S")
15768 (plus:P (match_dup 3)
15769 (const_int 1)))]
15770 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15771 "%^movsb"
15772 [(set_attr "type" "str")
15773 (set_attr "memory" "both")
15774 (set (attr "prefix_rex")
15775 (if_then_else
15776 (match_test "<P:MODE>mode == DImode")
15777 (const_string "0")
15778 (const_string "*")))
15779 (set_attr "mode" "QI")])
15780
15781 (define_expand "rep_mov"
15782 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15783 (set (match_operand 0 "register_operand")
15784 (match_operand 5))
15785 (set (match_operand 2 "register_operand")
15786 (match_operand 6))
15787 (set (match_operand 1 "memory_operand")
15788 (match_operand 3 "memory_operand"))
15789 (use (match_dup 4))])]
15790 ""
15791 "ix86_current_function_needs_cld = 1;")
15792
15793 (define_insn "*rep_movdi_rex64"
15794 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15795 (set (match_operand:P 0 "register_operand" "=D")
15796 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15797 (const_int 3))
15798 (match_operand:P 3 "register_operand" "0")))
15799 (set (match_operand:P 1 "register_operand" "=S")
15800 (plus:P (ashift:P (match_dup 5) (const_int 3))
15801 (match_operand:P 4 "register_operand" "1")))
15802 (set (mem:BLK (match_dup 3))
15803 (mem:BLK (match_dup 4)))
15804 (use (match_dup 5))]
15805 "TARGET_64BIT
15806 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15807 "%^rep{%;} movsq"
15808 [(set_attr "type" "str")
15809 (set_attr "prefix_rep" "1")
15810 (set_attr "memory" "both")
15811 (set_attr "mode" "DI")])
15812
15813 (define_insn "*rep_movsi"
15814 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15815 (set (match_operand:P 0 "register_operand" "=D")
15816 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15817 (const_int 2))
15818 (match_operand:P 3 "register_operand" "0")))
15819 (set (match_operand:P 1 "register_operand" "=S")
15820 (plus:P (ashift:P (match_dup 5) (const_int 2))
15821 (match_operand:P 4 "register_operand" "1")))
15822 (set (mem:BLK (match_dup 3))
15823 (mem:BLK (match_dup 4)))
15824 (use (match_dup 5))]
15825 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15826 "%^rep{%;} movs{l|d}"
15827 [(set_attr "type" "str")
15828 (set_attr "prefix_rep" "1")
15829 (set_attr "memory" "both")
15830 (set_attr "mode" "SI")])
15831
15832 (define_insn "*rep_movqi"
15833 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15834 (set (match_operand:P 0 "register_operand" "=D")
15835 (plus:P (match_operand:P 3 "register_operand" "0")
15836 (match_operand:P 5 "register_operand" "2")))
15837 (set (match_operand:P 1 "register_operand" "=S")
15838 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15839 (set (mem:BLK (match_dup 3))
15840 (mem:BLK (match_dup 4)))
15841 (use (match_dup 5))]
15842 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15843 "%^rep{%;} movsb"
15844 [(set_attr "type" "str")
15845 (set_attr "prefix_rep" "1")
15846 (set_attr "memory" "both")
15847 (set_attr "mode" "QI")])
15848
15849 (define_expand "setmem<mode>"
15850 [(use (match_operand:BLK 0 "memory_operand"))
15851 (use (match_operand:SWI48 1 "nonmemory_operand"))
15852 (use (match_operand:QI 2 "nonmemory_operand"))
15853 (use (match_operand 3 "const_int_operand"))
15854 (use (match_operand:SI 4 "const_int_operand"))
15855 (use (match_operand:SI 5 "const_int_operand"))]
15856 ""
15857 {
15858 if (ix86_expand_setmem (operands[0], operands[1],
15859 operands[2], operands[3],
15860 operands[4], operands[5]))
15861 DONE;
15862 else
15863 FAIL;
15864 })
15865
15866 ;; Most CPUs don't like single string operations
15867 ;; Handle this case here to simplify previous expander.
15868
15869 (define_expand "strset"
15870 [(set (match_operand 1 "memory_operand")
15871 (match_operand 2 "register_operand"))
15872 (parallel [(set (match_operand 0 "register_operand")
15873 (match_dup 3))
15874 (clobber (reg:CC FLAGS_REG))])]
15875 ""
15876 {
15877 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15878 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15879
15880 /* If .md ever supports :P for Pmode, this can be directly
15881 in the pattern above. */
15882 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15883 GEN_INT (GET_MODE_SIZE (GET_MODE
15884 (operands[2]))));
15885 /* Can't use this if the user has appropriated eax or edi. */
15886 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15887 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15888 {
15889 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15890 operands[3]));
15891 DONE;
15892 }
15893 })
15894
15895 (define_expand "strset_singleop"
15896 [(parallel [(set (match_operand 1 "memory_operand")
15897 (match_operand 2 "register_operand"))
15898 (set (match_operand 0 "register_operand")
15899 (match_operand 3))])]
15900 ""
15901 "ix86_current_function_needs_cld = 1;")
15902
15903 (define_insn "*strsetdi_rex_1"
15904 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15905 (match_operand:DI 2 "register_operand" "a"))
15906 (set (match_operand:P 0 "register_operand" "=D")
15907 (plus:P (match_dup 1)
15908 (const_int 8)))]
15909 "TARGET_64BIT
15910 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15911 "%^stosq"
15912 [(set_attr "type" "str")
15913 (set_attr "memory" "store")
15914 (set_attr "mode" "DI")])
15915
15916 (define_insn "*strsetsi_1"
15917 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15918 (match_operand:SI 2 "register_operand" "a"))
15919 (set (match_operand:P 0 "register_operand" "=D")
15920 (plus:P (match_dup 1)
15921 (const_int 4)))]
15922 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15923 "%^stos{l|d}"
15924 [(set_attr "type" "str")
15925 (set_attr "memory" "store")
15926 (set_attr "mode" "SI")])
15927
15928 (define_insn "*strsethi_1"
15929 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15930 (match_operand:HI 2 "register_operand" "a"))
15931 (set (match_operand:P 0 "register_operand" "=D")
15932 (plus:P (match_dup 1)
15933 (const_int 2)))]
15934 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15935 "%^stosw"
15936 [(set_attr "type" "str")
15937 (set_attr "memory" "store")
15938 (set_attr "mode" "HI")])
15939
15940 (define_insn "*strsetqi_1"
15941 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15942 (match_operand:QI 2 "register_operand" "a"))
15943 (set (match_operand:P 0 "register_operand" "=D")
15944 (plus:P (match_dup 1)
15945 (const_int 1)))]
15946 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15947 "%^stosb"
15948 [(set_attr "type" "str")
15949 (set_attr "memory" "store")
15950 (set (attr "prefix_rex")
15951 (if_then_else
15952 (match_test "<P:MODE>mode == DImode")
15953 (const_string "0")
15954 (const_string "*")))
15955 (set_attr "mode" "QI")])
15956
15957 (define_expand "rep_stos"
15958 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15959 (set (match_operand 0 "register_operand")
15960 (match_operand 4))
15961 (set (match_operand 2 "memory_operand") (const_int 0))
15962 (use (match_operand 3 "register_operand"))
15963 (use (match_dup 1))])]
15964 ""
15965 "ix86_current_function_needs_cld = 1;")
15966
15967 (define_insn "*rep_stosdi_rex64"
15968 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15969 (set (match_operand:P 0 "register_operand" "=D")
15970 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15971 (const_int 3))
15972 (match_operand:P 3 "register_operand" "0")))
15973 (set (mem:BLK (match_dup 3))
15974 (const_int 0))
15975 (use (match_operand:DI 2 "register_operand" "a"))
15976 (use (match_dup 4))]
15977 "TARGET_64BIT
15978 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15979 "%^rep{%;} stosq"
15980 [(set_attr "type" "str")
15981 (set_attr "prefix_rep" "1")
15982 (set_attr "memory" "store")
15983 (set_attr "mode" "DI")])
15984
15985 (define_insn "*rep_stossi"
15986 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15987 (set (match_operand:P 0 "register_operand" "=D")
15988 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15989 (const_int 2))
15990 (match_operand:P 3 "register_operand" "0")))
15991 (set (mem:BLK (match_dup 3))
15992 (const_int 0))
15993 (use (match_operand:SI 2 "register_operand" "a"))
15994 (use (match_dup 4))]
15995 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15996 "%^rep{%;} stos{l|d}"
15997 [(set_attr "type" "str")
15998 (set_attr "prefix_rep" "1")
15999 (set_attr "memory" "store")
16000 (set_attr "mode" "SI")])
16001
16002 (define_insn "*rep_stosqi"
16003 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16004 (set (match_operand:P 0 "register_operand" "=D")
16005 (plus:P (match_operand:P 3 "register_operand" "0")
16006 (match_operand:P 4 "register_operand" "1")))
16007 (set (mem:BLK (match_dup 3))
16008 (const_int 0))
16009 (use (match_operand:QI 2 "register_operand" "a"))
16010 (use (match_dup 4))]
16011 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16012 "%^rep{%;} stosb"
16013 [(set_attr "type" "str")
16014 (set_attr "prefix_rep" "1")
16015 (set_attr "memory" "store")
16016 (set (attr "prefix_rex")
16017 (if_then_else
16018 (match_test "<P:MODE>mode == DImode")
16019 (const_string "0")
16020 (const_string "*")))
16021 (set_attr "mode" "QI")])
16022
16023 (define_expand "cmpstrnsi"
16024 [(set (match_operand:SI 0 "register_operand")
16025 (compare:SI (match_operand:BLK 1 "general_operand")
16026 (match_operand:BLK 2 "general_operand")))
16027 (use (match_operand 3 "general_operand"))
16028 (use (match_operand 4 "immediate_operand"))]
16029 ""
16030 {
16031 rtx addr1, addr2, out, outlow, count, countreg, align;
16032
16033 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16034 FAIL;
16035
16036 /* Can't use this if the user has appropriated ecx, esi or edi. */
16037 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16038 FAIL;
16039
16040 out = operands[0];
16041 if (!REG_P (out))
16042 out = gen_reg_rtx (SImode);
16043
16044 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16045 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16046 if (addr1 != XEXP (operands[1], 0))
16047 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16048 if (addr2 != XEXP (operands[2], 0))
16049 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16050
16051 count = operands[3];
16052 countreg = ix86_zero_extend_to_Pmode (count);
16053
16054 /* %%% Iff we are testing strict equality, we can use known alignment
16055 to good advantage. This may be possible with combine, particularly
16056 once cc0 is dead. */
16057 align = operands[4];
16058
16059 if (CONST_INT_P (count))
16060 {
16061 if (INTVAL (count) == 0)
16062 {
16063 emit_move_insn (operands[0], const0_rtx);
16064 DONE;
16065 }
16066 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16067 operands[1], operands[2]));
16068 }
16069 else
16070 {
16071 rtx (*gen_cmp) (rtx, rtx);
16072
16073 gen_cmp = (TARGET_64BIT
16074 ? gen_cmpdi_1 : gen_cmpsi_1);
16075
16076 emit_insn (gen_cmp (countreg, countreg));
16077 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16078 operands[1], operands[2]));
16079 }
16080
16081 outlow = gen_lowpart (QImode, out);
16082 emit_insn (gen_cmpintqi (outlow));
16083 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16084
16085 if (operands[0] != out)
16086 emit_move_insn (operands[0], out);
16087
16088 DONE;
16089 })
16090
16091 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16092
16093 (define_expand "cmpintqi"
16094 [(set (match_dup 1)
16095 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16096 (set (match_dup 2)
16097 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16098 (parallel [(set (match_operand:QI 0 "register_operand")
16099 (minus:QI (match_dup 1)
16100 (match_dup 2)))
16101 (clobber (reg:CC FLAGS_REG))])]
16102 ""
16103 {
16104 operands[1] = gen_reg_rtx (QImode);
16105 operands[2] = gen_reg_rtx (QImode);
16106 })
16107
16108 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16109 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16110
16111 (define_expand "cmpstrnqi_nz_1"
16112 [(parallel [(set (reg:CC FLAGS_REG)
16113 (compare:CC (match_operand 4 "memory_operand")
16114 (match_operand 5 "memory_operand")))
16115 (use (match_operand 2 "register_operand"))
16116 (use (match_operand:SI 3 "immediate_operand"))
16117 (clobber (match_operand 0 "register_operand"))
16118 (clobber (match_operand 1 "register_operand"))
16119 (clobber (match_dup 2))])]
16120 ""
16121 "ix86_current_function_needs_cld = 1;")
16122
16123 (define_insn "*cmpstrnqi_nz_1"
16124 [(set (reg:CC FLAGS_REG)
16125 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16126 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16127 (use (match_operand:P 6 "register_operand" "2"))
16128 (use (match_operand:SI 3 "immediate_operand" "i"))
16129 (clobber (match_operand:P 0 "register_operand" "=S"))
16130 (clobber (match_operand:P 1 "register_operand" "=D"))
16131 (clobber (match_operand:P 2 "register_operand" "=c"))]
16132 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16133 "%^repz{%;} cmpsb"
16134 [(set_attr "type" "str")
16135 (set_attr "mode" "QI")
16136 (set (attr "prefix_rex")
16137 (if_then_else
16138 (match_test "<P:MODE>mode == DImode")
16139 (const_string "0")
16140 (const_string "*")))
16141 (set_attr "prefix_rep" "1")])
16142
16143 ;; The same, but the count is not known to not be zero.
16144
16145 (define_expand "cmpstrnqi_1"
16146 [(parallel [(set (reg:CC FLAGS_REG)
16147 (if_then_else:CC (ne (match_operand 2 "register_operand")
16148 (const_int 0))
16149 (compare:CC (match_operand 4 "memory_operand")
16150 (match_operand 5 "memory_operand"))
16151 (const_int 0)))
16152 (use (match_operand:SI 3 "immediate_operand"))
16153 (use (reg:CC FLAGS_REG))
16154 (clobber (match_operand 0 "register_operand"))
16155 (clobber (match_operand 1 "register_operand"))
16156 (clobber (match_dup 2))])]
16157 ""
16158 "ix86_current_function_needs_cld = 1;")
16159
16160 (define_insn "*cmpstrnqi_1"
16161 [(set (reg:CC FLAGS_REG)
16162 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16163 (const_int 0))
16164 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16165 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16166 (const_int 0)))
16167 (use (match_operand:SI 3 "immediate_operand" "i"))
16168 (use (reg:CC FLAGS_REG))
16169 (clobber (match_operand:P 0 "register_operand" "=S"))
16170 (clobber (match_operand:P 1 "register_operand" "=D"))
16171 (clobber (match_operand:P 2 "register_operand" "=c"))]
16172 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16173 "%^repz{%;} cmpsb"
16174 [(set_attr "type" "str")
16175 (set_attr "mode" "QI")
16176 (set (attr "prefix_rex")
16177 (if_then_else
16178 (match_test "<P:MODE>mode == DImode")
16179 (const_string "0")
16180 (const_string "*")))
16181 (set_attr "prefix_rep" "1")])
16182
16183 (define_expand "strlen<mode>"
16184 [(set (match_operand:P 0 "register_operand")
16185 (unspec:P [(match_operand:BLK 1 "general_operand")
16186 (match_operand:QI 2 "immediate_operand")
16187 (match_operand 3 "immediate_operand")]
16188 UNSPEC_SCAS))]
16189 ""
16190 {
16191 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16192 DONE;
16193 else
16194 FAIL;
16195 })
16196
16197 (define_expand "strlenqi_1"
16198 [(parallel [(set (match_operand 0 "register_operand")
16199 (match_operand 2))
16200 (clobber (match_operand 1 "register_operand"))
16201 (clobber (reg:CC FLAGS_REG))])]
16202 ""
16203 "ix86_current_function_needs_cld = 1;")
16204
16205 (define_insn "*strlenqi_1"
16206 [(set (match_operand:P 0 "register_operand" "=&c")
16207 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16208 (match_operand:QI 2 "register_operand" "a")
16209 (match_operand:P 3 "immediate_operand" "i")
16210 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16211 (clobber (match_operand:P 1 "register_operand" "=D"))
16212 (clobber (reg:CC FLAGS_REG))]
16213 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16214 "%^repnz{%;} scasb"
16215 [(set_attr "type" "str")
16216 (set_attr "mode" "QI")
16217 (set (attr "prefix_rex")
16218 (if_then_else
16219 (match_test "<P:MODE>mode == DImode")
16220 (const_string "0")
16221 (const_string "*")))
16222 (set_attr "prefix_rep" "1")])
16223
16224 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16225 ;; handled in combine, but it is not currently up to the task.
16226 ;; When used for their truth value, the cmpstrn* expanders generate
16227 ;; code like this:
16228 ;;
16229 ;; repz cmpsb
16230 ;; seta %al
16231 ;; setb %dl
16232 ;; cmpb %al, %dl
16233 ;; jcc label
16234 ;;
16235 ;; The intermediate three instructions are unnecessary.
16236
16237 ;; This one handles cmpstrn*_nz_1...
16238 (define_peephole2
16239 [(parallel[
16240 (set (reg:CC FLAGS_REG)
16241 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16242 (mem:BLK (match_operand 5 "register_operand"))))
16243 (use (match_operand 6 "register_operand"))
16244 (use (match_operand:SI 3 "immediate_operand"))
16245 (clobber (match_operand 0 "register_operand"))
16246 (clobber (match_operand 1 "register_operand"))
16247 (clobber (match_operand 2 "register_operand"))])
16248 (set (match_operand:QI 7 "register_operand")
16249 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16250 (set (match_operand:QI 8 "register_operand")
16251 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16252 (set (reg FLAGS_REG)
16253 (compare (match_dup 7) (match_dup 8)))
16254 ]
16255 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16256 [(parallel[
16257 (set (reg:CC FLAGS_REG)
16258 (compare:CC (mem:BLK (match_dup 4))
16259 (mem:BLK (match_dup 5))))
16260 (use (match_dup 6))
16261 (use (match_dup 3))
16262 (clobber (match_dup 0))
16263 (clobber (match_dup 1))
16264 (clobber (match_dup 2))])])
16265
16266 ;; ...and this one handles cmpstrn*_1.
16267 (define_peephole2
16268 [(parallel[
16269 (set (reg:CC FLAGS_REG)
16270 (if_then_else:CC (ne (match_operand 6 "register_operand")
16271 (const_int 0))
16272 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16273 (mem:BLK (match_operand 5 "register_operand")))
16274 (const_int 0)))
16275 (use (match_operand:SI 3 "immediate_operand"))
16276 (use (reg:CC FLAGS_REG))
16277 (clobber (match_operand 0 "register_operand"))
16278 (clobber (match_operand 1 "register_operand"))
16279 (clobber (match_operand 2 "register_operand"))])
16280 (set (match_operand:QI 7 "register_operand")
16281 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16282 (set (match_operand:QI 8 "register_operand")
16283 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16284 (set (reg FLAGS_REG)
16285 (compare (match_dup 7) (match_dup 8)))
16286 ]
16287 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16288 [(parallel[
16289 (set (reg:CC FLAGS_REG)
16290 (if_then_else:CC (ne (match_dup 6)
16291 (const_int 0))
16292 (compare:CC (mem:BLK (match_dup 4))
16293 (mem:BLK (match_dup 5)))
16294 (const_int 0)))
16295 (use (match_dup 3))
16296 (use (reg:CC FLAGS_REG))
16297 (clobber (match_dup 0))
16298 (clobber (match_dup 1))
16299 (clobber (match_dup 2))])])
16300 \f
16301 ;; Conditional move instructions.
16302
16303 (define_expand "mov<mode>cc"
16304 [(set (match_operand:SWIM 0 "register_operand")
16305 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16306 (match_operand:SWIM 2 "<general_operand>")
16307 (match_operand:SWIM 3 "<general_operand>")))]
16308 ""
16309 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16310
16311 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16312 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16313 ;; So just document what we're doing explicitly.
16314
16315 (define_expand "x86_mov<mode>cc_0_m1"
16316 [(parallel
16317 [(set (match_operand:SWI48 0 "register_operand")
16318 (if_then_else:SWI48
16319 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16320 [(match_operand 1 "flags_reg_operand")
16321 (const_int 0)])
16322 (const_int -1)
16323 (const_int 0)))
16324 (clobber (reg:CC FLAGS_REG))])])
16325
16326 (define_insn "*x86_mov<mode>cc_0_m1"
16327 [(set (match_operand:SWI48 0 "register_operand" "=r")
16328 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16329 [(reg FLAGS_REG) (const_int 0)])
16330 (const_int -1)
16331 (const_int 0)))
16332 (clobber (reg:CC FLAGS_REG))]
16333 ""
16334 "sbb{<imodesuffix>}\t%0, %0"
16335 ; Since we don't have the proper number of operands for an alu insn,
16336 ; fill in all the blanks.
16337 [(set_attr "type" "alu")
16338 (set_attr "use_carry" "1")
16339 (set_attr "pent_pair" "pu")
16340 (set_attr "memory" "none")
16341 (set_attr "imm_disp" "false")
16342 (set_attr "mode" "<MODE>")
16343 (set_attr "length_immediate" "0")])
16344
16345 (define_insn "*x86_mov<mode>cc_0_m1_se"
16346 [(set (match_operand:SWI48 0 "register_operand" "=r")
16347 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16348 [(reg FLAGS_REG) (const_int 0)])
16349 (const_int 1)
16350 (const_int 0)))
16351 (clobber (reg:CC FLAGS_REG))]
16352 ""
16353 "sbb{<imodesuffix>}\t%0, %0"
16354 [(set_attr "type" "alu")
16355 (set_attr "use_carry" "1")
16356 (set_attr "pent_pair" "pu")
16357 (set_attr "memory" "none")
16358 (set_attr "imm_disp" "false")
16359 (set_attr "mode" "<MODE>")
16360 (set_attr "length_immediate" "0")])
16361
16362 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16363 [(set (match_operand:SWI48 0 "register_operand" "=r")
16364 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16365 [(reg FLAGS_REG) (const_int 0)])))
16366 (clobber (reg:CC FLAGS_REG))]
16367 ""
16368 "sbb{<imodesuffix>}\t%0, %0"
16369 [(set_attr "type" "alu")
16370 (set_attr "use_carry" "1")
16371 (set_attr "pent_pair" "pu")
16372 (set_attr "memory" "none")
16373 (set_attr "imm_disp" "false")
16374 (set_attr "mode" "<MODE>")
16375 (set_attr "length_immediate" "0")])
16376
16377 (define_insn "*mov<mode>cc_noc"
16378 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16379 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16380 [(reg FLAGS_REG) (const_int 0)])
16381 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16382 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16383 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16384 "@
16385 cmov%O2%C1\t{%2, %0|%0, %2}
16386 cmov%O2%c1\t{%3, %0|%0, %3}"
16387 [(set_attr "type" "icmov")
16388 (set_attr "mode" "<MODE>")])
16389
16390 (define_insn "*movqicc_noc"
16391 [(set (match_operand:QI 0 "register_operand" "=r,r")
16392 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16393 [(reg FLAGS_REG) (const_int 0)])
16394 (match_operand:QI 2 "register_operand" "r,0")
16395 (match_operand:QI 3 "register_operand" "0,r")))]
16396 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16397 "#"
16398 [(set_attr "type" "icmov")
16399 (set_attr "mode" "QI")])
16400
16401 (define_split
16402 [(set (match_operand 0 "register_operand")
16403 (if_then_else (match_operator 1 "ix86_comparison_operator"
16404 [(reg FLAGS_REG) (const_int 0)])
16405 (match_operand 2 "register_operand")
16406 (match_operand 3 "register_operand")))]
16407 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16408 && (GET_MODE (operands[0]) == QImode
16409 || GET_MODE (operands[0]) == HImode)
16410 && reload_completed"
16411 [(set (match_dup 0)
16412 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16413 {
16414 operands[0] = gen_lowpart (SImode, operands[0]);
16415 operands[2] = gen_lowpart (SImode, operands[2]);
16416 operands[3] = gen_lowpart (SImode, operands[3]);
16417 })
16418
16419 (define_expand "mov<mode>cc"
16420 [(set (match_operand:X87MODEF 0 "register_operand")
16421 (if_then_else:X87MODEF
16422 (match_operand 1 "ix86_fp_comparison_operator")
16423 (match_operand:X87MODEF 2 "register_operand")
16424 (match_operand:X87MODEF 3 "register_operand")))]
16425 "(TARGET_80387 && TARGET_CMOVE)
16426 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16427 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16428
16429 (define_insn "*movxfcc_1"
16430 [(set (match_operand:XF 0 "register_operand" "=f,f")
16431 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16432 [(reg FLAGS_REG) (const_int 0)])
16433 (match_operand:XF 2 "register_operand" "f,0")
16434 (match_operand:XF 3 "register_operand" "0,f")))]
16435 "TARGET_80387 && TARGET_CMOVE"
16436 "@
16437 fcmov%F1\t{%2, %0|%0, %2}
16438 fcmov%f1\t{%3, %0|%0, %3}"
16439 [(set_attr "type" "fcmov")
16440 (set_attr "mode" "XF")])
16441
16442 (define_insn "*movdfcc_1_rex64"
16443 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16444 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16445 [(reg FLAGS_REG) (const_int 0)])
16446 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16447 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16448 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16449 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16450 "@
16451 fcmov%F1\t{%2, %0|%0, %2}
16452 fcmov%f1\t{%3, %0|%0, %3}
16453 cmov%O2%C1\t{%2, %0|%0, %2}
16454 cmov%O2%c1\t{%3, %0|%0, %3}"
16455 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16456 (set_attr "mode" "DF,DF,DI,DI")])
16457
16458 (define_insn "*movdfcc_1"
16459 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16460 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16461 [(reg FLAGS_REG) (const_int 0)])
16462 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16463 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16464 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16465 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16466 "@
16467 fcmov%F1\t{%2, %0|%0, %2}
16468 fcmov%f1\t{%3, %0|%0, %3}
16469 #
16470 #"
16471 [(set_attr "type" "fcmov,fcmov,multi,multi")
16472 (set_attr "mode" "DF,DF,DI,DI")])
16473
16474 (define_split
16475 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16476 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16477 [(reg FLAGS_REG) (const_int 0)])
16478 (match_operand:DF 2 "nonimmediate_operand")
16479 (match_operand:DF 3 "nonimmediate_operand")))]
16480 "!TARGET_64BIT && reload_completed"
16481 [(set (match_dup 2)
16482 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16483 (set (match_dup 3)
16484 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16485 {
16486 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16487 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16488 })
16489
16490 (define_insn "*movsfcc_1_387"
16491 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16492 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16493 [(reg FLAGS_REG) (const_int 0)])
16494 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16495 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16496 "TARGET_80387 && TARGET_CMOVE
16497 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16498 "@
16499 fcmov%F1\t{%2, %0|%0, %2}
16500 fcmov%f1\t{%3, %0|%0, %3}
16501 cmov%O2%C1\t{%2, %0|%0, %2}
16502 cmov%O2%c1\t{%3, %0|%0, %3}"
16503 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16504 (set_attr "mode" "SF,SF,SI,SI")])
16505
16506 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16507 ;; the scalar versions to have only XMM registers as operands.
16508
16509 ;; XOP conditional move
16510 (define_insn "*xop_pcmov_<mode>"
16511 [(set (match_operand:MODEF 0 "register_operand" "=x")
16512 (if_then_else:MODEF
16513 (match_operand:MODEF 1 "register_operand" "x")
16514 (match_operand:MODEF 2 "register_operand" "x")
16515 (match_operand:MODEF 3 "register_operand" "x")))]
16516 "TARGET_XOP"
16517 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16518 [(set_attr "type" "sse4arg")])
16519
16520 ;; These versions of the min/max patterns are intentionally ignorant of
16521 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16522 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16523 ;; are undefined in this condition, we're certain this is correct.
16524
16525 (define_insn "<code><mode>3"
16526 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16527 (smaxmin:MODEF
16528 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16529 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16530 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16531 "@
16532 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16533 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16534 [(set_attr "isa" "noavx,avx")
16535 (set_attr "prefix" "orig,vex")
16536 (set_attr "type" "sseadd")
16537 (set_attr "mode" "<MODE>")])
16538
16539 ;; These versions of the min/max patterns implement exactly the operations
16540 ;; min = (op1 < op2 ? op1 : op2)
16541 ;; max = (!(op1 < op2) ? op1 : op2)
16542 ;; Their operands are not commutative, and thus they may be used in the
16543 ;; presence of -0.0 and NaN.
16544
16545 (define_int_iterator IEEE_MAXMIN
16546 [UNSPEC_IEEE_MAX
16547 UNSPEC_IEEE_MIN])
16548
16549 (define_int_attr ieee_maxmin
16550 [(UNSPEC_IEEE_MAX "max")
16551 (UNSPEC_IEEE_MIN "min")])
16552
16553 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16554 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16555 (unspec:MODEF
16556 [(match_operand:MODEF 1 "register_operand" "0,x")
16557 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16558 IEEE_MAXMIN))]
16559 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16560 "@
16561 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16562 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16563 [(set_attr "isa" "noavx,avx")
16564 (set_attr "prefix" "orig,vex")
16565 (set_attr "type" "sseadd")
16566 (set_attr "mode" "<MODE>")])
16567
16568 ;; Make two stack loads independent:
16569 ;; fld aa fld aa
16570 ;; fld %st(0) -> fld bb
16571 ;; fmul bb fmul %st(1), %st
16572 ;;
16573 ;; Actually we only match the last two instructions for simplicity.
16574 (define_peephole2
16575 [(set (match_operand 0 "fp_register_operand")
16576 (match_operand 1 "fp_register_operand"))
16577 (set (match_dup 0)
16578 (match_operator 2 "binary_fp_operator"
16579 [(match_dup 0)
16580 (match_operand 3 "memory_operand")]))]
16581 "REGNO (operands[0]) != REGNO (operands[1])"
16582 [(set (match_dup 0) (match_dup 3))
16583 (set (match_dup 0) (match_dup 4))]
16584
16585 ;; The % modifier is not operational anymore in peephole2's, so we have to
16586 ;; swap the operands manually in the case of addition and multiplication.
16587 {
16588 rtx op0, op1;
16589
16590 if (COMMUTATIVE_ARITH_P (operands[2]))
16591 op0 = operands[0], op1 = operands[1];
16592 else
16593 op0 = operands[1], op1 = operands[0];
16594
16595 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16596 GET_MODE (operands[2]),
16597 op0, op1);
16598 })
16599
16600 ;; Conditional addition patterns
16601 (define_expand "add<mode>cc"
16602 [(match_operand:SWI 0 "register_operand")
16603 (match_operand 1 "ordered_comparison_operator")
16604 (match_operand:SWI 2 "register_operand")
16605 (match_operand:SWI 3 "const_int_operand")]
16606 ""
16607 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16608 \f
16609 ;; Misc patterns (?)
16610
16611 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16612 ;; Otherwise there will be nothing to keep
16613 ;;
16614 ;; [(set (reg ebp) (reg esp))]
16615 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16616 ;; (clobber (eflags)]
16617 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16618 ;;
16619 ;; in proper program order.
16620
16621 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16622 [(set (match_operand:P 0 "register_operand" "=r,r")
16623 (plus:P (match_operand:P 1 "register_operand" "0,r")
16624 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16625 (clobber (reg:CC FLAGS_REG))
16626 (clobber (mem:BLK (scratch)))]
16627 ""
16628 {
16629 switch (get_attr_type (insn))
16630 {
16631 case TYPE_IMOV:
16632 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16633
16634 case TYPE_ALU:
16635 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16636 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16637 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16638
16639 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16640
16641 default:
16642 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16643 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16644 }
16645 }
16646 [(set (attr "type")
16647 (cond [(and (eq_attr "alternative" "0")
16648 (not (match_test "TARGET_OPT_AGU")))
16649 (const_string "alu")
16650 (match_operand:<MODE> 2 "const0_operand")
16651 (const_string "imov")
16652 ]
16653 (const_string "lea")))
16654 (set (attr "length_immediate")
16655 (cond [(eq_attr "type" "imov")
16656 (const_string "0")
16657 (and (eq_attr "type" "alu")
16658 (match_operand 2 "const128_operand"))
16659 (const_string "1")
16660 ]
16661 (const_string "*")))
16662 (set_attr "mode" "<MODE>")])
16663
16664 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16665 [(set (match_operand:P 0 "register_operand" "=r")
16666 (minus:P (match_operand:P 1 "register_operand" "0")
16667 (match_operand:P 2 "register_operand" "r")))
16668 (clobber (reg:CC FLAGS_REG))
16669 (clobber (mem:BLK (scratch)))]
16670 ""
16671 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16672 [(set_attr "type" "alu")
16673 (set_attr "mode" "<MODE>")])
16674
16675 (define_insn "allocate_stack_worker_probe_<mode>"
16676 [(set (match_operand:P 0 "register_operand" "=a")
16677 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16678 UNSPECV_STACK_PROBE))
16679 (clobber (reg:CC FLAGS_REG))]
16680 "ix86_target_stack_probe ()"
16681 "call\t___chkstk_ms"
16682 [(set_attr "type" "multi")
16683 (set_attr "length" "5")])
16684
16685 (define_expand "allocate_stack"
16686 [(match_operand 0 "register_operand")
16687 (match_operand 1 "general_operand")]
16688 "ix86_target_stack_probe ()"
16689 {
16690 rtx x;
16691
16692 #ifndef CHECK_STACK_LIMIT
16693 #define CHECK_STACK_LIMIT 0
16694 #endif
16695
16696 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16697 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16698 x = operands[1];
16699 else
16700 {
16701 rtx (*insn) (rtx, rtx);
16702
16703 x = copy_to_mode_reg (Pmode, operands[1]);
16704
16705 insn = (TARGET_64BIT
16706 ? gen_allocate_stack_worker_probe_di
16707 : gen_allocate_stack_worker_probe_si);
16708
16709 emit_insn (insn (x, x));
16710 }
16711
16712 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16713 stack_pointer_rtx, 0, OPTAB_DIRECT);
16714
16715 if (x != stack_pointer_rtx)
16716 emit_move_insn (stack_pointer_rtx, x);
16717
16718 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16719 DONE;
16720 })
16721
16722 ;; Use IOR for stack probes, this is shorter.
16723 (define_expand "probe_stack"
16724 [(match_operand 0 "memory_operand")]
16725 ""
16726 {
16727 rtx (*gen_ior3) (rtx, rtx, rtx);
16728
16729 gen_ior3 = (GET_MODE (operands[0]) == DImode
16730 ? gen_iordi3 : gen_iorsi3);
16731
16732 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16733 DONE;
16734 })
16735
16736 (define_insn "adjust_stack_and_probe<mode>"
16737 [(set (match_operand:P 0 "register_operand" "=r")
16738 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16739 UNSPECV_PROBE_STACK_RANGE))
16740 (set (reg:P SP_REG)
16741 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16742 (clobber (reg:CC FLAGS_REG))
16743 (clobber (mem:BLK (scratch)))]
16744 ""
16745 "* return output_adjust_stack_and_probe (operands[0]);"
16746 [(set_attr "type" "multi")])
16747
16748 (define_insn "probe_stack_range<mode>"
16749 [(set (match_operand:P 0 "register_operand" "=r")
16750 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16751 (match_operand:P 2 "const_int_operand" "n")]
16752 UNSPECV_PROBE_STACK_RANGE))
16753 (clobber (reg:CC FLAGS_REG))]
16754 ""
16755 "* return output_probe_stack_range (operands[0], operands[2]);"
16756 [(set_attr "type" "multi")])
16757
16758 (define_expand "builtin_setjmp_receiver"
16759 [(label_ref (match_operand 0))]
16760 "!TARGET_64BIT && flag_pic"
16761 {
16762 #if TARGET_MACHO
16763 if (TARGET_MACHO)
16764 {
16765 rtx xops[3];
16766 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16767 rtx label_rtx = gen_label_rtx ();
16768 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16769 xops[0] = xops[1] = picreg;
16770 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16771 ix86_expand_binary_operator (MINUS, SImode, xops);
16772 }
16773 else
16774 #endif
16775 emit_insn (gen_set_got (pic_offset_table_rtx));
16776 DONE;
16777 })
16778 \f
16779 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16780
16781 (define_split
16782 [(set (match_operand 0 "register_operand")
16783 (match_operator 3 "promotable_binary_operator"
16784 [(match_operand 1 "register_operand")
16785 (match_operand 2 "aligned_operand")]))
16786 (clobber (reg:CC FLAGS_REG))]
16787 "! TARGET_PARTIAL_REG_STALL && reload_completed
16788 && ((GET_MODE (operands[0]) == HImode
16789 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16790 /* ??? next two lines just !satisfies_constraint_K (...) */
16791 || !CONST_INT_P (operands[2])
16792 || satisfies_constraint_K (operands[2])))
16793 || (GET_MODE (operands[0]) == QImode
16794 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16795 [(parallel [(set (match_dup 0)
16796 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16797 (clobber (reg:CC FLAGS_REG))])]
16798 {
16799 operands[0] = gen_lowpart (SImode, operands[0]);
16800 operands[1] = gen_lowpart (SImode, operands[1]);
16801 if (GET_CODE (operands[3]) != ASHIFT)
16802 operands[2] = gen_lowpart (SImode, operands[2]);
16803 PUT_MODE (operands[3], SImode);
16804 })
16805
16806 ; Promote the QImode tests, as i386 has encoding of the AND
16807 ; instruction with 32-bit sign-extended immediate and thus the
16808 ; instruction size is unchanged, except in the %eax case for
16809 ; which it is increased by one byte, hence the ! optimize_size.
16810 (define_split
16811 [(set (match_operand 0 "flags_reg_operand")
16812 (match_operator 2 "compare_operator"
16813 [(and (match_operand 3 "aligned_operand")
16814 (match_operand 4 "const_int_operand"))
16815 (const_int 0)]))
16816 (set (match_operand 1 "register_operand")
16817 (and (match_dup 3) (match_dup 4)))]
16818 "! TARGET_PARTIAL_REG_STALL && reload_completed
16819 && optimize_insn_for_speed_p ()
16820 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16821 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16822 /* Ensure that the operand will remain sign-extended immediate. */
16823 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16824 [(parallel [(set (match_dup 0)
16825 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16826 (const_int 0)]))
16827 (set (match_dup 1)
16828 (and:SI (match_dup 3) (match_dup 4)))])]
16829 {
16830 operands[4]
16831 = gen_int_mode (INTVAL (operands[4])
16832 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16833 operands[1] = gen_lowpart (SImode, operands[1]);
16834 operands[3] = gen_lowpart (SImode, operands[3]);
16835 })
16836
16837 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16838 ; the TEST instruction with 32-bit sign-extended immediate and thus
16839 ; the instruction size would at least double, which is not what we
16840 ; want even with ! optimize_size.
16841 (define_split
16842 [(set (match_operand 0 "flags_reg_operand")
16843 (match_operator 1 "compare_operator"
16844 [(and (match_operand:HI 2 "aligned_operand")
16845 (match_operand:HI 3 "const_int_operand"))
16846 (const_int 0)]))]
16847 "! TARGET_PARTIAL_REG_STALL && reload_completed
16848 && ! TARGET_FAST_PREFIX
16849 && optimize_insn_for_speed_p ()
16850 /* Ensure that the operand will remain sign-extended immediate. */
16851 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16852 [(set (match_dup 0)
16853 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16854 (const_int 0)]))]
16855 {
16856 operands[3]
16857 = gen_int_mode (INTVAL (operands[3])
16858 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16859 operands[2] = gen_lowpart (SImode, operands[2]);
16860 })
16861
16862 (define_split
16863 [(set (match_operand 0 "register_operand")
16864 (neg (match_operand 1 "register_operand")))
16865 (clobber (reg:CC FLAGS_REG))]
16866 "! TARGET_PARTIAL_REG_STALL && reload_completed
16867 && (GET_MODE (operands[0]) == HImode
16868 || (GET_MODE (operands[0]) == QImode
16869 && (TARGET_PROMOTE_QImode
16870 || optimize_insn_for_size_p ())))"
16871 [(parallel [(set (match_dup 0)
16872 (neg:SI (match_dup 1)))
16873 (clobber (reg:CC FLAGS_REG))])]
16874 {
16875 operands[0] = gen_lowpart (SImode, operands[0]);
16876 operands[1] = gen_lowpart (SImode, operands[1]);
16877 })
16878
16879 (define_split
16880 [(set (match_operand 0 "register_operand")
16881 (not (match_operand 1 "register_operand")))]
16882 "! TARGET_PARTIAL_REG_STALL && reload_completed
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 (not:SI (match_dup 1)))]
16889 {
16890 operands[0] = gen_lowpart (SImode, operands[0]);
16891 operands[1] = gen_lowpart (SImode, operands[1]);
16892 })
16893 \f
16894 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16895 ;; transform a complex memory operation into two memory to register operations.
16896
16897 ;; Don't push memory operands
16898 (define_peephole2
16899 [(set (match_operand:SWI 0 "push_operand")
16900 (match_operand:SWI 1 "memory_operand"))
16901 (match_scratch:SWI 2 "<r>")]
16902 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16903 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16904 [(set (match_dup 2) (match_dup 1))
16905 (set (match_dup 0) (match_dup 2))])
16906
16907 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16908 ;; SImode pushes.
16909 (define_peephole2
16910 [(set (match_operand:SF 0 "push_operand")
16911 (match_operand:SF 1 "memory_operand"))
16912 (match_scratch:SF 2 "r")]
16913 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16914 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16915 [(set (match_dup 2) (match_dup 1))
16916 (set (match_dup 0) (match_dup 2))])
16917
16918 ;; Don't move an immediate directly to memory when the instruction
16919 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16920 (define_peephole2
16921 [(match_scratch:SWI124 1 "<r>")
16922 (set (match_operand:SWI124 0 "memory_operand")
16923 (const_int 0))]
16924 "optimize_insn_for_speed_p ()
16925 && ((<MODE>mode == HImode
16926 && TARGET_LCP_STALL)
16927 || (!TARGET_USE_MOV0
16928 && TARGET_SPLIT_LONG_MOVES
16929 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16930 && peep2_regno_dead_p (0, FLAGS_REG)"
16931 [(parallel [(set (match_dup 2) (const_int 0))
16932 (clobber (reg:CC FLAGS_REG))])
16933 (set (match_dup 0) (match_dup 1))]
16934 "operands[2] = gen_lowpart (SImode, operands[1]);")
16935
16936 (define_peephole2
16937 [(match_scratch:SWI124 2 "<r>")
16938 (set (match_operand:SWI124 0 "memory_operand")
16939 (match_operand:SWI124 1 "immediate_operand"))]
16940 "optimize_insn_for_speed_p ()
16941 && ((<MODE>mode == HImode
16942 && TARGET_LCP_STALL)
16943 || (TARGET_SPLIT_LONG_MOVES
16944 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16945 [(set (match_dup 2) (match_dup 1))
16946 (set (match_dup 0) (match_dup 2))])
16947
16948 ;; Don't compare memory with zero, load and use a test instead.
16949 (define_peephole2
16950 [(set (match_operand 0 "flags_reg_operand")
16951 (match_operator 1 "compare_operator"
16952 [(match_operand:SI 2 "memory_operand")
16953 (const_int 0)]))
16954 (match_scratch:SI 3 "r")]
16955 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16956 [(set (match_dup 3) (match_dup 2))
16957 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16958
16959 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16960 ;; Don't split NOTs with a displacement operand, because resulting XOR
16961 ;; will not be pairable anyway.
16962 ;;
16963 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16964 ;; represented using a modRM byte. The XOR replacement is long decoded,
16965 ;; so this split helps here as well.
16966 ;;
16967 ;; Note: Can't do this as a regular split because we can't get proper
16968 ;; lifetime information then.
16969
16970 (define_peephole2
16971 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16972 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16973 "optimize_insn_for_speed_p ()
16974 && ((TARGET_NOT_UNPAIRABLE
16975 && (!MEM_P (operands[0])
16976 || !memory_displacement_operand (operands[0], <MODE>mode)))
16977 || (TARGET_NOT_VECTORMODE
16978 && long_memory_operand (operands[0], <MODE>mode)))
16979 && peep2_regno_dead_p (0, FLAGS_REG)"
16980 [(parallel [(set (match_dup 0)
16981 (xor:SWI124 (match_dup 1) (const_int -1)))
16982 (clobber (reg:CC FLAGS_REG))])])
16983
16984 ;; Non pairable "test imm, reg" instructions can be translated to
16985 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16986 ;; byte opcode instead of two, have a short form for byte operands),
16987 ;; so do it for other CPUs as well. Given that the value was dead,
16988 ;; this should not create any new dependencies. Pass on the sub-word
16989 ;; versions if we're concerned about partial register stalls.
16990
16991 (define_peephole2
16992 [(set (match_operand 0 "flags_reg_operand")
16993 (match_operator 1 "compare_operator"
16994 [(and:SI (match_operand:SI 2 "register_operand")
16995 (match_operand:SI 3 "immediate_operand"))
16996 (const_int 0)]))]
16997 "ix86_match_ccmode (insn, CCNOmode)
16998 && (true_regnum (operands[2]) != AX_REG
16999 || satisfies_constraint_K (operands[3]))
17000 && peep2_reg_dead_p (1, operands[2])"
17001 [(parallel
17002 [(set (match_dup 0)
17003 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17004 (const_int 0)]))
17005 (set (match_dup 2)
17006 (and:SI (match_dup 2) (match_dup 3)))])])
17007
17008 ;; We don't need to handle HImode case, because it will be promoted to SImode
17009 ;; on ! TARGET_PARTIAL_REG_STALL
17010
17011 (define_peephole2
17012 [(set (match_operand 0 "flags_reg_operand")
17013 (match_operator 1 "compare_operator"
17014 [(and:QI (match_operand:QI 2 "register_operand")
17015 (match_operand:QI 3 "immediate_operand"))
17016 (const_int 0)]))]
17017 "! TARGET_PARTIAL_REG_STALL
17018 && ix86_match_ccmode (insn, CCNOmode)
17019 && true_regnum (operands[2]) != AX_REG
17020 && peep2_reg_dead_p (1, operands[2])"
17021 [(parallel
17022 [(set (match_dup 0)
17023 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17024 (const_int 0)]))
17025 (set (match_dup 2)
17026 (and:QI (match_dup 2) (match_dup 3)))])])
17027
17028 (define_peephole2
17029 [(set (match_operand 0 "flags_reg_operand")
17030 (match_operator 1 "compare_operator"
17031 [(and:SI
17032 (zero_extract:SI
17033 (match_operand 2 "ext_register_operand")
17034 (const_int 8)
17035 (const_int 8))
17036 (match_operand 3 "const_int_operand"))
17037 (const_int 0)]))]
17038 "! TARGET_PARTIAL_REG_STALL
17039 && ix86_match_ccmode (insn, CCNOmode)
17040 && true_regnum (operands[2]) != AX_REG
17041 && peep2_reg_dead_p (1, operands[2])"
17042 [(parallel [(set (match_dup 0)
17043 (match_op_dup 1
17044 [(and:SI
17045 (zero_extract:SI
17046 (match_dup 2)
17047 (const_int 8)
17048 (const_int 8))
17049 (match_dup 3))
17050 (const_int 0)]))
17051 (set (zero_extract:SI (match_dup 2)
17052 (const_int 8)
17053 (const_int 8))
17054 (and:SI
17055 (zero_extract:SI
17056 (match_dup 2)
17057 (const_int 8)
17058 (const_int 8))
17059 (match_dup 3)))])])
17060
17061 ;; Don't do logical operations with memory inputs.
17062 (define_peephole2
17063 [(match_scratch:SI 2 "r")
17064 (parallel [(set (match_operand:SI 0 "register_operand")
17065 (match_operator:SI 3 "arith_or_logical_operator"
17066 [(match_dup 0)
17067 (match_operand:SI 1 "memory_operand")]))
17068 (clobber (reg:CC FLAGS_REG))])]
17069 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17070 [(set (match_dup 2) (match_dup 1))
17071 (parallel [(set (match_dup 0)
17072 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17073 (clobber (reg:CC FLAGS_REG))])])
17074
17075 (define_peephole2
17076 [(match_scratch:SI 2 "r")
17077 (parallel [(set (match_operand:SI 0 "register_operand")
17078 (match_operator:SI 3 "arith_or_logical_operator"
17079 [(match_operand:SI 1 "memory_operand")
17080 (match_dup 0)]))
17081 (clobber (reg:CC FLAGS_REG))])]
17082 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17083 [(set (match_dup 2) (match_dup 1))
17084 (parallel [(set (match_dup 0)
17085 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17086 (clobber (reg:CC FLAGS_REG))])])
17087
17088 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17089 ;; refers to the destination of the load!
17090
17091 (define_peephole2
17092 [(set (match_operand:SI 0 "register_operand")
17093 (match_operand:SI 1 "register_operand"))
17094 (parallel [(set (match_dup 0)
17095 (match_operator:SI 3 "commutative_operator"
17096 [(match_dup 0)
17097 (match_operand:SI 2 "memory_operand")]))
17098 (clobber (reg:CC FLAGS_REG))])]
17099 "REGNO (operands[0]) != REGNO (operands[1])
17100 && GENERAL_REGNO_P (REGNO (operands[0]))
17101 && GENERAL_REGNO_P (REGNO (operands[1]))"
17102 [(set (match_dup 0) (match_dup 4))
17103 (parallel [(set (match_dup 0)
17104 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17105 (clobber (reg:CC FLAGS_REG))])]
17106 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17107
17108 (define_peephole2
17109 [(set (match_operand 0 "register_operand")
17110 (match_operand 1 "register_operand"))
17111 (set (match_dup 0)
17112 (match_operator 3 "commutative_operator"
17113 [(match_dup 0)
17114 (match_operand 2 "memory_operand")]))]
17115 "REGNO (operands[0]) != REGNO (operands[1])
17116 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17117 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17118 [(set (match_dup 0) (match_dup 2))
17119 (set (match_dup 0)
17120 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17121
17122 ; Don't do logical operations with memory outputs
17123 ;
17124 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17125 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17126 ; the same decoder scheduling characteristics as the original.
17127
17128 (define_peephole2
17129 [(match_scratch:SI 2 "r")
17130 (parallel [(set (match_operand:SI 0 "memory_operand")
17131 (match_operator:SI 3 "arith_or_logical_operator"
17132 [(match_dup 0)
17133 (match_operand:SI 1 "nonmemory_operand")]))
17134 (clobber (reg:CC FLAGS_REG))])]
17135 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17136 /* Do not split stack checking probes. */
17137 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17138 [(set (match_dup 2) (match_dup 0))
17139 (parallel [(set (match_dup 2)
17140 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17141 (clobber (reg:CC FLAGS_REG))])
17142 (set (match_dup 0) (match_dup 2))])
17143
17144 (define_peephole2
17145 [(match_scratch:SI 2 "r")
17146 (parallel [(set (match_operand:SI 0 "memory_operand")
17147 (match_operator:SI 3 "arith_or_logical_operator"
17148 [(match_operand:SI 1 "nonmemory_operand")
17149 (match_dup 0)]))
17150 (clobber (reg:CC FLAGS_REG))])]
17151 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17152 /* Do not split stack checking probes. */
17153 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17154 [(set (match_dup 2) (match_dup 0))
17155 (parallel [(set (match_dup 2)
17156 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17157 (clobber (reg:CC FLAGS_REG))])
17158 (set (match_dup 0) (match_dup 2))])
17159
17160 ;; Attempt to use arith or logical operations with memory outputs with
17161 ;; setting of flags.
17162 (define_peephole2
17163 [(set (match_operand:SWI 0 "register_operand")
17164 (match_operand:SWI 1 "memory_operand"))
17165 (parallel [(set (match_dup 0)
17166 (match_operator:SWI 3 "plusminuslogic_operator"
17167 [(match_dup 0)
17168 (match_operand:SWI 2 "<nonmemory_operand>")]))
17169 (clobber (reg:CC FLAGS_REG))])
17170 (set (match_dup 1) (match_dup 0))
17171 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17172 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17173 && peep2_reg_dead_p (4, operands[0])
17174 && !reg_overlap_mentioned_p (operands[0], operands[1])
17175 && (<MODE>mode != QImode
17176 || immediate_operand (operands[2], QImode)
17177 || q_regs_operand (operands[2], QImode))
17178 && ix86_match_ccmode (peep2_next_insn (3),
17179 (GET_CODE (operands[3]) == PLUS
17180 || GET_CODE (operands[3]) == MINUS)
17181 ? CCGOCmode : CCNOmode)"
17182 [(parallel [(set (match_dup 4) (match_dup 5))
17183 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17184 (match_dup 2)]))])]
17185 {
17186 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17187 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17188 copy_rtx (operands[1]),
17189 copy_rtx (operands[2]));
17190 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17191 operands[5], const0_rtx);
17192 })
17193
17194 (define_peephole2
17195 [(parallel [(set (match_operand:SWI 0 "register_operand")
17196 (match_operator:SWI 2 "plusminuslogic_operator"
17197 [(match_dup 0)
17198 (match_operand:SWI 1 "memory_operand")]))
17199 (clobber (reg:CC FLAGS_REG))])
17200 (set (match_dup 1) (match_dup 0))
17201 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17202 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17203 && GET_CODE (operands[2]) != MINUS
17204 && peep2_reg_dead_p (3, operands[0])
17205 && !reg_overlap_mentioned_p (operands[0], operands[1])
17206 && ix86_match_ccmode (peep2_next_insn (2),
17207 GET_CODE (operands[2]) == PLUS
17208 ? CCGOCmode : CCNOmode)"
17209 [(parallel [(set (match_dup 3) (match_dup 4))
17210 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17211 (match_dup 0)]))])]
17212 {
17213 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17214 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17215 copy_rtx (operands[1]),
17216 copy_rtx (operands[0]));
17217 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17218 operands[4], const0_rtx);
17219 })
17220
17221 (define_peephole2
17222 [(set (match_operand:SWI12 0 "register_operand")
17223 (match_operand:SWI12 1 "memory_operand"))
17224 (parallel [(set (match_operand:SI 4 "register_operand")
17225 (match_operator:SI 3 "plusminuslogic_operator"
17226 [(match_dup 4)
17227 (match_operand:SI 2 "nonmemory_operand")]))
17228 (clobber (reg:CC FLAGS_REG))])
17229 (set (match_dup 1) (match_dup 0))
17230 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17231 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17232 && REG_P (operands[0]) && REG_P (operands[4])
17233 && REGNO (operands[0]) == REGNO (operands[4])
17234 && peep2_reg_dead_p (4, operands[0])
17235 && (<MODE>mode != QImode
17236 || immediate_operand (operands[2], SImode)
17237 || q_regs_operand (operands[2], SImode))
17238 && !reg_overlap_mentioned_p (operands[0], operands[1])
17239 && ix86_match_ccmode (peep2_next_insn (3),
17240 (GET_CODE (operands[3]) == PLUS
17241 || GET_CODE (operands[3]) == MINUS)
17242 ? CCGOCmode : CCNOmode)"
17243 [(parallel [(set (match_dup 4) (match_dup 5))
17244 (set (match_dup 1) (match_dup 6))])]
17245 {
17246 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17247 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17248 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17249 copy_rtx (operands[1]), operands[2]);
17250 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17251 operands[5], const0_rtx);
17252 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17253 copy_rtx (operands[1]),
17254 copy_rtx (operands[2]));
17255 })
17256
17257 ;; Attempt to always use XOR for zeroing registers.
17258 (define_peephole2
17259 [(set (match_operand 0 "register_operand")
17260 (match_operand 1 "const0_operand"))]
17261 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17262 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17263 && GENERAL_REG_P (operands[0])
17264 && peep2_regno_dead_p (0, FLAGS_REG)"
17265 [(parallel [(set (match_dup 0) (const_int 0))
17266 (clobber (reg:CC FLAGS_REG))])]
17267 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17268
17269 (define_peephole2
17270 [(set (strict_low_part (match_operand 0 "register_operand"))
17271 (const_int 0))]
17272 "(GET_MODE (operands[0]) == QImode
17273 || GET_MODE (operands[0]) == HImode)
17274 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17275 && peep2_regno_dead_p (0, FLAGS_REG)"
17276 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17277 (clobber (reg:CC FLAGS_REG))])])
17278
17279 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17280 (define_peephole2
17281 [(set (match_operand:SWI248 0 "register_operand")
17282 (const_int -1))]
17283 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17284 && peep2_regno_dead_p (0, FLAGS_REG)"
17285 [(parallel [(set (match_dup 0) (const_int -1))
17286 (clobber (reg:CC FLAGS_REG))])]
17287 {
17288 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17289 operands[0] = gen_lowpart (SImode, operands[0]);
17290 })
17291
17292 ;; Attempt to convert simple lea to add/shift.
17293 ;; These can be created by move expanders.
17294
17295 (define_peephole2
17296 [(set (match_operand:SWI48 0 "register_operand")
17297 (plus:SWI48 (match_dup 0)
17298 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17299 "peep2_regno_dead_p (0, FLAGS_REG)"
17300 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17301 (clobber (reg:CC FLAGS_REG))])])
17302
17303 (define_peephole2
17304 [(set (match_operand:SWI48 0 "register_operand")
17305 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17306 (match_dup 0)))]
17307 "peep2_regno_dead_p (0, FLAGS_REG)"
17308 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17309 (clobber (reg:CC FLAGS_REG))])])
17310
17311 (define_peephole2
17312 [(set (match_operand:SI 0 "register_operand")
17313 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17314 (match_operand:DI 2 "nonmemory_operand")) 0))]
17315 "TARGET_64BIT
17316 && peep2_regno_dead_p (0, FLAGS_REG)
17317 && REGNO (operands[0]) == REGNO (operands[1])"
17318 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17319 (clobber (reg:CC FLAGS_REG))])]
17320 "operands[2] = gen_lowpart (SImode, operands[2]);")
17321
17322 (define_peephole2
17323 [(set (match_operand:SI 0 "register_operand")
17324 (subreg:SI (plus:DI (match_operand:DI 1 "nonmemory_operand")
17325 (match_operand:DI 2 "register_operand")) 0))]
17326 "TARGET_64BIT
17327 && peep2_regno_dead_p (0, FLAGS_REG)
17328 && REGNO (operands[0]) == REGNO (operands[2])"
17329 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17330 (clobber (reg:CC FLAGS_REG))])]
17331 "operands[1] = gen_lowpart (SImode, operands[1]);")
17332
17333 (define_peephole2
17334 [(set (match_operand:SWI48 0 "register_operand")
17335 (mult:SWI48 (match_dup 0)
17336 (match_operand:SWI48 1 "const_int_operand")))]
17337 "exact_log2 (INTVAL (operands[1])) >= 0
17338 && peep2_regno_dead_p (0, FLAGS_REG)"
17339 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17340 (clobber (reg:CC FLAGS_REG))])]
17341 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17342
17343 (define_peephole2
17344 [(set (match_operand:SI 0 "register_operand")
17345 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17346 (match_operand:DI 2 "const_int_operand")) 0))]
17347 "TARGET_64BIT
17348 && exact_log2 (INTVAL (operands[2])) >= 0
17349 && REGNO (operands[0]) == REGNO (operands[1])
17350 && peep2_regno_dead_p (0, FLAGS_REG)"
17351 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17352 (clobber (reg:CC FLAGS_REG))])]
17353 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17354
17355 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17356 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17357 ;; On many CPUs it is also faster, since special hardware to avoid esp
17358 ;; dependencies is present.
17359
17360 ;; While some of these conversions may be done using splitters, we use
17361 ;; peepholes in order to allow combine_stack_adjustments pass to see
17362 ;; nonobfuscated RTL.
17363
17364 ;; Convert prologue esp subtractions to push.
17365 ;; We need register to push. In order to keep verify_flow_info happy we have
17366 ;; two choices
17367 ;; - use scratch and clobber it in order to avoid dependencies
17368 ;; - use already live register
17369 ;; We can't use the second way right now, since there is no reliable way how to
17370 ;; verify that given register is live. First choice will also most likely in
17371 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17372 ;; call clobbered registers are dead. We may want to use base pointer as an
17373 ;; alternative when no register is available later.
17374
17375 (define_peephole2
17376 [(match_scratch:W 1 "r")
17377 (parallel [(set (reg:P SP_REG)
17378 (plus:P (reg:P SP_REG)
17379 (match_operand:P 0 "const_int_operand")))
17380 (clobber (reg:CC FLAGS_REG))
17381 (clobber (mem:BLK (scratch)))])]
17382 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17383 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17384 [(clobber (match_dup 1))
17385 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17386 (clobber (mem:BLK (scratch)))])])
17387
17388 (define_peephole2
17389 [(match_scratch:W 1 "r")
17390 (parallel [(set (reg:P SP_REG)
17391 (plus:P (reg:P SP_REG)
17392 (match_operand:P 0 "const_int_operand")))
17393 (clobber (reg:CC FLAGS_REG))
17394 (clobber (mem:BLK (scratch)))])]
17395 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17396 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17397 [(clobber (match_dup 1))
17398 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17399 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17400 (clobber (mem:BLK (scratch)))])])
17401
17402 ;; Convert esp subtractions to push.
17403 (define_peephole2
17404 [(match_scratch:W 1 "r")
17405 (parallel [(set (reg:P SP_REG)
17406 (plus:P (reg:P SP_REG)
17407 (match_operand:P 0 "const_int_operand")))
17408 (clobber (reg:CC FLAGS_REG))])]
17409 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17410 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17411 [(clobber (match_dup 1))
17412 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17413
17414 (define_peephole2
17415 [(match_scratch:W 1 "r")
17416 (parallel [(set (reg:P SP_REG)
17417 (plus:P (reg:P SP_REG)
17418 (match_operand:P 0 "const_int_operand")))
17419 (clobber (reg:CC FLAGS_REG))])]
17420 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17421 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17422 [(clobber (match_dup 1))
17423 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17424 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17425
17426 ;; Convert epilogue deallocator to pop.
17427 (define_peephole2
17428 [(match_scratch:W 1 "r")
17429 (parallel [(set (reg:P SP_REG)
17430 (plus:P (reg:P SP_REG)
17431 (match_operand:P 0 "const_int_operand")))
17432 (clobber (reg:CC FLAGS_REG))
17433 (clobber (mem:BLK (scratch)))])]
17434 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17435 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17436 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17437 (clobber (mem:BLK (scratch)))])])
17438
17439 ;; Two pops case is tricky, since pop causes dependency
17440 ;; on destination register. We use two registers if available.
17441 (define_peephole2
17442 [(match_scratch:W 1 "r")
17443 (match_scratch:W 2 "r")
17444 (parallel [(set (reg:P SP_REG)
17445 (plus:P (reg:P SP_REG)
17446 (match_operand:P 0 "const_int_operand")))
17447 (clobber (reg:CC FLAGS_REG))
17448 (clobber (mem:BLK (scratch)))])]
17449 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17450 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17451 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17452 (clobber (mem:BLK (scratch)))])
17453 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17454
17455 (define_peephole2
17456 [(match_scratch:W 1 "r")
17457 (parallel [(set (reg:P SP_REG)
17458 (plus:P (reg:P SP_REG)
17459 (match_operand:P 0 "const_int_operand")))
17460 (clobber (reg:CC FLAGS_REG))
17461 (clobber (mem:BLK (scratch)))])]
17462 "optimize_insn_for_size_p ()
17463 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17464 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17465 (clobber (mem:BLK (scratch)))])
17466 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17467
17468 ;; Convert esp additions to pop.
17469 (define_peephole2
17470 [(match_scratch:W 1 "r")
17471 (parallel [(set (reg:P SP_REG)
17472 (plus:P (reg:P SP_REG)
17473 (match_operand:P 0 "const_int_operand")))
17474 (clobber (reg:CC FLAGS_REG))])]
17475 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17476 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17477
17478 ;; Two pops case is tricky, since pop causes dependency
17479 ;; on destination register. We use two registers if available.
17480 (define_peephole2
17481 [(match_scratch:W 1 "r")
17482 (match_scratch:W 2 "r")
17483 (parallel [(set (reg:P SP_REG)
17484 (plus:P (reg:P SP_REG)
17485 (match_operand:P 0 "const_int_operand")))
17486 (clobber (reg:CC FLAGS_REG))])]
17487 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17488 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17489 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17490
17491 (define_peephole2
17492 [(match_scratch:W 1 "r")
17493 (parallel [(set (reg:P SP_REG)
17494 (plus:P (reg:P SP_REG)
17495 (match_operand:P 0 "const_int_operand")))
17496 (clobber (reg:CC FLAGS_REG))])]
17497 "optimize_insn_for_size_p ()
17498 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17499 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17500 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17501 \f
17502 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17503 ;; required and register dies. Similarly for 128 to -128.
17504 (define_peephole2
17505 [(set (match_operand 0 "flags_reg_operand")
17506 (match_operator 1 "compare_operator"
17507 [(match_operand 2 "register_operand")
17508 (match_operand 3 "const_int_operand")]))]
17509 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17510 && incdec_operand (operands[3], GET_MODE (operands[3])))
17511 || (!TARGET_FUSE_CMP_AND_BRANCH
17512 && INTVAL (operands[3]) == 128))
17513 && ix86_match_ccmode (insn, CCGCmode)
17514 && peep2_reg_dead_p (1, operands[2])"
17515 [(parallel [(set (match_dup 0)
17516 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17517 (clobber (match_dup 2))])])
17518 \f
17519 ;; Convert imul by three, five and nine into lea
17520 (define_peephole2
17521 [(parallel
17522 [(set (match_operand:SWI48 0 "register_operand")
17523 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17524 (match_operand:SWI48 2 "const359_operand")))
17525 (clobber (reg:CC FLAGS_REG))])]
17526 "!TARGET_PARTIAL_REG_STALL
17527 || <MODE>mode == SImode
17528 || optimize_function_for_size_p (cfun)"
17529 [(set (match_dup 0)
17530 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17531 (match_dup 1)))]
17532 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17533
17534 (define_peephole2
17535 [(parallel
17536 [(set (match_operand:SWI48 0 "register_operand")
17537 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17538 (match_operand:SWI48 2 "const359_operand")))
17539 (clobber (reg:CC FLAGS_REG))])]
17540 "optimize_insn_for_speed_p ()
17541 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17542 [(set (match_dup 0) (match_dup 1))
17543 (set (match_dup 0)
17544 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17545 (match_dup 0)))]
17546 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17547
17548 ;; imul $32bit_imm, mem, reg is vector decoded, while
17549 ;; imul $32bit_imm, reg, reg is direct decoded.
17550 (define_peephole2
17551 [(match_scratch:SWI48 3 "r")
17552 (parallel [(set (match_operand:SWI48 0 "register_operand")
17553 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17554 (match_operand:SWI48 2 "immediate_operand")))
17555 (clobber (reg:CC FLAGS_REG))])]
17556 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17557 && !satisfies_constraint_K (operands[2])"
17558 [(set (match_dup 3) (match_dup 1))
17559 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17560 (clobber (reg:CC FLAGS_REG))])])
17561
17562 (define_peephole2
17563 [(match_scratch:SI 3 "r")
17564 (parallel [(set (match_operand:DI 0 "register_operand")
17565 (zero_extend:DI
17566 (mult:SI (match_operand:SI 1 "memory_operand")
17567 (match_operand:SI 2 "immediate_operand"))))
17568 (clobber (reg:CC FLAGS_REG))])]
17569 "TARGET_64BIT
17570 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17571 && !satisfies_constraint_K (operands[2])"
17572 [(set (match_dup 3) (match_dup 1))
17573 (parallel [(set (match_dup 0)
17574 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17575 (clobber (reg:CC FLAGS_REG))])])
17576
17577 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17578 ;; Convert it into imul reg, reg
17579 ;; It would be better to force assembler to encode instruction using long
17580 ;; immediate, but there is apparently no way to do so.
17581 (define_peephole2
17582 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17583 (mult:SWI248
17584 (match_operand:SWI248 1 "nonimmediate_operand")
17585 (match_operand:SWI248 2 "const_int_operand")))
17586 (clobber (reg:CC FLAGS_REG))])
17587 (match_scratch:SWI248 3 "r")]
17588 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17589 && satisfies_constraint_K (operands[2])"
17590 [(set (match_dup 3) (match_dup 2))
17591 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17592 (clobber (reg:CC FLAGS_REG))])]
17593 {
17594 if (!rtx_equal_p (operands[0], operands[1]))
17595 emit_move_insn (operands[0], operands[1]);
17596 })
17597
17598 ;; After splitting up read-modify operations, array accesses with memory
17599 ;; operands might end up in form:
17600 ;; sall $2, %eax
17601 ;; movl 4(%esp), %edx
17602 ;; addl %edx, %eax
17603 ;; instead of pre-splitting:
17604 ;; sall $2, %eax
17605 ;; addl 4(%esp), %eax
17606 ;; Turn it into:
17607 ;; movl 4(%esp), %edx
17608 ;; leal (%edx,%eax,4), %eax
17609
17610 (define_peephole2
17611 [(match_scratch:W 5 "r")
17612 (parallel [(set (match_operand 0 "register_operand")
17613 (ashift (match_operand 1 "register_operand")
17614 (match_operand 2 "const_int_operand")))
17615 (clobber (reg:CC FLAGS_REG))])
17616 (parallel [(set (match_operand 3 "register_operand")
17617 (plus (match_dup 0)
17618 (match_operand 4 "x86_64_general_operand")))
17619 (clobber (reg:CC FLAGS_REG))])]
17620 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17621 /* Validate MODE for lea. */
17622 && ((!TARGET_PARTIAL_REG_STALL
17623 && (GET_MODE (operands[0]) == QImode
17624 || GET_MODE (operands[0]) == HImode))
17625 || GET_MODE (operands[0]) == SImode
17626 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17627 && (rtx_equal_p (operands[0], operands[3])
17628 || peep2_reg_dead_p (2, operands[0]))
17629 /* We reorder load and the shift. */
17630 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17631 [(set (match_dup 5) (match_dup 4))
17632 (set (match_dup 0) (match_dup 1))]
17633 {
17634 enum machine_mode op1mode = GET_MODE (operands[1]);
17635 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17636 int scale = 1 << INTVAL (operands[2]);
17637 rtx index = gen_lowpart (word_mode, operands[1]);
17638 rtx base = gen_lowpart (word_mode, operands[5]);
17639 rtx dest = gen_lowpart (mode, operands[3]);
17640
17641 operands[1] = gen_rtx_PLUS (word_mode, base,
17642 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17643 operands[5] = base;
17644 if (mode != word_mode)
17645 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17646 if (op1mode != word_mode)
17647 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17648 operands[0] = dest;
17649 })
17650 \f
17651 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17652 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17653 ;; caught for use by garbage collectors and the like. Using an insn that
17654 ;; maps to SIGILL makes it more likely the program will rightfully die.
17655 ;; Keeping with tradition, "6" is in honor of #UD.
17656 (define_insn "trap"
17657 [(trap_if (const_int 1) (const_int 6))]
17658 ""
17659 { return ASM_SHORT "0x0b0f"; }
17660 [(set_attr "length" "2")])
17661
17662 (define_expand "prefetch"
17663 [(prefetch (match_operand 0 "address_operand")
17664 (match_operand:SI 1 "const_int_operand")
17665 (match_operand:SI 2 "const_int_operand"))]
17666 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17667 {
17668 int rw = INTVAL (operands[1]);
17669 int locality = INTVAL (operands[2]);
17670
17671 gcc_assert (rw == 0 || rw == 1);
17672 gcc_assert (locality >= 0 && locality <= 3);
17673 gcc_assert (GET_MODE (operands[0]) == Pmode
17674 || GET_MODE (operands[0]) == VOIDmode);
17675 if (TARGET_PRFCHW && rw)
17676 operands[2] = GEN_INT (3);
17677
17678 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17679 supported by SSE counterpart or the SSE prefetch is not available
17680 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17681 of locality. */
17682 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17683 operands[2] = GEN_INT (3);
17684 else
17685 operands[1] = const0_rtx;
17686 })
17687
17688 (define_insn "*prefetch_sse_<mode>"
17689 [(prefetch (match_operand:P 0 "address_operand" "p")
17690 (const_int 0)
17691 (match_operand:SI 1 "const_int_operand"))]
17692 "TARGET_PREFETCH_SSE"
17693 {
17694 static const char * const patterns[4] = {
17695 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17696 };
17697
17698 int locality = INTVAL (operands[1]);
17699 gcc_assert (locality >= 0 && locality <= 3);
17700
17701 return patterns[locality];
17702 }
17703 [(set_attr "type" "sse")
17704 (set_attr "atom_sse_attr" "prefetch")
17705 (set (attr "length_address")
17706 (symbol_ref "memory_address_length (operands[0])"))
17707 (set_attr "memory" "none")])
17708
17709 (define_insn "*prefetch_3dnow_<mode>"
17710 [(prefetch (match_operand:P 0 "address_operand" "p")
17711 (match_operand:SI 1 "const_int_operand" "n")
17712 (const_int 3))]
17713 "TARGET_3DNOW || TARGET_PRFCHW"
17714 {
17715 if (INTVAL (operands[1]) == 0)
17716 return "prefetch\t%a0";
17717 else
17718 return "prefetchw\t%a0";
17719 }
17720 [(set_attr "type" "mmx")
17721 (set (attr "length_address")
17722 (symbol_ref "memory_address_length (operands[0])"))
17723 (set_attr "memory" "none")])
17724
17725 (define_expand "stack_protect_set"
17726 [(match_operand 0 "memory_operand")
17727 (match_operand 1 "memory_operand")]
17728 "!TARGET_HAS_BIONIC"
17729 {
17730 rtx (*insn)(rtx, rtx);
17731
17732 #ifdef TARGET_THREAD_SSP_OFFSET
17733 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17734 insn = (TARGET_LP64
17735 ? gen_stack_tls_protect_set_di
17736 : gen_stack_tls_protect_set_si);
17737 #else
17738 insn = (TARGET_LP64
17739 ? gen_stack_protect_set_di
17740 : gen_stack_protect_set_si);
17741 #endif
17742
17743 emit_insn (insn (operands[0], operands[1]));
17744 DONE;
17745 })
17746
17747 (define_insn "stack_protect_set_<mode>"
17748 [(set (match_operand:PTR 0 "memory_operand" "=m")
17749 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17750 UNSPEC_SP_SET))
17751 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17752 (clobber (reg:CC FLAGS_REG))]
17753 "!TARGET_HAS_BIONIC"
17754 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17755 [(set_attr "type" "multi")])
17756
17757 (define_insn "stack_tls_protect_set_<mode>"
17758 [(set (match_operand:PTR 0 "memory_operand" "=m")
17759 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17760 UNSPEC_SP_TLS_SET))
17761 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17762 (clobber (reg:CC FLAGS_REG))]
17763 ""
17764 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17765 [(set_attr "type" "multi")])
17766
17767 (define_expand "stack_protect_test"
17768 [(match_operand 0 "memory_operand")
17769 (match_operand 1 "memory_operand")
17770 (match_operand 2)]
17771 "!TARGET_HAS_BIONIC"
17772 {
17773 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17774
17775 rtx (*insn)(rtx, rtx, rtx);
17776
17777 #ifdef TARGET_THREAD_SSP_OFFSET
17778 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17779 insn = (TARGET_LP64
17780 ? gen_stack_tls_protect_test_di
17781 : gen_stack_tls_protect_test_si);
17782 #else
17783 insn = (TARGET_LP64
17784 ? gen_stack_protect_test_di
17785 : gen_stack_protect_test_si);
17786 #endif
17787
17788 emit_insn (insn (flags, operands[0], operands[1]));
17789
17790 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17791 flags, const0_rtx, operands[2]));
17792 DONE;
17793 })
17794
17795 (define_insn "stack_protect_test_<mode>"
17796 [(set (match_operand:CCZ 0 "flags_reg_operand")
17797 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17798 (match_operand:PTR 2 "memory_operand" "m")]
17799 UNSPEC_SP_TEST))
17800 (clobber (match_scratch:PTR 3 "=&r"))]
17801 "!TARGET_HAS_BIONIC"
17802 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17803 [(set_attr "type" "multi")])
17804
17805 (define_insn "stack_tls_protect_test_<mode>"
17806 [(set (match_operand:CCZ 0 "flags_reg_operand")
17807 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17808 (match_operand:PTR 2 "const_int_operand" "i")]
17809 UNSPEC_SP_TLS_TEST))
17810 (clobber (match_scratch:PTR 3 "=r"))]
17811 ""
17812 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17813 [(set_attr "type" "multi")])
17814
17815 (define_insn "sse4_2_crc32<mode>"
17816 [(set (match_operand:SI 0 "register_operand" "=r")
17817 (unspec:SI
17818 [(match_operand:SI 1 "register_operand" "0")
17819 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17820 UNSPEC_CRC32))]
17821 "TARGET_SSE4_2 || TARGET_CRC32"
17822 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17823 [(set_attr "type" "sselog1")
17824 (set_attr "prefix_rep" "1")
17825 (set_attr "prefix_extra" "1")
17826 (set (attr "prefix_data16")
17827 (if_then_else (match_operand:HI 2)
17828 (const_string "1")
17829 (const_string "*")))
17830 (set (attr "prefix_rex")
17831 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17832 (const_string "1")
17833 (const_string "*")))
17834 (set_attr "mode" "SI")])
17835
17836 (define_insn "sse4_2_crc32di"
17837 [(set (match_operand:DI 0 "register_operand" "=r")
17838 (unspec:DI
17839 [(match_operand:DI 1 "register_operand" "0")
17840 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17841 UNSPEC_CRC32))]
17842 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17843 "crc32{q}\t{%2, %0|%0, %2}"
17844 [(set_attr "type" "sselog1")
17845 (set_attr "prefix_rep" "1")
17846 (set_attr "prefix_extra" "1")
17847 (set_attr "mode" "DI")])
17848
17849 (define_expand "rdpmc"
17850 [(match_operand:DI 0 "register_operand")
17851 (match_operand:SI 1 "register_operand")]
17852 ""
17853 {
17854 rtx reg = gen_reg_rtx (DImode);
17855 rtx si;
17856
17857 /* Force operand 1 into ECX. */
17858 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17859 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17860 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17861 UNSPECV_RDPMC);
17862
17863 if (TARGET_64BIT)
17864 {
17865 rtvec vec = rtvec_alloc (2);
17866 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17867 rtx upper = gen_reg_rtx (DImode);
17868 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17869 gen_rtvec (1, const0_rtx),
17870 UNSPECV_RDPMC);
17871 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17872 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17873 emit_insn (load);
17874 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17875 NULL, 1, OPTAB_DIRECT);
17876 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17877 OPTAB_DIRECT);
17878 }
17879 else
17880 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17881 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17882 DONE;
17883 })
17884
17885 (define_insn "*rdpmc"
17886 [(set (match_operand:DI 0 "register_operand" "=A")
17887 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17888 UNSPECV_RDPMC))]
17889 "!TARGET_64BIT"
17890 "rdpmc"
17891 [(set_attr "type" "other")
17892 (set_attr "length" "2")])
17893
17894 (define_insn "*rdpmc_rex64"
17895 [(set (match_operand:DI 0 "register_operand" "=a")
17896 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17897 UNSPECV_RDPMC))
17898 (set (match_operand:DI 1 "register_operand" "=d")
17899 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17900 "TARGET_64BIT"
17901 "rdpmc"
17902 [(set_attr "type" "other")
17903 (set_attr "length" "2")])
17904
17905 (define_expand "rdtsc"
17906 [(set (match_operand:DI 0 "register_operand")
17907 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17908 ""
17909 {
17910 if (TARGET_64BIT)
17911 {
17912 rtvec vec = rtvec_alloc (2);
17913 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17914 rtx upper = gen_reg_rtx (DImode);
17915 rtx lower = gen_reg_rtx (DImode);
17916 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17917 gen_rtvec (1, const0_rtx),
17918 UNSPECV_RDTSC);
17919 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17920 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17921 emit_insn (load);
17922 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17923 NULL, 1, OPTAB_DIRECT);
17924 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17925 OPTAB_DIRECT);
17926 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17927 DONE;
17928 }
17929 })
17930
17931 (define_insn "*rdtsc"
17932 [(set (match_operand:DI 0 "register_operand" "=A")
17933 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17934 "!TARGET_64BIT"
17935 "rdtsc"
17936 [(set_attr "type" "other")
17937 (set_attr "length" "2")])
17938
17939 (define_insn "*rdtsc_rex64"
17940 [(set (match_operand:DI 0 "register_operand" "=a")
17941 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17942 (set (match_operand:DI 1 "register_operand" "=d")
17943 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17944 "TARGET_64BIT"
17945 "rdtsc"
17946 [(set_attr "type" "other")
17947 (set_attr "length" "2")])
17948
17949 (define_expand "rdtscp"
17950 [(match_operand:DI 0 "register_operand")
17951 (match_operand:SI 1 "memory_operand")]
17952 ""
17953 {
17954 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17955 gen_rtvec (1, const0_rtx),
17956 UNSPECV_RDTSCP);
17957 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17958 gen_rtvec (1, const0_rtx),
17959 UNSPECV_RDTSCP);
17960 rtx reg = gen_reg_rtx (DImode);
17961 rtx tmp = gen_reg_rtx (SImode);
17962
17963 if (TARGET_64BIT)
17964 {
17965 rtvec vec = rtvec_alloc (3);
17966 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17967 rtx upper = gen_reg_rtx (DImode);
17968 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17969 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17970 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17971 emit_insn (load);
17972 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17973 NULL, 1, OPTAB_DIRECT);
17974 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17975 OPTAB_DIRECT);
17976 }
17977 else
17978 {
17979 rtvec vec = rtvec_alloc (2);
17980 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17981 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17982 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17983 emit_insn (load);
17984 }
17985 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17986 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17987 DONE;
17988 })
17989
17990 (define_insn "*rdtscp"
17991 [(set (match_operand:DI 0 "register_operand" "=A")
17992 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17993 (set (match_operand:SI 1 "register_operand" "=c")
17994 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17995 "!TARGET_64BIT"
17996 "rdtscp"
17997 [(set_attr "type" "other")
17998 (set_attr "length" "3")])
17999
18000 (define_insn "*rdtscp_rex64"
18001 [(set (match_operand:DI 0 "register_operand" "=a")
18002 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18003 (set (match_operand:DI 1 "register_operand" "=d")
18004 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18005 (set (match_operand:SI 2 "register_operand" "=c")
18006 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18007 "TARGET_64BIT"
18008 "rdtscp"
18009 [(set_attr "type" "other")
18010 (set_attr "length" "3")])
18011
18012 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18013 ;;
18014 ;; LWP instructions
18015 ;;
18016 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18017
18018 (define_expand "lwp_llwpcb"
18019 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18020 UNSPECV_LLWP_INTRINSIC)]
18021 "TARGET_LWP")
18022
18023 (define_insn "*lwp_llwpcb<mode>1"
18024 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18025 UNSPECV_LLWP_INTRINSIC)]
18026 "TARGET_LWP"
18027 "llwpcb\t%0"
18028 [(set_attr "type" "lwp")
18029 (set_attr "mode" "<MODE>")
18030 (set_attr "length" "5")])
18031
18032 (define_expand "lwp_slwpcb"
18033 [(set (match_operand 0 "register_operand" "=r")
18034 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18035 "TARGET_LWP"
18036 {
18037 rtx (*insn)(rtx);
18038
18039 insn = (Pmode == DImode
18040 ? gen_lwp_slwpcbdi
18041 : gen_lwp_slwpcbsi);
18042
18043 emit_insn (insn (operands[0]));
18044 DONE;
18045 })
18046
18047 (define_insn "lwp_slwpcb<mode>"
18048 [(set (match_operand:P 0 "register_operand" "=r")
18049 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18050 "TARGET_LWP"
18051 "slwpcb\t%0"
18052 [(set_attr "type" "lwp")
18053 (set_attr "mode" "<MODE>")
18054 (set_attr "length" "5")])
18055
18056 (define_expand "lwp_lwpval<mode>3"
18057 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18058 (match_operand:SI 2 "nonimmediate_operand" "rm")
18059 (match_operand:SI 3 "const_int_operand" "i")]
18060 UNSPECV_LWPVAL_INTRINSIC)]
18061 "TARGET_LWP"
18062 ;; Avoid unused variable warning.
18063 "(void) operands[0];")
18064
18065 (define_insn "*lwp_lwpval<mode>3_1"
18066 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18067 (match_operand:SI 1 "nonimmediate_operand" "rm")
18068 (match_operand:SI 2 "const_int_operand" "i")]
18069 UNSPECV_LWPVAL_INTRINSIC)]
18070 "TARGET_LWP"
18071 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18072 [(set_attr "type" "lwp")
18073 (set_attr "mode" "<MODE>")
18074 (set (attr "length")
18075 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18076
18077 (define_expand "lwp_lwpins<mode>3"
18078 [(set (reg:CCC FLAGS_REG)
18079 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18080 (match_operand:SI 2 "nonimmediate_operand" "rm")
18081 (match_operand:SI 3 "const_int_operand" "i")]
18082 UNSPECV_LWPINS_INTRINSIC))
18083 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18084 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18085 "TARGET_LWP")
18086
18087 (define_insn "*lwp_lwpins<mode>3_1"
18088 [(set (reg:CCC FLAGS_REG)
18089 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18090 (match_operand:SI 1 "nonimmediate_operand" "rm")
18091 (match_operand:SI 2 "const_int_operand" "i")]
18092 UNSPECV_LWPINS_INTRINSIC))]
18093 "TARGET_LWP"
18094 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18095 [(set_attr "type" "lwp")
18096 (set_attr "mode" "<MODE>")
18097 (set (attr "length")
18098 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18099
18100 (define_int_iterator RDFSGSBASE
18101 [UNSPECV_RDFSBASE
18102 UNSPECV_RDGSBASE])
18103
18104 (define_int_iterator WRFSGSBASE
18105 [UNSPECV_WRFSBASE
18106 UNSPECV_WRGSBASE])
18107
18108 (define_int_attr fsgs
18109 [(UNSPECV_RDFSBASE "fs")
18110 (UNSPECV_RDGSBASE "gs")
18111 (UNSPECV_WRFSBASE "fs")
18112 (UNSPECV_WRGSBASE "gs")])
18113
18114 (define_insn "rd<fsgs>base<mode>"
18115 [(set (match_operand:SWI48 0 "register_operand" "=r")
18116 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18117 "TARGET_64BIT && TARGET_FSGSBASE"
18118 "rd<fsgs>base\t%0"
18119 [(set_attr "type" "other")
18120 (set_attr "prefix_extra" "2")])
18121
18122 (define_insn "wr<fsgs>base<mode>"
18123 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18124 WRFSGSBASE)]
18125 "TARGET_64BIT && TARGET_FSGSBASE"
18126 "wr<fsgs>base\t%0"
18127 [(set_attr "type" "other")
18128 (set_attr "prefix_extra" "2")])
18129
18130 (define_insn "rdrand<mode>_1"
18131 [(set (match_operand:SWI248 0 "register_operand" "=r")
18132 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18133 (set (reg:CCC FLAGS_REG)
18134 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18135 "TARGET_RDRND"
18136 "rdrand\t%0"
18137 [(set_attr "type" "other")
18138 (set_attr "prefix_extra" "1")])
18139
18140 (define_expand "pause"
18141 [(set (match_dup 0)
18142 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18143 ""
18144 {
18145 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18146 MEM_VOLATILE_P (operands[0]) = 1;
18147 })
18148
18149 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18150 ;; They have the same encoding.
18151 (define_insn "*pause"
18152 [(set (match_operand:BLK 0)
18153 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18154 ""
18155 "rep%; nop"
18156 [(set_attr "length" "2")
18157 (set_attr "memory" "unknown")])
18158
18159 (define_expand "xbegin"
18160 [(set (match_operand:SI 0 "register_operand")
18161 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18162 "TARGET_RTM"
18163 {
18164 rtx label = gen_label_rtx ();
18165
18166 operands[1] = force_reg (SImode, constm1_rtx);
18167
18168 emit_jump_insn (gen_xbegin_1 (operands[1], label));
18169
18170 emit_label (label);
18171 LABEL_NUSES (label) = 1;
18172
18173 emit_move_insn (operands[0], operands[1]);
18174
18175 DONE;
18176 })
18177
18178 (define_insn "xbegin_1"
18179 [(set (pc)
18180 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18181 (const_int 0))
18182 (label_ref (match_operand 1))
18183 (pc)))
18184 (set (match_operand:SI 0 "register_operand" "+a")
18185 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18186 "TARGET_RTM"
18187 "xbegin\t%l1"
18188 [(set_attr "type" "other")
18189 (set_attr "length" "6")])
18190
18191 (define_insn "xend"
18192 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18193 "TARGET_RTM"
18194 "xend"
18195 [(set_attr "type" "other")
18196 (set_attr "length" "3")])
18197
18198 (define_insn "xabort"
18199 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18200 UNSPECV_XABORT)]
18201 "TARGET_RTM"
18202 "xabort\t%0"
18203 [(set_attr "type" "other")
18204 (set_attr "length" "3")])
18205
18206 (define_expand "xtest"
18207 [(set (match_operand:QI 0 "register_operand")
18208 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18209 "TARGET_RTM"
18210 {
18211 emit_insn (gen_xtest_1 ());
18212
18213 ix86_expand_setcc (operands[0], NE,
18214 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18215 DONE;
18216 })
18217
18218 (define_insn "xtest_1"
18219 [(set (reg:CCZ FLAGS_REG)
18220 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18221 "TARGET_RTM"
18222 "xtest"
18223 [(set_attr "type" "other")
18224 (set_attr "length" "3")])
18225
18226 (include "mmx.md")
18227 (include "sse.md")
18228 (include "sync.md")